diff --git a/spi_master_ss.v b/spi_master_ss.v index f71a874..fdf1f35 100644 --- a/spi_master_ss.v +++ b/spi_master_ss.v @@ -32,7 +32,7 @@ module spi_master_ss input miso, input [WID-1:0] to_slave, - output reg mosi, + output mosi, output sck_wire, output finished, diff --git a/spi_master_ss_wb.v b/spi_master_ss_wb.v new file mode 100644 index 0000000..5f77bc8 --- /dev/null +++ b/spi_master_ss_wb.v @@ -0,0 +1,107 @@ +/* (c) Peter McGoron 2022 v0.4 + * + * This code is disjunctively dual-licensed under the MPL v2.0, or the + * CERN-OHL-W v2. + */ + +module spi_master_ss +#( + parameter BUS_WID = 32, /* Width of a request on the bus. */ + parameter SELECT_WID = 4, /* Width of the wishbone byte select. */ + + parameter SS_WAIT = 1, + parameter SS_WAIT_TIMER_LEN = 2, + + parameter ENABLE_MISO = 1, + parameter ENABLE_MOSI = 1, + parameter WID = 24, + parameter WID_LEN = 5, + parameter CYCLE_HALF_WAIT = 1, + parameter TIMER_LEN = 3, + + parameter POLARITY = 0, + parameter PHASE = 0 +) ( + input clk, + input rst_L, + + input miso, + output reg mosi, + output sck_wire, + output ss_L + + input wb_cyc, + input wb_stb, + input wb_we, + input [SELECT_WID-1:0] wb_sel, + input [BUS_WID-1:0] wb_addr, + input [BUS_WID-1:0] wb_dat_w, + output reg wb_ack, + output reg [BUS_WID-1:0] wb_dat_r, +); + +/* Address map: + + All words are little endian. Access must be word-aligned and word-level + or undefined behavior will occur. + + word 0: ready_to_arm | (finished << 1) (RW) + word 1: arm (RO) + word 2: from_slave (RO) + word 3: to_slave (RW) +*/ + +wire [WID-1:0] from_slave; +reg [WID-1:0] to_slave; +wire finished; +wire ready_to_arm; +reg arm; + +spi_master_ss #( + .SS_WAIT(SS_WAIT), + .SS_WAIT_TIMER_LEN(SS_WAIT_TIMER_LEN), + + .ENABLE_MISO(ENABLE_MISO), + .ENABLE_MOSI(ENABLE_MOSI), + .WID(WID), + .WID_LEN(WID_LEN), + .CYCLE_HALF_WAIT(CYCLE_HALF_WAIT), + .TIMER_LEN(TIMER_LEN), + + .POLARITY(POLARITY), + .PHASE(PHASE) +) spi ( + .clk(clk), + .rst_L(rst_L), + + .from_slave(from_slave), + .miso(miso), + + .to_slave(to_slave), + .mosi(mosi), + + .sck_wire(sck_wire), + .finished(finished), + .ready_to_arm(ready_to_arm), + .ss_L(ss_L), + .arm(arm) +); + +always @ (posedge clk) if (wb_cyc && wb_stb && !wb_ack) begin + if (!wb_we) case (wb_addr[4-1:0]) + 4'h0: wb_dat_r <= {30'b0, finished, ready_to_arm}; + 4'h4: wb_dat_r <= {31'b0, arm}; + 4'h8: wb_dat_r <= from_slave; + 4'hC: wb_dat_r <= to_slave; + default: wb_dat_r <= 0; + endcase else case (wb_addr[4-1:0]) + 4'h4: arm <= wb_dat_w[0]; + 4'hC: to_slave <= wb_dat_w; + default: ; + end + wb_ack <= 1; +end else begin + wb_ack <= 0; +end + +endmodule