URL
https://opencores.org/ocsvn/yifive/yifive/trunk
Subversion Repositories yifive
Compare Revisions
- This comparison shows the changes necessary to convert path
/yifive/trunk/caravel_yifive/verilog/rtl/spi_master/src
- from Rev 20 to Rev 21
- ↔ Reverse comparison
Rev 20 → Rev 21
/spim_clkgen.sv
85,32 → 85,47
if(clk_cnt == sck_half_period) |
begin |
spi_clk <= 1'b0; |
spi_fall <= 1'b1; |
spi_rise <= 1'b0; |
clk_cnt <= clk_cnt + 1'b1; |
end // if (clk_cnt == sck_half_period) |
else begin |
if(clk_cnt == cfg_sck_period) |
begin |
else if(clk_cnt == cfg_sck_period) begin |
spi_clk <= 1'b1; |
spi_fall <= 1'b0; |
spi_rise <= 1'b1; |
clk_cnt <= 'h1; |
end // if (clk_cnt == cfg_sck_period) |
else |
begin |
clk_cnt <= clk_cnt + 1'b1; |
spi_fall <= 1'b0; |
spi_rise <= 1'b0; |
end // else: !if(clk_cnt == cfg_sck_period) |
end // else: !if(clk_cnt == sck_half_period) |
end // if (en) |
else begin |
clk_cnt <= 'h1; |
spi_fall <= 1'b0; |
spi_rise <= 1'b0; |
end |
end else begin |
spi_clk <= 1'b1; |
end // else: !if(en) |
end // else: !if(!reset_n) |
end // always @ (posedge clk or negedge reset_n) |
|
// Generate Free runnng spi_fall and rise pulse |
// after en is asserted |
always @(posedge clk or negedge rstn) begin |
if(!rstn) begin |
clk_cnt <= 'h1; |
spi_fall <= 1'b0; |
spi_rise <= 1'b0; |
end // if (!reset_n) |
else |
begin |
if(clk_cnt == sck_half_period) |
begin |
spi_fall <= 1'b0; |
spi_rise <= 1'b1; |
clk_cnt <= clk_cnt + 1'b1; |
end // if (clk_cnt == sck_half_period) |
else begin |
if(clk_cnt == cfg_sck_period) |
begin |
spi_fall <= 1'b1; |
spi_rise <= 1'b0; |
clk_cnt <= 'h1; |
end // if (clk_cnt == cfg_sck_period) |
else |
begin |
clk_cnt <= clk_cnt + 1'b1; |
spi_fall <= 1'b0; |
spi_rise <= 1'b0; |
end // else: !if(clk_cnt == cfg_sck_period) |
end // else: !if(clk_cnt == sck_half_period) |
end // else: !if(!reset_n) |
end // always @ (posedge clk or negedge reset_n) |
|
endmodule |
/spim_ctrl.sv
51,7 → 51,7
|
input logic [7:0] spi_clk_div, |
input logic spi_clk_div_valid, |
output logic [7:0] spi_status, |
output logic [8:0] spi_status, |
|
|
input logic spi_req, |
133,7 → 133,7
|
enum logic [2:0] {DATA_NULL,DATA_EMPTY,DATA_CMD,DATA_ADDR,DATA_MODE,DATA_FIFO} ctrl_data_mux; |
|
enum logic [4:0] {IDLE,CMD,ADDR,MODE,DUMMY,DATA_TX,DATA_RX,WAIT_EDGE} state,state_next; |
enum logic [4:0] {IDLE,CMD,ADDR,MODE,DUMMY_RX,DUMMY_TX,DATA_TX,DATA_RX,WAIT_EDGE} state,state_next; |
|
assign en_quad = spi_qrd | spi_qwr | en_quad_int; |
|
169,7 → 169,6
.data_ready ( ), |
.clk_en_o ( tx_clk_en ) |
); |
|
spim_rx u_rxreg |
( |
.clk ( clk ), |
190,7 → 189,6
.clk_en_o ( rx_clk_en ) |
); |
|
|
|
always_comb |
begin |
256,7 → 254,7
begin |
spi_status[0] = 1'b1; |
s_spi_mode = SPI_QUAD_RX; |
if (spi_req) |
if (spi_req && spi_fall) |
begin |
spi_cs = 1'b0; |
spi_clock_en = 1'b1; |
299,11 → 297,12
s_spi_mode = (spi_qrd) ? SPI_QUAD_RX : SPI_STD; |
if(spi_dummy_rd_len != 0) |
begin |
counter_tx = en_quad ? {2'b00,spi_dummy_rd_len[13:0]} : spi_dummy_rd_len; |
counter_tx_valid = 1'b1; |
spi_en_tx = 1'b1; |
counter_rx = en_quad ? {2'b00,spi_dummy_rd_len[13:0]} : spi_dummy_rd_len; |
counter_rx_valid = 1'b1; |
spi_en_rx = 1'b1; |
ctrl_data_mux = DATA_EMPTY; |
state_next = DUMMY; |
spi_clock_en = rx_clk_en; |
state_next = DUMMY_RX; |
end |
else |
begin |
310,6 → 309,7
counter_rx = spi_data_len; |
counter_rx_valid = 1'b1; |
spi_en_rx = 1'b1; |
spi_clock_en = rx_clk_en; |
state_next = DATA_RX; |
end |
end |
322,7 → 322,8
counter_tx_valid = 1'b1; |
ctrl_data_mux = DATA_EMPTY; |
spi_en_tx = 1'b1; |
state_next = DUMMY; |
spi_clock_en = tx_clk_en; |
state_next = DUMMY_TX; |
end |
else |
begin |
331,6 → 332,7
ctrl_data_mux = DATA_FIFO; |
ctrl_data_valid = 1'b0; |
spi_en_tx = 1'b1; |
spi_clock_en = tx_clk_en; |
state_next = DATA_TX; |
end |
end |
350,7 → 352,7
spi_clock_en = 1'b1; |
// s_spi_mode = (en_quad) ? SPI_QUAD_TX : SPI_STD; |
s_spi_mode = SPI_STD; // Command is always Standard Mode ? |
if (tx_done) |
if (tx_done && spi_fall) |
begin |
if (spi_addr_len != 0) |
begin |
379,11 → 381,12
s_spi_mode = (en_quad) ? SPI_QUAD_RX : SPI_STD; |
if(spi_dummy_rd_len != 0) |
begin |
counter_tx = en_quad ? {2'b00,spi_dummy_rd_len[13:0]} : spi_dummy_rd_len; |
counter_tx_valid = 1'b1; |
spi_en_tx = 1'b1; |
counter_rx = en_quad ? {2'b00,spi_dummy_rd_len[13:0]} : spi_dummy_rd_len; |
counter_rx_valid = 1'b1; |
spi_en_rx = 1'b1; |
ctrl_data_mux = DATA_EMPTY; |
state_next = DUMMY; |
spi_clock_en = rx_clk_en; |
state_next = DUMMY_RX; |
end |
else |
begin |
390,6 → 393,7
counter_rx = spi_data_len; |
counter_rx_valid = 1'b1; |
spi_en_rx = 1'b1; |
spi_clock_en = rx_clk_en; |
state_next = DATA_RX; |
end |
end |
402,7 → 406,8
counter_tx_valid = 1'b1; |
ctrl_data_mux = DATA_EMPTY; |
spi_en_tx = 1'b1; |
state_next = DUMMY; |
spi_clock_en = tx_clk_en; |
state_next = DUMMY_TX; |
end |
else |
begin |
411,6 → 416,7
ctrl_data_mux = DATA_FIFO; |
ctrl_data_valid = 1'b1; |
spi_en_tx = 1'b1; |
spi_clock_en = tx_clk_en; |
state_next = DATA_TX; |
end |
end |
436,7 → 442,7
spi_clock_en = 1'b1; |
s_spi_mode = (en_quad) ? SPI_QUAD_TX : SPI_STD; |
|
if (tx_done) |
if (tx_done && spi_fall) |
begin |
if (spi_mode_cmd_enb != 0) |
begin |
455,11 → 461,12
s_spi_mode = (en_quad) ? SPI_QUAD_RX : SPI_STD; |
if(spi_dummy_rd_len != 0) |
begin |
counter_tx = en_quad ? {2'b00,spi_dummy_rd_len[13:0]} : spi_dummy_rd_len; |
counter_tx_valid = 1'b1; |
spi_en_tx = 1'b1; |
counter_rx = en_quad ? {2'b00,spi_dummy_rd_len[13:0]} : spi_dummy_rd_len; |
counter_rx_valid = 1'b1; |
spi_en_rx = 1'b1; |
ctrl_data_mux = DATA_EMPTY; |
state_next = DUMMY; |
spi_clock_en = rx_clk_en; |
state_next = DUMMY_RX; |
end |
else |
begin |
466,6 → 473,7
counter_rx = spi_data_len; |
counter_rx_valid = 1'b1; |
spi_en_rx = 1'b1; |
spi_clock_en = rx_clk_en; |
state_next = DATA_RX; |
end |
end |
478,12 → 486,14
counter_tx = en_quad ? {2'b00,spi_dummy_wr_len[13:0]} : spi_dummy_wr_len; |
counter_tx_valid = 1'b1; |
ctrl_data_mux = DATA_EMPTY; |
state_next = DUMMY; |
spi_clock_en = tx_clk_en; |
state_next = DUMMY_TX; |
end else begin |
counter_tx = spi_data_len; |
counter_tx_valid = 1'b1; |
ctrl_data_mux = DATA_FIFO; |
ctrl_data_valid = 1'b1; |
spi_clock_en = tx_clk_en; |
state_next = DATA_TX; |
end |
end |
502,7 → 512,7
spi_cs = 1'b0; |
spi_clock_en = 1'b1; |
s_spi_mode = (en_quad) ? SPI_QUAD_TX : SPI_STD; |
if (tx_done) |
if (tx_done && spi_fall) |
begin |
if (spi_data_len != 0) |
begin |
511,11 → 521,12
s_spi_mode = (en_quad) ? SPI_QUAD_RX : SPI_STD; |
if(spi_dummy_rd_len != 0) |
begin |
counter_tx = en_quad ? {2'b00,spi_dummy_rd_len[13:0]} : spi_dummy_rd_len; |
counter_tx_valid = 1'b1; |
spi_en_tx = 1'b1; |
counter_rx = en_quad ? {2'b00,spi_dummy_rd_len[13:0]} : spi_dummy_rd_len; |
counter_rx_valid = 1'b1; |
spi_en_rx = 1'b1; |
ctrl_data_mux = DATA_EMPTY; |
state_next = DUMMY; |
spi_clock_en = rx_clk_en; |
state_next = DUMMY_RX; |
end |
else |
begin |
522,6 → 533,7
counter_rx = spi_data_len; |
counter_rx_valid = 1'b1; |
spi_en_rx = 1'b1; |
spi_clock_en = rx_clk_en; |
state_next = DATA_RX; |
end |
end |
534,12 → 546,14
counter_tx = en_quad ? {2'b00,spi_dummy_wr_len[13:0]} : spi_dummy_wr_len; |
counter_tx_valid = 1'b1; |
ctrl_data_mux = DATA_EMPTY; |
state_next = DUMMY; |
spi_clock_en = tx_clk_en; |
state_next = DUMMY_TX; |
end else begin |
counter_tx = spi_data_len; |
counter_tx_valid = 1'b1; |
ctrl_data_mux = DATA_FIFO; |
ctrl_data_valid = 1'b1; |
spi_clock_en = tx_clk_en; |
state_next = DATA_TX; |
end |
end |
551,7 → 565,7
end |
end |
|
DUMMY: |
DUMMY_TX: |
begin |
spi_en_tx = 1'b1; |
spi_status[4] = 1'b1; |
559,12 → 573,13
spi_clock_en = 1'b1; |
s_spi_mode = (en_quad) ? SPI_QUAD_RX : SPI_STD; |
|
if (tx_done) begin |
if (tx_done && spi_fall) begin |
if (spi_data_len != 0) begin |
if (do_rx) begin |
counter_rx = spi_data_len; |
counter_rx_valid = 1'b1; |
spi_en_rx = 1'b1; |
spi_clock_en = rx_clk_en; |
state_next = DATA_RX; |
end else begin |
counter_tx = spi_data_len; |
586,21 → 601,60
begin |
ctrl_data_mux = DATA_EMPTY; |
spi_en_tx = 1'b1; |
state_next = DUMMY; |
state_next = DUMMY_TX; |
end |
end |
|
DUMMY_RX: |
begin |
spi_en_rx = 1'b1; |
spi_status[5] = 1'b1; |
spi_cs = 1'b0; |
spi_clock_en = 1'b1; |
s_spi_mode = (en_quad) ? SPI_QUAD_RX : SPI_STD; |
|
if (rx_done && spi_rise) begin |
if (spi_data_len != 0) begin |
if (do_rx) begin |
counter_rx = spi_data_len; |
counter_rx_valid = 1'b1; |
spi_en_rx = 1'b1; |
spi_clock_en = rx_clk_en; |
state_next = DATA_RX; |
end else begin |
counter_tx = spi_data_len; |
counter_tx_valid = 1'b1; |
s_spi_mode = (en_quad) ? SPI_QUAD_TX : SPI_STD; |
|
spi_clock_en = tx_clk_en; |
spi_en_tx = 1'b1; |
state_next = DATA_TX; |
end |
end |
else |
begin |
eot = 1'b1; |
state_next = WAIT_EDGE; |
end |
end |
else |
begin |
ctrl_data_mux = DATA_EMPTY; |
spi_en_tx = 1'b1; |
spi_clock_en = rx_clk_en; |
state_next = DUMMY_RX; |
end |
end |
DATA_TX: |
begin |
spi_status[5] = 1'b1; |
spi_status[6] = 1'b1; |
spi_cs = 1'b0; |
spi_clock_en = tx_clk_en; |
ctrl_data_mux = DATA_FIFO; |
ctrl_data_valid = 1'b1; |
spi_en_tx = 1'b1; |
s_spi_mode = (en_quad) ? SPI_QUAD_TX : SPI_STD; |
|
if (tx_done) begin |
if (tx_done && spi_fall) begin |
eot = 1'b1; |
state_next = WAIT_EDGE; |
spi_clock_en = 1'b0; |
611,12 → 665,12
|
DATA_RX: |
begin |
spi_status[6] = 1'b1; |
spi_status[7] = 1'b1; |
spi_cs = 1'b0; |
spi_clock_en = rx_clk_en; |
s_spi_mode = (en_quad) ? SPI_QUAD_RX : SPI_STD; |
|
if (rx_done) begin |
if (rx_done && spi_rise) begin |
state_next = WAIT_EDGE; |
end else begin |
spi_en_rx = 1'b1; |
625,7 → 679,7
end |
WAIT_EDGE: |
begin |
spi_status[7] = 1'b1; |
spi_status[8] = 1'b1; |
spi_cs = 1'b0; |
spi_clock_en = 1'b0; |
s_spi_mode = (en_quad) ? SPI_QUAD_RX : SPI_STD; |
635,7 → 689,7
endcase |
end |
|
assign spi_ack = ((spi_req ==1) && (state_next == WAIT_EDGE)) ? 1'b1 : 1'b0; |
assign spi_ack = ((spi_req ==1) && (state == WAIT_EDGE)) ? 1'b1 : 1'b0; |
|
|
always_ff @(posedge clk, negedge rstn) |
/spim_regs.sv
66,7 → 66,7
|
output logic [7:0] spi_clk_div, |
output logic spi_clk_div_valid, |
input logic [7:0] spi_status, |
input logic [8:0] spi_status, |
|
// Towards SPI TX/RX FSM |
|
107,10 → 107,12
parameter REG_STATUS = 4'b1000; |
|
// Init FSM |
parameter SPI_INIT_IDLE = 3'b000; |
parameter SPI_INIT_CMD_WAIT = 3'b001; |
parameter SPI_INIT_WRR_CMD = 3'b010; |
parameter SPI_INIT_WRR_WAIT = 3'b011; |
parameter SPI_INIT_IDLE = 3'b000; |
parameter SPI_INIT_CMD_WAIT = 3'b001; |
parameter SPI_INIT_WREN_CMD = 3'b010; |
parameter SPI_INIT_WREN_WAIT = 3'b011; |
parameter SPI_INIT_WRR_CMD = 3'b100; |
parameter SPI_INIT_WRR_WAIT = 3'b101; |
|
//--------------------------------------------------------- |
// Variable declartion |
161,8 → 163,8
assign spi_mode_cmd = (spim_mem_req && !spim_wb_we) ? 8'h00 : reg2spi_mode; |
assign spi_mode_cmd_enb = (spim_mem_req && !spim_wb_we) ? 1 : reg2spi_mode_enb; |
assign spi_csreg = (spim_mem_req && !spim_wb_we) ? '1 : reg2spi_csreg; |
assign spi_data_len = (spim_mem_req && !spim_wb_we) ? 'h10 : reg2spi_data_len; |
assign spi_dummy_rd_len = (spim_mem_req && !spim_wb_we) ? 16 : reg2spi_dummy_rd_len; |
assign spi_data_len = (spim_mem_req && !spim_wb_we) ? 'h20 : reg2spi_data_len; |
assign spi_dummy_rd_len = (spim_mem_req && !spim_wb_we) ? 'h20 : reg2spi_dummy_rd_len; |
assign spi_dummy_wr_len = (spim_mem_req && !spim_wb_we) ? 0 : reg2spi_dummy_wr_len; |
assign spi_swrst = (spim_mem_req && !spim_wb_we) ? 0 : reg2spi_swrst; |
assign spi_rd = (spim_mem_req && !spim_wb_we) ? 0 : reg2spi_rd; |
200,27 → 202,29
spim_wb_we <= '0; |
spim_wb_ack <= '0; |
end else begin |
spim_wb_req <= wbd_stb_i; |
spim_wb_req_l <= spim_wb_req; |
spim_wb_wdata <= wbd_dat_i; |
spim_wb_addr <= wbd_adr_i; |
spim_wb_be <= wbd_sel_i; |
spim_wb_we <= wbd_we_i; |
|
|
// If there is Reg2Spi read Access, Register the Read Data |
if(reg2spi_req && (reg2spi_rd || reg2spi_qrd ) && spi_ack) |
spim_reg_rdata <= spi_rdata; |
|
if(!spim_wb_we && spim_wb_req && spi_ack) |
spim_wb_rdata <= spi_rdata; |
else |
spim_wb_rdata <= reg_rdata; |
|
if(spi_init_done) begin // Wait for internal SPI Init Done |
spim_wb_req <= wbd_stb_i && (spi_ack == 0) && (spim_wb_ack==0); |
spim_wb_req_l <= spim_wb_req; |
spim_wb_wdata <= wbd_dat_i; |
spim_wb_addr <= wbd_adr_i; |
spim_wb_be <= wbd_sel_i; |
spim_wb_we <= wbd_we_i; |
|
|
// If there is Reg2Spi read Access, Register the Read Data |
if(reg2spi_req && (reg2spi_rd || reg2spi_qrd ) && spi_ack) |
spim_reg_rdata <= spi_rdata; |
|
if(!spim_wb_we && spim_wb_req && spi_ack) |
spim_wb_rdata <= spi_rdata; |
else if (spim_reg_req) |
spim_wb_rdata <= reg_rdata; |
|
// For safer design, we have generated ack after 2 cycle latter to |
// cross-check current request is towards SPI or not |
spim_wb_ack <= (spi_req) ? spi_ack : |
((spim_wb_ack==0) && spim_wb_req && spim_wb_req_l) ; |
// cross-check current request is towards SPI or not |
spim_wb_ack <= (spi_req && spim_wb_req) ? spi_ack : |
((spim_wb_ack==0) && spim_wb_req && spim_wb_req_l) ; |
end |
end |
end |
|
259,7 → 263,7
reg2spi_qwr <= 'h0; |
reg2spi_swrst <= 'h0; |
reg2spi_csreg <= 'h1; |
reg2spi_cmd[7:0] <= 'h6; // WREN command |
reg2spi_cmd[7:0] <= 'hAB; // POWER UP command |
reg2spi_mode[7:0] <= 'h0; |
reg2spi_cmd_len <= 'h8; |
reg2spi_addr_len <= 'h0; |
272,6 → 276,30
begin |
if(spi_ack) begin |
reg2spi_req <= 1'b0; |
spi_init_state <= SPI_INIT_WREN_CMD; |
end |
end |
SPI_INIT_WREN_CMD: |
begin |
reg2spi_rd <= 'h0; |
reg2spi_wr <= 'h1; // SPI Write Req |
reg2spi_qrd <= 'h0; |
reg2spi_qwr <= 'h0; |
reg2spi_swrst <= 'h0; |
reg2spi_csreg <= 'h1; |
reg2spi_cmd[7:0] <= 'h6; // WREN command |
reg2spi_mode[7:0] <= 'h0; |
reg2spi_cmd_len <= 'h8; |
reg2spi_addr_len <= 'h0; |
reg2spi_data_len <= 'h0; |
reg2spi_wdata <= 'h0; |
reg2spi_req <= 'h1; |
spi_init_state <= SPI_INIT_WREN_WAIT; |
end |
SPI_INIT_WREN_WAIT: |
begin |
if(spi_ack) begin |
reg2spi_req <= 1'b0; |
spi_init_state <= SPI_INIT_WRR_CMD; |
end |
end |
372,38 → 400,43
end |
|
|
|
wire [3:0] reg_addr = spim_wb_addr[7:4]; |
|
// implement slave model register read mux |
always_comb |
begin |
reg_rdata = '0; |
case(spim_wb_addr[7:4]) |
REG_CTRL: |
reg_rdata[31:0] = { 20'h0, |
reg2spi_csreg, |
3'b0, |
reg2spi_swrst, |
reg2spi_qwr, |
reg2spi_qrd, |
reg2spi_wr, |
reg2spi_rd}; |
if(spim_reg_req) begin |
case(reg_addr) |
REG_CTRL: |
reg_rdata[31:0] = { 20'h0, |
reg2spi_csreg, |
3'b0, |
reg2spi_swrst, |
reg2spi_qwr, |
reg2spi_qrd, |
reg2spi_wr, |
reg2spi_rd}; |
|
REG_CLKDIV: |
reg_rdata[31:0] = {24'h0,spi_clk_div}; |
REG_SPICMD: |
reg_rdata[31:0] = {16'h0,reg2spi_mode,reg2spi_cmd}; |
REG_SPIADR: |
reg_rdata[31:0] = reg2spi_addr; |
REG_SPILEN: |
reg_rdata[31:0] = {reg2spi_data_len,2'b00,reg2spi_addr_len,1'b0,reg2spi_mode_enb,reg2spi_cmd_len}; |
REG_SPIDUM: |
reg_rdata[31:0] = {reg2spi_dummy_wr_len,reg2spi_dummy_rd_len}; |
REG_SPIWDATA: |
reg_rdata[31:0] = reg2spi_wdata; |
REG_SPIRDATA: |
reg_rdata[31:0] = spim_reg_rdata; |
REG_STATUS: |
reg_rdata[31:0] = {24'h0,spi_status}; |
endcase |
REG_CLKDIV: |
reg_rdata[31:0] = {24'h0,spi_clk_div}; |
REG_SPICMD: |
reg_rdata[31:0] = {16'h0,reg2spi_mode,reg2spi_cmd}; |
REG_SPIADR: |
reg_rdata[31:0] = reg2spi_addr; |
REG_SPILEN: |
reg_rdata[31:0] = {reg2spi_data_len,2'b00,reg2spi_addr_len,1'b0,reg2spi_mode_enb,reg2spi_cmd_len}; |
REG_SPIDUM: |
reg_rdata[31:0] = {reg2spi_dummy_wr_len,reg2spi_dummy_rd_len}; |
REG_SPIWDATA: |
reg_rdata[31:0] = reg2spi_wdata; |
REG_SPIRDATA: |
reg_rdata[31:0] = spim_reg_rdata; |
REG_STATUS: |
reg_rdata[31:0] = {23'h0,spi_status}; |
endcase |
end |
end |
|
|
/spim_rx.sv
72,7 → 72,6
logic [15:0] counter; |
logic [15:0] counter_trgt; |
logic [15:0] counter_next; |
logic [15:0] counter_trgt_next; |
logic reg_done; |
enum logic [1:0] { IDLE, RECEIVE, WAIT_FIFO, WAIT_FIFO_DONE } rx_CS, rx_NS; |
|
81,20 → 80,11
|
// RISV is little endian, so data is converted to little endian format |
assign data = (ENDIEAN) ? data_int_next : {data_int_next[7:0],data_int_next[15:8],data_int_next[23:16],data_int_next[31:24]}; |
assign rx_done = (counter == (counter_trgt-1)) & rx_edge; |
|
always_comb |
begin |
if (counter_in_upd) |
counter_trgt_next = (en_quad_in) ? {2'b00,counter_in[15:2]} : counter_in; |
else |
counter_trgt_next = counter_trgt; |
end |
|
always_comb |
begin |
rx_NS = rx_CS; |
clk_en_o = 1'b0; |
data_int_next = data_int; |
data_valid = 1'b0; |
counter_next = counter; |
101,7 → 91,6
|
case (rx_CS) |
IDLE: begin |
clk_en_o = 1'b0; |
|
// check first if there is available space instead of later |
if (en) begin |
110,7 → 99,6
end |
|
RECEIVE: begin |
clk_en_o = 1'b1; |
|
if (rx_edge) begin |
counter_next = counter + 1; |
132,7 → 120,6
|
if (~data_ready) begin |
// no space in the FIFO, wait for free space |
clk_en_o = 1'b0; |
rx_NS = WAIT_FIFO; |
end |
end |
161,14 → 148,22
counter <= 0; |
counter_trgt <= 'h8; |
data_int <= '0; |
rx_done <= '0; |
clk_en_o <= '0; |
rx_CS <= IDLE; |
end |
else |
begin |
counter <= counter_next; |
counter_trgt <= counter_trgt_next; |
data_int <= data_int_next; |
rx_CS <= rx_NS; |
if (rx_edge) begin |
counter <= counter_next; |
data_int <= data_int_next; |
rx_CS <= rx_NS; |
rx_done <= (counter_next == (counter_trgt-1)) && (rx_NS == RECEIVE); |
clk_en_o <= (rx_NS == RECEIVE); |
end |
if (en && counter_in_upd) begin |
counter_trgt <= (en_quad_in) ? {2'b00,counter_in[15:2]} : counter_in; |
end |
end |
end |
|
/spim_top.sv
85,7 → 85,8
|
logic [7:0] spi_clk_div; |
logic spi_clk_div_valid; |
logic [7:0] spi_status; |
logic spi_req; |
logic spi_ack; |
logic [31:0] spi_addr; |
logic [5:0] spi_addr_len; |
logic [7:0] spi_cmd; |
109,7 → 110,7
logic [31:0] spi_data_rx; |
logic spi_data_rx_valid; |
logic spi_data_rx_ready; |
logic [7:0] spi_ctrl_status; |
logic [8:0] spi_ctrl_status; |
logic [31:0] spi_ctrl_data_tx; |
logic spi_ctrl_data_tx_valid; |
logic spi_ctrl_data_tx_ready; |
144,7 → 145,7
|
.spi_clk_div (spi_clk_div ), |
.spi_clk_div_valid (spi_clk_div_valid ), |
.spi_status (spi_status ), |
.spi_status (spi_ctrl_status ), |
|
|
.spi_req (spi_req ), |
/spim_tx.sv
80,16 → 80,7
|
enum logic [0:0] { IDLE, TRANSMIT } tx_CS, tx_NS; |
|
// Counter Exit condition, quad mode div-4 , else actual counter |
always_comb |
begin |
counter_trgt = (en_quad_in) ? {2'b00,counter_in[15:2]} : counter_in; |
end |
|
//Indicate end of transmission of all the bytes |
assign tx_done = (counter == counter_trgt) && tx_edge; |
|
|
// Indicate 32 bit data done, usefull for readining next 32b from txfifo |
assign tx32b_done = (!en_quad && (counter[4:0] == 5'b11111)) || (en_quad && (counter[2:0] == 3'b111)) && tx_edge; |
|
98,7 → 89,6
always_comb |
begin |
tx_NS = tx_CS; |
clk_en_o = 1'b0; |
data_int_next = data_int; |
data_ready = 1'b0; |
counter_next = counter; |
105,8 → 95,8
|
case (tx_CS) |
IDLE: begin |
clk_en_o = 1'b0; |
data_int_next = txdata; |
counter_next = '0; |
|
if (en && data_valid) begin |
data_ready = 1'b1; |
115,27 → 105,24
end |
|
TRANSMIT: begin |
clk_en_o = 1'b1; |
counter_next = counter + 1; |
data_int_next = (en_quad) ? {data_int[27:0],4'b0000} : {data_int[30:0],1'b0}; |
counter_next = counter + 1; |
data_int_next = (en_quad) ? {data_int[27:0],4'b0000} : {data_int[30:0],1'b0}; |
|
if (tx_done) begin |
if (tx_done) begin |
counter_next = 0; |
// Check if there is next data |
// Check if there is next data |
if (en && data_valid) begin |
data_int_next = txdata; |
data_ready = 1'b1; |
tx_NS = TRANSMIT; |
end else begin |
clk_en_o = 1'b0; |
tx_NS = IDLE; |
end |
end else if (tx32b_done) begin |
end else if (tx32b_done) begin |
if (data_valid) begin |
data_int_next = txdata; |
data_ready = 1'b1; |
end else begin |
clk_en_o = 1'b0; |
tx_NS = IDLE; |
end |
end |
151,6 → 138,13
data_int <= 'h0; |
tx_CS <= IDLE; |
en_quad <= 0; |
tx_done <= '0; |
clk_en_o <= '0; |
sdo0 <= '0; |
sdo1 <= '0; |
sdo2 <= '0; |
sdo3 <= '0; |
counter_trgt <= '0; |
end |
else |
begin |
158,12 → 152,18
counter <= counter_next; |
data_int <= data_int_next; |
sdo0 <= (en_quad_in) ? data_int_next[28] : data_int_next[31]; |
sdo1 <= (en_quad_in) ? data_int_next[29] : 1'b1; |
sdo2 <= (en_quad_in) ? data_int_next[30] : 1'b1; |
sdo3 <= (en_quad_in) ? data_int_next[31] : 1'b1; |
sdo1 <= (en_quad_in) ? data_int_next[29] : 1'b0; |
sdo2 <= (en_quad_in) ? data_int_next[30] : 1'b0; |
sdo3 <= (en_quad_in) ? data_int_next[31] : 1'b0; |
tx_CS <= tx_NS; |
en_quad <= en_quad_in; |
tx_done <= (counter_next == (counter_trgt -1)) && (tx_NS == TRANSMIT); |
clk_en_o <= (tx_NS == TRANSMIT); |
end |
end |
// Counter Exit condition, quad mode div-4 , else actual counter |
if (en && data_valid) begin |
counter_trgt <= (en_quad_in) ? {2'b00,counter_in[15:2]} : counter_in; |
end |
end |
end |
endmodule |