diff --git a/CPLD2/BUS_Con.v b/CPLD2/BUS_Con.v index b836e16..5f6924f 100644 --- a/CPLD2/BUS_Con.v +++ b/CPLD2/BUS_Con.v @@ -28,7 +28,6 @@ module BUS_Con ( reg [1:0] mosi_sync; wire cs_active; - wire cs_rise; wire sclk_rise; // For Sampling MOSI wire sclk_fall; // For Shifting MISO wire mosi_data; @@ -47,7 +46,6 @@ module BUS_Con ( end assign cs_active = ~cs_sync[1]; - assign cs_rise = (!cs_sync[1] && cs_sync[0]); // SPI Mode 0: Sample MOSI on Rising, Shift MISO on Falling assign sclk_rise = (!sclk_sync[1] && sclk_sync[0]); @@ -61,8 +59,9 @@ module BUS_Con ( reg err_flag; reg [1:0] state; // - reg [31:0] tx_buffer; // Holds data waiting for the next CS Low - reg [31:0] miso_shift; // The actual shifter + reg [31:0] miso_shift; // The actual shifter + reg wr_flag;// Flag: 1=W/0=R + reg miso_loaded; // Output Registers reg [6:0] addr_out; reg [23:0] data_out; @@ -82,9 +81,10 @@ module BUS_Con ( bit_cnt <= 6'd0; data_ready <= 1'b0; err_flag <= 1'b0; + wr_flag <= 1'b1; end else begin - // Clear data_ready when FSM has consumed the command + // Clear data_ready when FSM has consumed the command (CMD_SENT = consumed) if (state == CMD_SENT) begin data_ready <= 1'b0; end @@ -92,71 +92,76 @@ module BUS_Con ( if (cs_active) begin if (sclk_rise) begin recv_reg <= {recv_reg[30:0], mosi_data}; - if (bit_cnt == 6'd7) begin - // 8th bit received: check if read (MSB=0) or write (MSB=1) - if (recv_reg[0] == 1'b0) begin - // Read command: set data_ready after 8 bits + bit_cnt <= bit_cnt + 1'b1; + + // After 8 bits: check WR bit (recv_reg[7] = first bit received) + // Read (WR=0): set data_ready early so MISO data is prepared + // Write (WR=1): wait for all 32 bits + if (bit_cnt == 'd7) begin + if (recv_reg[6] == 1'b0) begin + // Read command: signal ready after address received data_ready <= 1'b1; + wr_flag <= 1'b0; + end + else begin + wr_flag <= 1'b1; end end else if (bit_cnt == 6'd31) begin - // 32nd bit received: write command complete + // Write command complete (32 bits received) data_ready <= 1'b1; end - bit_cnt <= bit_cnt + 1'b1; + end - else if (cs_rise) begin - if (bit_cnt == 6'd32) begin - data_ready <= 1'b1; - err_flag <= 1'b0; - bit_cnt <= 6'd0; - end - else if (bit_cnt != 0) begin - err_flag <= 1'b1; - bit_cnt <= 6'd0; + else if (!cs_active) begin + data_ready <= 1'b0; + if (bit_cnt == 6'd31) begin + err_flag <= 1'b0; + bit_cnt <= 6'd0; + end + else if (bit_cnt != 0 && bit_cnt != 6'd32) begin + err_flag <= 1'b1; + bit_cnt <= 6'd0; recv_reg <= 'd0; - end - end + end + end end - if (state == DONE) begin + else begin + // CS high: reset state + bit_cnt <= 6'd0; recv_reg <= 'd0; - end - end - end - - // --- 3. MISO (Transmit) Logic --- - // Protocol: We shift out 32 bits. - // Format: [8 bit Status/Padding] + [24 bit i_rdata] - - - // Capture data from backend when valid - always @(posedge i_sys_clk) begin - if (!i_rst_n) begin - tx_buffer <= 32'd0; - end else begin - // If backend provides valid read data, store it. - // We pad the top 8 bits with Zeros (or you can put status flags here) - if (i_rvalid) begin - tx_buffer <= {8'h00, i_rdata}; + data_ready <= 1'b0; end end end - // Shift data out + // --- 3. MISO (Transmit) Logic --- + // Protocol: We shift out 32 bits. + // Format: [8'h00 padding] + [24 bit i_rdata] + // Shift MSB out on each falling edge of SCLK (master samples on rising) + // Consolidated: load on first rising edge, shift on falling edges + always @(posedge i_sys_clk) begin if (!i_rst_n) begin - miso_shift <= 32'd0; - end else begin + miso_shift <= 32'd0; + miso_loaded <= 1'b0; + end + else begin if (!cs_active) begin // Reset shifter while CS is High - miso_shift <= 32'd0; - end else if (sclk_fall) begin - // Shift on Falling Edge (Master samples on Rising) - miso_shift <= {miso_shift[30:0], 1'b0}; + miso_shift <= 32'd0; end - // Load register data when read completes (takes priority over shift) - if (i_rvalid) begin - miso_shift <= {8'h00, i_rdata}; + else begin + if (i_rvalid && (bit_cnt == 'd8)) begin + miso_shift <= {i_rdata,8'd0}; + miso_loaded <= 1'b1; + end + if (miso_loaded && sclk_fall) begin + // Shift out MSB on falling edges (data valid before master's rising-edge sample) + if (bit_cnt > 'd8) begin + miso_shift <= {miso_shift[30:0], 1'b0}; + end + end end end end @@ -166,8 +171,8 @@ module BUS_Con ( assign o_miso = (cs_active) ? miso_shift[31] : 1'bz; // --- 4. Register Control FSM --- - - + // Command format: [WR:1b][Addr:7b][Data:24b] = 32 bits + // recv_reg layout after 32 bits: {WR, Addr[6:0], Data[23:0]} always @(posedge i_sys_clk) begin if (!i_rst_n) begin @@ -180,9 +185,16 @@ module BUS_Con ( case (state) IDLE: begin if (data_ready) begin - addr_out <= recv_reg[30:24]; - data_out <= recv_reg[23:0]; - wr_out <= recv_reg[31]; + // Extract fields from received command + if (wr_flag == 1'b1) begin + addr_out <= recv_reg[30:24]; + data_out <= recv_reg[23:0]; + wr_out <= recv_reg[31]; + end + else begin + addr_out <= recv_reg[6:0]; + wr_out <= recv_reg[7]; + end if (!i_reg_busy) begin cmd_valid_out <= 1'b1; diff --git a/CPLD2/RelayConTop.v b/CPLD2/RelayConTop.v index a20acac..103f5e9 100644 --- a/CPLD2/RelayConTop.v +++ b/CPLD2/RelayConTop.v @@ -73,7 +73,7 @@ BUS_Con BUS_Con_2( .i_rdata(r_data), .o_cmd_valid(cmd_valid), .o_wr(wr_flag), - .o_miso(o_miso), + .o_miso(o_miso), .o_rvalid(o_rvalid), .o_wready(o_wready), .o_data(w_data), diff --git a/CPLD3/BUS_Con.v b/CPLD3/BUS_Con.v index b836e16..5f6924f 100644 --- a/CPLD3/BUS_Con.v +++ b/CPLD3/BUS_Con.v @@ -28,7 +28,6 @@ module BUS_Con ( reg [1:0] mosi_sync; wire cs_active; - wire cs_rise; wire sclk_rise; // For Sampling MOSI wire sclk_fall; // For Shifting MISO wire mosi_data; @@ -47,7 +46,6 @@ module BUS_Con ( end assign cs_active = ~cs_sync[1]; - assign cs_rise = (!cs_sync[1] && cs_sync[0]); // SPI Mode 0: Sample MOSI on Rising, Shift MISO on Falling assign sclk_rise = (!sclk_sync[1] && sclk_sync[0]); @@ -61,8 +59,9 @@ module BUS_Con ( reg err_flag; reg [1:0] state; // - reg [31:0] tx_buffer; // Holds data waiting for the next CS Low - reg [31:0] miso_shift; // The actual shifter + reg [31:0] miso_shift; // The actual shifter + reg wr_flag;// Flag: 1=W/0=R + reg miso_loaded; // Output Registers reg [6:0] addr_out; reg [23:0] data_out; @@ -82,9 +81,10 @@ module BUS_Con ( bit_cnt <= 6'd0; data_ready <= 1'b0; err_flag <= 1'b0; + wr_flag <= 1'b1; end else begin - // Clear data_ready when FSM has consumed the command + // Clear data_ready when FSM has consumed the command (CMD_SENT = consumed) if (state == CMD_SENT) begin data_ready <= 1'b0; end @@ -92,71 +92,76 @@ module BUS_Con ( if (cs_active) begin if (sclk_rise) begin recv_reg <= {recv_reg[30:0], mosi_data}; - if (bit_cnt == 6'd7) begin - // 8th bit received: check if read (MSB=0) or write (MSB=1) - if (recv_reg[0] == 1'b0) begin - // Read command: set data_ready after 8 bits + bit_cnt <= bit_cnt + 1'b1; + + // After 8 bits: check WR bit (recv_reg[7] = first bit received) + // Read (WR=0): set data_ready early so MISO data is prepared + // Write (WR=1): wait for all 32 bits + if (bit_cnt == 'd7) begin + if (recv_reg[6] == 1'b0) begin + // Read command: signal ready after address received data_ready <= 1'b1; + wr_flag <= 1'b0; + end + else begin + wr_flag <= 1'b1; end end else if (bit_cnt == 6'd31) begin - // 32nd bit received: write command complete + // Write command complete (32 bits received) data_ready <= 1'b1; end - bit_cnt <= bit_cnt + 1'b1; + end - else if (cs_rise) begin - if (bit_cnt == 6'd32) begin - data_ready <= 1'b1; - err_flag <= 1'b0; - bit_cnt <= 6'd0; - end - else if (bit_cnt != 0) begin - err_flag <= 1'b1; - bit_cnt <= 6'd0; + else if (!cs_active) begin + data_ready <= 1'b0; + if (bit_cnt == 6'd31) begin + err_flag <= 1'b0; + bit_cnt <= 6'd0; + end + else if (bit_cnt != 0 && bit_cnt != 6'd32) begin + err_flag <= 1'b1; + bit_cnt <= 6'd0; recv_reg <= 'd0; - end - end + end + end end - if (state == DONE) begin + else begin + // CS high: reset state + bit_cnt <= 6'd0; recv_reg <= 'd0; - end - end - end - - // --- 3. MISO (Transmit) Logic --- - // Protocol: We shift out 32 bits. - // Format: [8 bit Status/Padding] + [24 bit i_rdata] - - - // Capture data from backend when valid - always @(posedge i_sys_clk) begin - if (!i_rst_n) begin - tx_buffer <= 32'd0; - end else begin - // If backend provides valid read data, store it. - // We pad the top 8 bits with Zeros (or you can put status flags here) - if (i_rvalid) begin - tx_buffer <= {8'h00, i_rdata}; + data_ready <= 1'b0; end end end - // Shift data out + // --- 3. MISO (Transmit) Logic --- + // Protocol: We shift out 32 bits. + // Format: [8'h00 padding] + [24 bit i_rdata] + // Shift MSB out on each falling edge of SCLK (master samples on rising) + // Consolidated: load on first rising edge, shift on falling edges + always @(posedge i_sys_clk) begin if (!i_rst_n) begin - miso_shift <= 32'd0; - end else begin + miso_shift <= 32'd0; + miso_loaded <= 1'b0; + end + else begin if (!cs_active) begin // Reset shifter while CS is High - miso_shift <= 32'd0; - end else if (sclk_fall) begin - // Shift on Falling Edge (Master samples on Rising) - miso_shift <= {miso_shift[30:0], 1'b0}; + miso_shift <= 32'd0; end - // Load register data when read completes (takes priority over shift) - if (i_rvalid) begin - miso_shift <= {8'h00, i_rdata}; + else begin + if (i_rvalid && (bit_cnt == 'd8)) begin + miso_shift <= {i_rdata,8'd0}; + miso_loaded <= 1'b1; + end + if (miso_loaded && sclk_fall) begin + // Shift out MSB on falling edges (data valid before master's rising-edge sample) + if (bit_cnt > 'd8) begin + miso_shift <= {miso_shift[30:0], 1'b0}; + end + end end end end @@ -166,8 +171,8 @@ module BUS_Con ( assign o_miso = (cs_active) ? miso_shift[31] : 1'bz; // --- 4. Register Control FSM --- - - + // Command format: [WR:1b][Addr:7b][Data:24b] = 32 bits + // recv_reg layout after 32 bits: {WR, Addr[6:0], Data[23:0]} always @(posedge i_sys_clk) begin if (!i_rst_n) begin @@ -180,9 +185,16 @@ module BUS_Con ( case (state) IDLE: begin if (data_ready) begin - addr_out <= recv_reg[30:24]; - data_out <= recv_reg[23:0]; - wr_out <= recv_reg[31]; + // Extract fields from received command + if (wr_flag == 1'b1) begin + addr_out <= recv_reg[30:24]; + data_out <= recv_reg[23:0]; + wr_out <= recv_reg[31]; + end + else begin + addr_out <= recv_reg[6:0]; + wr_out <= recv_reg[7]; + end if (!i_reg_busy) begin cmd_valid_out <= 1'b1;