module ddr_ctrl( input sys_clk, // 12M on-board oscillator input rst_n, input test_flag, // 1: read register, 0: start convert data // 2132 input miso, output mosi, output cs_n, output sclk, //esp32 output MOSI_ESP32, output cs_ESP32, output sclk_ESP32, //uart output wire tx, // 串行输出信号 output test_flag_led, output convert_flag_led // for simulation // output reg [25:0] state, // output reg [25:0] next, //output [15:0] dout ); reg start1, start2,start_uart; wire done1,done2,done_uart; localparam [4:0] s0 = 0, s1 = 1, s2 = 2, s3 = 3, s4 = 4, s5 = 5, s6 = 6, s7 = 7, s8 = 8, s9 = 9, s10 = 10, s11 = 11, s12 = 12, s13 = 13, s14 = 14, s15 = 15, s16 = 16, s17 = 17, s18 = 18, s19 = 19, s20 = 20, s21 = 21, s22 = 22, s23 = 23, s24 = 24, s25 = 25, s26 = 26, s27 = 27, s28 = 28, s29 = 29, s30 = 30; reg [30:0] state, next; reg [15:0] din_r; wire [15:0] din; reg [15:0] received_data; // 存储从从机1接收到的数据 reg [15:0] sent_data; // 要发送到从机2的数据 assign din = din_r; assign test_flag_led = test_flag; assign convert_flag_led = ~test_flag; // 定义状态编码 parameter IDLE = 2'b00, SEND1 = 2'b01, SEND2 = 2'b10, SEND_uart =2'b11; // 定义状态变量 reg [1:0] state_top; //状态机,用于控制两个SPI模块的启动 always @(posedge clk_115200 or negedge rst_n) begin if (!rst_n) begin start1 <= 0; start2 <= 0; state_top <= IDLE; end else begin case (state_top) IDLE: begin start1 <= 1; // 启动SPI主机1 start2 <= 0; state_top <= SEND1; end SEND1: begin if (done1) begin // SPI主机1完成接收 start1 <= 0; received_data <= dout1; // 存储接收到的数据 sent_data <= dout1; // 将接收到的数据准备好发送 start_uart <= 1; // 启动SPI主机2,发送数据给从机2 state_top <= SEND_uart; end end SEND_uart: begin if (done_uart) begin // uart完成发送 start_uart <= 0; //start2 <= 1; state_top <= IDLE; end end SEND2: begin if (done2) begin // SPI主机2完成发送 start2 <= 0; state_top <= IDLE; // 回到初始状态,等待下一轮传输 end end default: state_top <= IDLE; endcase end end //时序逻辑加组合逻辑完成din命令的有序发送 always @ (posedge cs_n or negedge rst_n) begin if(!rst_n) begin state <= 31'd0; state[s0] <= 1'b1; end else state <= next; end always @ (*) begin next = 31'd0; din_r = {2'b11,6'd63,8'h00}; case(1'b1) // synthesis parallel_case full_case state[s0]: begin din_r<={2'b11,6'd63,8'h00}; next[s1] = 1'b1; end state[s1]: begin din_r<={2'b11,6'd63,8'h00}; next[s2] = 1'b1; end state[s2]: begin din_r<={2'b10,6'd0,8'hDE}; next[s3] = 1'b1; end state[s3]: begin din_r<={2'b10,6'd1,8'h20}; next[s4] = 1'b1; end //8'h20 state[s4]: begin din_r<={2'b10,6'd2,8'h28}; next[s5] = 1'b1; end //8'h28 state[s5]: begin din_r<={2'b10,6'd3,8'h00}; next[s6] = 1'b1; end state[s6]: begin din_r<={2'b10,6'd4,8'hD6}; next[s7] = 1'b1; end state[s7]: begin din_r<={2'b10,6'd5,8'h00}; next[s8] = 1'b1; end state[s8]: begin din_r<={2'b10,6'd6,8'h80}; next[s9] = 1'b1; end state[s9]: begin din_r<={2'b10,6'd7,8'h00}; next[s10] = 1'b1; end state[s10]: begin din_r<={2'b10,6'd8,8'h16}; next[s11] = 1'b1; end state[s11]: begin din_r<={2'b10,6'd9,8'h80}; next[s12] = 1'b1; end state[s12]: begin din_r<={2'b10,6'd10,8'h17}; next[s13] = 1'b1; end state[s13]: begin din_r<={2'b10,6'd11,8'h80}; next[s14] = 1'b1; end state[s14]: begin din_r<={2'b10,6'd12,8'h2C}; next[s15] = 1'b1; end state[s15]: begin din_r<={2'b10,6'd13,8'h86}; next[s16] = 1'b1; end state[s16]: begin din_r<={2'b10,6'd14,8'hFF}; next[s17] = 1'b1; end state[s17]: begin din_r<={2'b10,6'd15,8'hFF}; next[s18] = 1'b1; end state[s18]: begin din_r<={2'b10,6'd16,8'hFF}; next[s19] = 1'b1; end state[s19]: begin din_r<={2'b10,6'd17,8'hFF}; next[s20] = 1'b1; end state[s20]: begin din_r<={2'b01,6'd21,8'h00}; next[s21] = 1'b1; end // CALIBRATE, {01,010101,8h00} state[s21]: begin din_r<={2'b11,6'd63,8'h00}; next[s22] = 1'b1; end // dummy 1 state[s22]: begin din_r<={2'b11,6'd63,8'h00}; next[s23] = 1'b1; end // dummy 2 state[s23]: begin din_r<={2'b11,6'd63,8'h00}; next[s24] = 1'b1; end // dummy 3 state[s24]: begin din_r<={2'b11,6'd63,8'h00}; next[s25] = 1'b1; end // dummy 4 state[s25]: begin din_r<={2'b11,6'd63,8'h00}; next[s26] = 1'b1; end // dummy 5 state[s26]: begin din_r<={2'b11,6'd63,8'h00}; next[s27] = 1'b1; end // dummy 6 state[s27]: begin din_r<={2'b11,6'd63,8'h00}; next[s28] = 1'b1; end // dummy 7 state[s28]: begin din_r<={2'b11,6'd63,8'h00}; next[s29] = 1'b1; end // dummy 8 state[s29]: begin din_r<={2'b11,6'd62,8'h00}; next[s30] = 1'b1; end // dummy 9 state[s30]: begin if (test_flag) begin din_r<={2'b00,6'd21,8'h00}; end // convert(3) else begin din_r<={2'b11,6'd62,8'h00}; end // read(63) next[s30] = 1'b1; end endcase end wire clk_115200; wire clk_230400; clk_gen clk_gen_inst ( .inclk0 ( sys_clk ), .c0 ( clk_115200 ), .c1 ( clk_230400 ) ); wire [15:0] dout1; spi_master_2164 u_spi_master_2164( .sys_clk(clk_115200 ), .rst_n(rst_n), .din(din), .start(start1), .dout(dout1), .done(done1), .sclk(sclk), .cs_n(cs_n), .mosi(mosi), .miso(miso), .cnt() ); spi_master_esp32 tranfer( .clk(sys_clk), .rst_n(rst_n), .start(start2), .din(sent_data), .done(done2), .sclk(sclk_ESP32), .mosi(MOSI_ESP32), .cs(cs_ESP32) ); uart_tx u_uart_pc( .clk(clk_115200), // 时钟信号 .rst(rst_n), // 复位信号 .tx_start(start_uart), // 开始发送信号 .tx_data(sent_data), // 顶层输入的16位待发送数据 .tx(tx), // 串行输出信号 .tx_done(done_uart) // 发送完成信号 ); endmodule