OpenCores
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.