rtl:perips:xip: add qspi mode support
Signed-off-by: liangkangnan <liangkangnan@163.com>verilator
parent
e379fdd445
commit
574474acc8
|
@ -23,7 +23,7 @@ module spi_master_transmit (
|
|||
input logic read_i, // 0: write, 1: read
|
||||
input logic [1:0] spi_mode_i, // 0: Standard SPI, 1: Dual SPI, 2: Quad SPI, 3: Standard SPI
|
||||
input logic [1:0] cp_mode_i, // [1]表示CPOL, [0]表示CPHA
|
||||
input logic [1:0] data_width_i, // 数据宽度, 0: 8bits, 1: 16bits, 2: 32bits, 3: 8bits
|
||||
input logic [1:0] data_width_i, // 数据宽度, 0: 8bits, 1: 16bits, 2: 24bits, 3: 32bits
|
||||
input logic [31:0] data_i, // 数据输入
|
||||
input logic [2:0] div_ratio_i, // 分频比(2 ^ div_ratio_i)
|
||||
input logic msb_first_i, // 1: MSB, 0: LSB
|
||||
|
@ -55,9 +55,15 @@ module spi_master_transmit (
|
|||
output logic spi_dq3_oe_o
|
||||
);
|
||||
|
||||
// SPI模式
|
||||
localparam MODE_STAND_SPI = 2'b00;
|
||||
localparam MODE_DUAL_SPI = 2'b01;
|
||||
localparam MODE_QUAD_SPI = 2'b10;
|
||||
// 数据宽度
|
||||
localparam SPI_DATA_WIDTH_8 = 2'b00;
|
||||
localparam SPI_DATA_WIDTH_16 = 2'b01;
|
||||
localparam SPI_DATA_WIDTH_24 = 2'b10;
|
||||
localparam SPI_DATA_WIDTH_32 = 2'b11;
|
||||
|
||||
localparam S_IDLE = 3'b001;
|
||||
localparam S_DATA = 3'b010;
|
||||
|
@ -173,28 +179,34 @@ module spi_master_transmit (
|
|||
if (edge_cnt_q != 8'd0) begin
|
||||
case (spi_mode_q)
|
||||
MODE_STAND_SPI: begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
out_data_d = {out_data_q[14:0], 1'b0};
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
out_data_d = {out_data_q[30:0], 1'b0};
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
out_data_d = {out_data_q[22:0], 1'b0};
|
||||
end else begin
|
||||
out_data_d = {out_data_q[6:0], 1'b0};
|
||||
end
|
||||
end
|
||||
MODE_DUAL_SPI : begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
out_data_d = {out_data_q[13:0], 2'b0};
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
out_data_d = {out_data_q[29:0], 2'b0};
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
out_data_d = {out_data_q[21:0], 2'b0};
|
||||
end else begin
|
||||
out_data_d = {out_data_q[5:0], 2'b0};
|
||||
end
|
||||
end
|
||||
MODE_QUAD_SPI : begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
out_data_d = {out_data_q[11:0], 4'b0};
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
out_data_d = {out_data_q[27:0], 4'b0};
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
out_data_d = {out_data_q[19:0], 4'b0};
|
||||
end else begin
|
||||
out_data_d = {out_data_q[3:0], 4'b0};
|
||||
end
|
||||
|
@ -206,28 +218,34 @@ module spi_master_transmit (
|
|||
end else begin
|
||||
case (spi_mode_q)
|
||||
MODE_STAND_SPI: begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
in_data_d = {in_data_q[14:0], spi_dq1_i};
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
in_data_d = {in_data_q[30:0], spi_dq1_i};
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
in_data_d = {in_data_q[22:0], spi_dq1_i};
|
||||
end else begin
|
||||
in_data_d = {in_data_q[6:0], spi_dq1_i};
|
||||
end
|
||||
end
|
||||
MODE_DUAL_SPI : begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
in_data_d = {in_data_q[13:0], spi_dq1_i, spi_dq0_i};
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
in_data_d = {in_data_q[29:0], spi_dq1_i, spi_dq0_i};
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
in_data_d = {in_data_q[21:0], spi_dq1_i, spi_dq0_i};
|
||||
end else begin
|
||||
in_data_d = {in_data_q[5:0], spi_dq1_i, spi_dq0_i};
|
||||
end
|
||||
end
|
||||
MODE_QUAD_SPI : begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
in_data_d = {in_data_q[11:0], spi_dq3_i, spi_dq2_i, spi_dq1_i, spi_dq0_i};
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
in_data_d = {in_data_q[27:0], spi_dq3_i, spi_dq2_i, spi_dq1_i, spi_dq0_i};
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
in_data_d = {in_data_q[19:0], spi_dq3_i, spi_dq2_i, spi_dq1_i, spi_dq0_i};
|
||||
end else begin
|
||||
in_data_d = {in_data_q[3:0], spi_dq3_i, spi_dq2_i, spi_dq1_i, spi_dq0_i};
|
||||
end
|
||||
|
@ -241,28 +259,34 @@ module spi_master_transmit (
|
|||
if (!cp_mode_q[0]) begin
|
||||
case (spi_mode_q)
|
||||
MODE_STAND_SPI: begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
out_data_d = {out_data_q[14:0], 1'b0};
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
out_data_d = {out_data_q[30:0], 1'b0};
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
out_data_d = {out_data_q[22:0], 1'b0};
|
||||
end else begin
|
||||
out_data_d = {out_data_q[6:0], 1'b0};
|
||||
end
|
||||
end
|
||||
MODE_DUAL_SPI : begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
out_data_d = {out_data_q[13:0], 2'b0};
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
out_data_d = {out_data_q[29:0], 2'b0};
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
out_data_d = {out_data_q[21:0], 2'b0};
|
||||
end else begin
|
||||
out_data_d = {out_data_q[5:0], 2'b0};
|
||||
end
|
||||
end
|
||||
MODE_QUAD_SPI : begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
out_data_d = {out_data_q[11:0], 4'b0};
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
out_data_d = {out_data_q[27:0], 4'b0};
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
out_data_d = {out_data_q[19:0], 4'b0};
|
||||
end else begin
|
||||
out_data_d = {out_data_q[3:0], 4'b0};
|
||||
end
|
||||
|
@ -273,28 +297,34 @@ module spi_master_transmit (
|
|||
end else begin
|
||||
case (spi_mode_q)
|
||||
MODE_STAND_SPI: begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
in_data_d = {in_data_q[14:0], spi_dq1_i};
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
in_data_d = {in_data_q[30:0], spi_dq1_i};
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
in_data_d = {in_data_q[22:0], spi_dq1_i};
|
||||
end else begin
|
||||
in_data_d = {in_data_q[6:0], spi_dq1_i};
|
||||
end
|
||||
end
|
||||
MODE_DUAL_SPI : begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
in_data_d = {in_data_q[13:0], spi_dq1_i, spi_dq0_i};
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
in_data_d = {in_data_q[29:0], spi_dq1_i, spi_dq0_i};
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
in_data_d = {in_data_q[21:0], spi_dq1_i, spi_dq0_i};
|
||||
end else begin
|
||||
in_data_d = {in_data_q[5:0], spi_dq1_i, spi_dq0_i};
|
||||
end
|
||||
end
|
||||
MODE_QUAD_SPI : begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
in_data_d = {in_data_q[11:0], spi_dq3_i, spi_dq2_i, spi_dq1_i, spi_dq0_i};
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
in_data_d = {in_data_q[27:0], spi_dq3_i, spi_dq2_i, spi_dq1_i, spi_dq0_i};
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
in_data_d = {in_data_q[19:0], spi_dq3_i, spi_dq2_i, spi_dq1_i, spi_dq0_i};
|
||||
end else begin
|
||||
in_data_d = {in_data_q[3:0], spi_dq3_i, spi_dq2_i, spi_dq1_i, spi_dq0_i};
|
||||
end
|
||||
|
@ -356,33 +386,40 @@ module spi_master_transmit (
|
|||
endcase
|
||||
end
|
||||
|
||||
// 沿个数
|
||||
always_comb begin
|
||||
total_edge_cnt_d = 8'd63;
|
||||
|
||||
case (spi_mode_q)
|
||||
MODE_STAND_SPI: begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
total_edge_cnt_d = 8'd31;
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
total_edge_cnt_d = 8'd63;
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
total_edge_cnt_d = 8'd47;
|
||||
end else begin
|
||||
total_edge_cnt_d = 8'd15;
|
||||
end
|
||||
end
|
||||
MODE_DUAL_SPI : begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
total_edge_cnt_d = 8'd15;
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
total_edge_cnt_d = 8'd31;
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
total_edge_cnt_d = 8'd23;
|
||||
end else begin
|
||||
total_edge_cnt_d = 8'd7;
|
||||
end
|
||||
end
|
||||
MODE_QUAD_SPI : begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
total_edge_cnt_d = 8'd7;
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
total_edge_cnt_d = 8'd15;
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
total_edge_cnt_d = 8'd11;
|
||||
end else begin
|
||||
total_edge_cnt_d = 8'd3;
|
||||
end
|
||||
|
@ -423,6 +460,7 @@ module spi_master_transmit (
|
|||
end
|
||||
end
|
||||
|
||||
// 输入输出引脚
|
||||
always_comb begin
|
||||
spi_dq0_d = 1'b0;
|
||||
spi_dq1_d = 1'b0;
|
||||
|
@ -435,10 +473,12 @@ module spi_master_transmit (
|
|||
|
||||
case (spi_mode_q)
|
||||
MODE_STAND_SPI: begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
spi_dq0_d = out_data_d[15];
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
spi_dq0_d = out_data_d[31];
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
spi_dq0_d = out_data_d[23];
|
||||
end else begin
|
||||
spi_dq0_d = out_data_d[7];
|
||||
end
|
||||
|
@ -446,12 +486,15 @@ module spi_master_transmit (
|
|||
end
|
||||
|
||||
MODE_DUAL_SPI: begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
spi_dq0_d = out_data_d[14];
|
||||
spi_dq1_d = out_data_d[15];
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
spi_dq0_d = out_data_d[30];
|
||||
spi_dq1_d = out_data_d[31];
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
spi_dq0_d = out_data_d[22];
|
||||
spi_dq1_d = out_data_d[23];
|
||||
end else begin
|
||||
spi_dq0_d = out_data_d[6];
|
||||
spi_dq1_d = out_data_d[7];
|
||||
|
@ -466,16 +509,21 @@ module spi_master_transmit (
|
|||
end
|
||||
|
||||
MODE_QUAD_SPI: begin
|
||||
if (data_width_q == 2'd1) begin
|
||||
if (data_width_q == SPI_DATA_WIDTH_16) begin
|
||||
spi_dq0_d = out_data_d[12];
|
||||
spi_dq1_d = out_data_d[13];
|
||||
spi_dq2_d = out_data_d[14];
|
||||
spi_dq3_d = out_data_d[15];
|
||||
end else if (data_width_q == 2'd2) begin
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_32) begin
|
||||
spi_dq0_d = out_data_d[28];
|
||||
spi_dq1_d = out_data_d[29];
|
||||
spi_dq2_d = out_data_d[30];
|
||||
spi_dq3_d = out_data_d[31];
|
||||
end else if (data_width_q == SPI_DATA_WIDTH_24) begin
|
||||
spi_dq0_d = out_data_d[20];
|
||||
spi_dq1_d = out_data_d[21];
|
||||
spi_dq2_d = out_data_d[22];
|
||||
spi_dq3_d = out_data_d[23];
|
||||
end else begin
|
||||
spi_dq0_d = out_data_d[4];
|
||||
spi_dq1_d = out_data_d[5];
|
||||
|
|
|
@ -14,10 +14,7 @@
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
module xip_core #(
|
||||
parameter int unsigned TX_FIFO_DEPTH = 8,
|
||||
parameter int unsigned RX_FIFO_DEPTH = 8
|
||||
)(
|
||||
module xip_core(
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
||||
|
@ -55,9 +52,10 @@ module xip_core #(
|
|||
localparam OP_READ = 2'b00;
|
||||
localparam OP_WRITE = 2'b01;
|
||||
localparam OP_SECTOR_ERASE = 2'b10;
|
||||
localparam OP_QUAD_ENABLE = 2'b11;
|
||||
|
||||
localparam S_IDLE = 2'b01;
|
||||
localparam S_WAIT = 2'b10;
|
||||
localparam S_WAIT_VALID = 2'b10;
|
||||
|
||||
logic[1:0] state_d, state_q;
|
||||
logic valid_d, valid_q;
|
||||
|
@ -68,9 +66,24 @@ module xip_core #(
|
|||
logic valid;
|
||||
|
||||
// 去掉基地址
|
||||
assign addr = {9'h0, addr_i[22:0]};
|
||||
// addr_i[23], 1: 表示擦除扇区; 0: 表示编程数据
|
||||
assign op = (!we_i) ? OP_READ : addr_i[23] ? OP_SECTOR_ERASE : OP_WRITE;
|
||||
assign addr = {10'h0, addr_i[21:0]};
|
||||
|
||||
// addr_i[23:22], 11:使能Quad SPI模式,10: 擦除扇区; 00: 编程数据
|
||||
always_comb begin
|
||||
op = '0;
|
||||
|
||||
if (we_i) begin
|
||||
if (addr_i[23] & addr_i[22]) begin
|
||||
op = OP_QUAD_ENABLE;
|
||||
end else if (addr_i[23]) begin
|
||||
op = OP_SECTOR_ERASE;
|
||||
end else begin
|
||||
op = OP_WRITE;
|
||||
end
|
||||
end else begin
|
||||
op = OP_READ;
|
||||
end
|
||||
end
|
||||
|
||||
assign gnt_o = (req_i & (state_q == S_IDLE));
|
||||
assign rvalid_o = valid_q;
|
||||
|
@ -85,11 +98,11 @@ module xip_core #(
|
|||
S_IDLE: begin
|
||||
valid_d = 1'b0;
|
||||
if (req_i) begin
|
||||
state_d = S_WAIT;
|
||||
state_d = S_WAIT_VALID;
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT: begin
|
||||
S_WAIT_VALID: begin
|
||||
if (valid) begin
|
||||
state_d = S_IDLE;
|
||||
valid_d = 1'b1;
|
||||
|
|
|
@ -50,7 +50,8 @@ module xip_w25q64_ctrl(
|
|||
// 数据宽度
|
||||
localparam SPI_DATA_WIDTH_8 = 2'b00;
|
||||
localparam SPI_DATA_WIDTH_16 = 2'b01;
|
||||
localparam SPI_DATA_WIDTH_32 = 2'b10;
|
||||
localparam SPI_DATA_WIDTH_24 = 2'b10;
|
||||
localparam SPI_DATA_WIDTH_32 = 2'b11;
|
||||
// 2分频
|
||||
localparam SPI_CLK_DIV = 3'd1;
|
||||
// SPI极性
|
||||
|
@ -59,20 +60,25 @@ module xip_w25q64_ctrl(
|
|||
localparam OP_READ = 2'b00;
|
||||
localparam OP_WRITE = 2'b01;
|
||||
localparam OP_SECTOR_ERASE = 2'b10;
|
||||
localparam OP_QUAD_ENABLE = 2'b11;
|
||||
|
||||
localparam STATE_NUM = 12;
|
||||
localparam S_IDLE = 12'h001;
|
||||
localparam S_SS_LOW = 12'h002;
|
||||
localparam S_SS_HIGH = 12'h004;
|
||||
localparam S_WRITE_ENABLE = 12'h008;
|
||||
localparam S_WRITE_DISABLE = 12'h010;
|
||||
localparam S_SECTOR_ERASE = 12'h020;
|
||||
localparam S_PAGE_PROGRAM = 12'h040;
|
||||
localparam S_WRITE_DATA = 12'h080;
|
||||
localparam S_READ_DATA = 12'h100;
|
||||
localparam S_READ = 12'h200;
|
||||
localparam S_READ_STATUS = 12'h400;
|
||||
localparam S_CHECK_WIP = 12'h800;
|
||||
localparam STATE_NUM = 16;
|
||||
localparam S_IDLE = 16'h001;
|
||||
localparam S_SS_LOW = 16'h002;
|
||||
localparam S_SS_HIGH = 16'h004;
|
||||
localparam S_WRITE_ENABLE = 16'h008;
|
||||
localparam S_WRITE_DISABLE = 16'h010;
|
||||
localparam S_SECTOR_ERASE = 16'h020;
|
||||
localparam S_PAGE_PROGRAM = 16'h040;
|
||||
localparam S_WRITE_DATA = 16'h080;
|
||||
localparam S_READ_DATA = 16'h100;
|
||||
localparam S_READ32 = 16'h200;
|
||||
localparam S_READ_STATUS = 16'h400;
|
||||
localparam S_CHECK_WIP = 16'h800;
|
||||
localparam S_QUAD_ENABLE = 16'h1000;
|
||||
localparam S_READ8 = 16'h2000;
|
||||
localparam S_QUAD_WRITE_ADDR= 16'h4000;
|
||||
localparam S_READ_DUMMY = 16'h8000;
|
||||
|
||||
logic [STATE_NUM-1:0] state_d, state_q;
|
||||
logic [STATE_NUM-1:0] next_state_d, next_state_q;
|
||||
|
@ -119,7 +125,7 @@ module xip_w25q64_ctrl(
|
|||
op_d = op_i;
|
||||
wdata_d = wdata_i;
|
||||
state_d = S_SS_LOW;
|
||||
if ((op_i == OP_WRITE) | (op_i == OP_SECTOR_ERASE)) begin
|
||||
if ((op_i == OP_WRITE) | (op_i == OP_SECTOR_ERASE) | (op_i == OP_QUAD_ENABLE)) begin
|
||||
next_state_d = S_WRITE_ENABLE;
|
||||
end else begin
|
||||
next_state_d = S_READ_DATA;
|
||||
|
@ -143,8 +149,10 @@ module xip_w25q64_ctrl(
|
|||
data_d = 8'h06;
|
||||
if (op_q == OP_SECTOR_ERASE) begin
|
||||
next_state_d = S_SECTOR_ERASE;
|
||||
end else begin
|
||||
end else if (op_q == OP_WRITE) begin
|
||||
next_state_d = S_PAGE_PROGRAM;
|
||||
end else begin
|
||||
next_state_d = S_QUAD_ENABLE;
|
||||
end
|
||||
state_d = S_SS_HIGH;
|
||||
end
|
||||
|
@ -162,13 +170,25 @@ module xip_w25q64_ctrl(
|
|||
end
|
||||
end
|
||||
|
||||
S_QUAD_ENABLE: begin
|
||||
if (spi_idle) begin
|
||||
start_d = 1'b1;
|
||||
read_d = 1'b0;
|
||||
spi_mode_d = MODE_STAND_SPI;
|
||||
data_width_d = SPI_DATA_WIDTH_24;
|
||||
data_d = {8'h01, 8'h00, 8'h02};
|
||||
state_d = S_SS_HIGH;
|
||||
next_state_d = S_READ_STATUS;
|
||||
end
|
||||
end
|
||||
|
||||
S_PAGE_PROGRAM: begin
|
||||
if (spi_idle) begin
|
||||
start_d = 1'b1;
|
||||
read_d = 1'b0;
|
||||
spi_mode_d = MODE_STAND_SPI;
|
||||
data_width_d = SPI_DATA_WIDTH_32;
|
||||
data_d = {8'h02, addr_q[23:0]};
|
||||
data_d = {8'h32, addr_q[23:0]};
|
||||
state_d = S_WRITE_DATA;
|
||||
end
|
||||
end
|
||||
|
@ -177,7 +197,7 @@ module xip_w25q64_ctrl(
|
|||
if (spi_idle) begin
|
||||
start_d = 1'b1;
|
||||
read_d = 1'b0;
|
||||
spi_mode_d = MODE_STAND_SPI;
|
||||
spi_mode_d = MODE_QUAD_SPI;
|
||||
data_width_d = SPI_DATA_WIDTH_32;
|
||||
data_d = wdata_q;
|
||||
state_d = S_SS_HIGH;
|
||||
|
@ -204,11 +224,21 @@ module xip_w25q64_ctrl(
|
|||
spi_mode_d = MODE_STAND_SPI;
|
||||
data_width_d = SPI_DATA_WIDTH_8;
|
||||
data_d = 8'h05;
|
||||
state_d = S_READ;
|
||||
state_d = S_READ8;
|
||||
next_state_d = S_CHECK_WIP;
|
||||
end
|
||||
end
|
||||
|
||||
S_READ8: begin
|
||||
if (spi_idle) begin
|
||||
start_d = 1'b1;
|
||||
read_d = 1'b1;
|
||||
spi_mode_d = MODE_STAND_SPI;
|
||||
data_width_d = SPI_DATA_WIDTH_8;
|
||||
state_d = S_SS_HIGH;
|
||||
end
|
||||
end
|
||||
|
||||
S_CHECK_WIP: begin
|
||||
if (spi_idle) begin
|
||||
// flash is in WIP
|
||||
|
@ -227,18 +257,41 @@ module xip_w25q64_ctrl(
|
|||
start_d = 1'b1;
|
||||
read_d = 1'b0;
|
||||
spi_mode_d = MODE_STAND_SPI;
|
||||
data_width_d = SPI_DATA_WIDTH_32;
|
||||
data_d = {8'h03, addr_q[23:0]};
|
||||
state_d = S_READ;
|
||||
data_width_d = SPI_DATA_WIDTH_8;
|
||||
data_d = 8'hEB;
|
||||
state_d = S_QUAD_WRITE_ADDR;
|
||||
next_state_d = S_IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
S_READ: begin
|
||||
S_QUAD_WRITE_ADDR: begin
|
||||
if (spi_idle) begin
|
||||
start_d = 1'b1;
|
||||
read_d = 1'b0;
|
||||
spi_mode_d = MODE_QUAD_SPI;
|
||||
data_width_d = SPI_DATA_WIDTH_32;
|
||||
data_d = {addr_q[23:0], 8'h00};
|
||||
state_d = S_READ_DUMMY;
|
||||
next_state_d = S_IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
S_READ_DUMMY: begin
|
||||
if (spi_idle) begin
|
||||
start_d = 1'b1;
|
||||
read_d = 1'b1;
|
||||
spi_mode_d = MODE_STAND_SPI;
|
||||
spi_mode_d = MODE_QUAD_SPI;
|
||||
data_width_d = SPI_DATA_WIDTH_16;
|
||||
state_d = S_READ32;
|
||||
next_state_d = S_IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
S_READ32: begin
|
||||
if (spi_idle) begin
|
||||
start_d = 1'b1;
|
||||
read_d = 1'b1;
|
||||
spi_mode_d = MODE_QUAD_SPI;
|
||||
data_width_d = SPI_DATA_WIDTH_32;
|
||||
state_d = S_SS_HIGH;
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue