FPGA/SPI: detect end of byte via MSB toggle instead of constant compare of async input

This commit is contained in:
Maximilian Rehkopf 2012-07-09 02:17:01 +02:00
parent c231c8b821
commit 968c347986
4 changed files with 79 additions and 39 deletions

View File

@ -143,12 +143,13 @@ reg [55:0] rtc_data_out_buf;
reg rtc_pgm_we_buf;
reg srtc_reset_buf;
initial srtc_reset_buf = 0;
reg [31:0] SNES_SYSCLK_FREQ_BUF;
reg [7:0] MCU_DATA_OUT_BUF;
reg [7:0] MCU_DATA_IN_BUF;
reg [1:0] mcu_nextaddr_buf;
reg [2:0] mcu_nextaddr_buf;
wire mcu_nextaddr;
@ -413,9 +414,9 @@ end
// value fetch during last SPI bit
always @(posedge clk) begin
if (cmd_data[7:4] == 4'h8 && mcu_nextaddr_buf == 2'b01)
if (cmd_data[7:4] == 4'h8 && mcu_nextaddr)
MCU_DATA_IN_BUF <= mcu_data_in;
else if (spi_bit_cnt == 3'h7) begin
else if (cmd_ready | param_ready /* bit_cnt == 7 */) begin
if (cmd_data[7:0] == 8'hF0)
MCU_DATA_IN_BUF <= 8'hA5;
else if (cmd_data[7:0] == 8'hF1)

View File

@ -39,15 +39,27 @@ module spi(
reg [7:0] cmd_data_r;
reg [7:0] param_data_r;
reg [1:0] SSELr; always @(posedge clk) SSELr <= {SSELr[0], SSEL};
reg [2:0] SSELr;
reg [2:0] SSELSCKr;
always @(posedge clk) SSELr <= {SSELr[1:0], SSEL};
always @(posedge SCK) SSELSCKr <= {SSELSCKr[1:0], SSEL};
wire SSEL_inactive = SSELr[1];
wire SSEL_active = ~SSELr[1]; // SSEL is active low
wire SSEL_startmessage = (SSELr[1:0]==2'b10); // message starts at falling edge
wire SSEL_endmessage = (SSELr[1:0]==2'b01); // message stops at rising edge
wire SSEL_startmessage = (SSELr[2:1]==2'b10); // message starts at falling edge
wire SSEL_endmessage = (SSELr[2:1]==2'b01); // message stops at rising edge
assign endmessage = SSEL_endmessage;
assign startmessage = SSEL_startmessage;
// bit count for one SPI byte + byte count for the message
reg [2:0] bitcnt;
initial bitcnt = 3'b000;
wire bitcnt_msb = bitcnt[2];
reg [2:0] bitcnt_wrap_r;
always @(posedge clk) bitcnt_wrap_r <= {bitcnt_wrap_r[1:0], bitcnt_msb};
wire byte_received_sync = (bitcnt_wrap_r[2:1] == 2'b10);
reg [31:0] byte_cnt_r;
reg byte_received; // high when a byte has been received
@ -56,23 +68,26 @@ reg [7:0] byte_data_received;
assign bit_cnt = bitcnt;
always @(posedge SCK) begin
if(SSEL) bitcnt <= 3'b000;
else begin
bitcnt <= bitcnt + 3'b001;
if(SSELSCKr[1]) bitcnt <= 3'b000;
else bitcnt <= bitcnt + 3'b001;
end
always @(posedge SCK) begin
if(~SSELSCKr[1]) begin
byte_data_received <= {byte_data_received[6:0], MOSI};
end
if(~SSEL && bitcnt==3'b111) byte_received <= 1'b1;
if(~SSELSCKr[1] && bitcnt==3'b111) byte_received <= 1'b1;
else byte_received <= 1'b0;
end
reg [1:0] byte_received_r;
always @(posedge clk) byte_received_r <= {byte_received_r[0], byte_received};
wire byte_received_sync = (byte_received_r == 2'b01);
//reg [2:0] byte_received_r;
//always @(posedge clk) byte_received_r <= {byte_received_r[1:0], byte_received};
//wire byte_received_sync = (byte_received_r[2:1] == 2'b01);
always @(posedge clk) begin
if(~SSEL_active)
if(SSEL_inactive) begin
byte_cnt_r <= 16'h0000;
else if(byte_received_sync) begin
end else if(byte_received_sync) begin
byte_cnt_r <= byte_cnt_r + 16'h0001;
end
end

View File

@ -39,15 +39,27 @@ module spi(
reg [7:0] cmd_data_r;
reg [7:0] param_data_r;
reg [1:0] SSELr; always @(posedge clk) SSELr <= {SSELr[0], SSEL};
reg [2:0] SSELr;
reg [2:0] SSELSCKr;
always @(posedge clk) SSELr <= {SSELr[1:0], SSEL};
always @(posedge SCK) SSELSCKr <= {SSELSCKr[1:0], SSEL};
wire SSEL_inactive = SSELr[1];
wire SSEL_active = ~SSELr[1]; // SSEL is active low
wire SSEL_startmessage = (SSELr[1:0]==2'b10); // message starts at falling edge
wire SSEL_endmessage = (SSELr[1:0]==2'b01); // message stops at rising edge
wire SSEL_startmessage = (SSELr[2:1]==2'b10); // message starts at falling edge
wire SSEL_endmessage = (SSELr[2:1]==2'b01); // message stops at rising edge
assign endmessage = SSEL_endmessage;
assign startmessage = SSEL_startmessage;
// bit count for one SPI byte + byte count for the message
reg [2:0] bitcnt;
initial bitcnt = 3'b000;
wire bitcnt_msb = bitcnt[2];
reg [2:0] bitcnt_wrap_r;
always @(posedge clk) bitcnt_wrap_r <= {bitcnt_wrap_r[1:0], bitcnt_msb};
wire byte_received_sync = (bitcnt_wrap_r[2:1] == 2'b10);
reg [31:0] byte_cnt_r;
reg byte_received; // high when a byte has been received
@ -56,23 +68,26 @@ reg [7:0] byte_data_received;
assign bit_cnt = bitcnt;
always @(posedge SCK) begin
if(SSEL) bitcnt <= 3'b000;
else begin
bitcnt <= bitcnt + 3'b001;
byte_data_received <= {byte_data_received[6:0], MOSI};
if(SSELSCKr[1]) bitcnt <= 3'b000;
else bitcnt <= bitcnt + 3'b001;
end
always @(posedge SCK) begin
if(~SSELSCKr[1]) begin
byte_data_received <= {byte_data_received[6:0], MOSI};
end
if(~SSEL && bitcnt==3'b111) byte_received <= 1'b1;
if(~SSELSCKr[1] && bitcnt==3'b111) byte_received <= 1'b1;
else byte_received <= 1'b0;
end
reg [1:0] byte_received_r;
always @(posedge clk) byte_received_r <= {byte_received_r[0], byte_received};
wire byte_received_sync = (byte_received_r == 2'b01);
//reg [2:0] byte_received_r;
//always @(posedge clk) byte_received_r <= {byte_received_r[1:0], byte_received};
//wire byte_received_sync = (byte_received_r[2:1] == 2'b01);
always @(posedge clk) begin
if(~SSEL_active)
if(SSEL_inactive) begin
byte_cnt_r <= 16'h0000;
else if(byte_received_sync) begin
end else if(byte_received_sync) begin
byte_cnt_r <= byte_cnt_r + 16'h0001;
end
end

View File

@ -47,11 +47,15 @@ wire SSEL_inactive = SSELr[1];
wire SSEL_active = ~SSELr[1]; // SSEL is active low
wire SSEL_startmessage = (SSELr[2:1]==2'b10); // message starts at falling edge
wire SSEL_endmessage = (SSELr[2:1]==2'b01); // message stops at rising edge
assign endmessage = SSEL_endmessage;
assign startmessage = SSEL_startmessage;
// bit count for one SPI byte + byte count for the message
reg [2:0] bitcnt;
initial bitcnt = 3'b000;
wire bitcnt_msb = bitcnt[2];
reg [2:0] bitcnt_wrap_r;
always @(posedge clk) bitcnt_wrap_r <= {bitcnt_wrap_r[1:0], bitcnt_msb};
wire byte_received_sync = (bitcnt_wrap_r[2:1] == 2'b10);
reg [31:0] byte_cnt_r;
reg byte_received; // high when a byte has been received
@ -60,27 +64,32 @@ reg [7:0] byte_data_received;
assign bit_cnt = bitcnt;
always @(posedge SCK) begin
if(SSEL) bitcnt <= 3'b000;
else begin
bitcnt <= bitcnt + 3'b001;
if(SSELSCKr[1]) bitcnt <= 3'b000;
else bitcnt <= bitcnt + 3'b001;
end
always @(posedge SCK) begin
if(~SSELSCKr[1]) begin
byte_data_received <= {byte_data_received[6:0], MOSI};
end
if(~SSEL && bitcnt==3'b111) byte_received <= 1'b1;
if(~SSELSCKr[1] && bitcnt==3'b111) byte_received <= 1'b1;
else byte_received <= 1'b0;
end
reg [1:0] byte_received_r;
always @(posedge clk) byte_received_r <= {byte_received_r[0], byte_received};
wire byte_received_sync = (byte_received_r == 2'b01);
//reg [2:0] byte_received_r;
//always @(posedge clk) byte_received_r <= {byte_received_r[1:0], byte_received};
//wire byte_received_sync = (byte_received_r[2:1] == 2'b01);
always @(posedge clk) begin
if(~SSEL_active)
if(SSEL_inactive) begin
byte_cnt_r <= 16'h0000;
else if(byte_received_sync) begin
end else if(byte_received_sync) begin
byte_cnt_r <= byte_cnt_r + 16'h0001;
end
end
reg [7:0] byte_data_sent;
assign MISO = ~SSEL ? input_data[7-bitcnt] : 1'bZ; // send MSB first
reg cmd_ready_r;