Fix MISO logic for CPLD2 & CPLD3
This commit is contained in:
+68
-56
@@ -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;
|
||||
|
||||
+1
-1
@@ -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),
|
||||
|
||||
+68
-56
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user