module SPIslave(
output wire MISO, //Master input , Slave output
output LEDS,
input MOSI, //Master ouput , slave input
input SS, //Slave select
input SCLK, //Serial clock
input CLK ,
output reg [3:0] ccount,
output reg [7:0] dataBUF
);
reg [7:0] dataBUF2;
reg try;
reg [2:0] SCLKr;
wire SCLK_falling,SCLK_rising;
assign SCLK_rising = (SCLKr[2:1] == 2'b01);
assign SCLK_falling = (SCLKr[2:1] == 2'b10);
always@ (posedge CLK) SCLKr <= {SCLKr[1:0],SCLK};
initial begin
dataBUF = 8'b11001010;
dataBUF2 = 8'hF0;
ccount = 4'b0000;
end
always @(posedge CLK)
begin
if(!SS) begin
if(SCLK_rising)
begin
dataBUF <= {dataBUF[6:0],MOSI};
ccount = ccount + 4'b1;
end
if(SCLK_falling)
begin
dataBUF2 <= {dataBUF2[6:0],dataBUF2[7]};
end
end
end
assign LEDS = ((dataBUF ==8'h66)||(dataBUF ==8'hAB)||(dataBUF ==8'hBA))? 1'b1:1'b0;
assign MISO = dataBUF2[7];
endmodule
the speed of the SPI clock is 2 MHz ,
i checked the voltage level of the outputs from the master , a 1 is 3.3V , a 0 is ~ 0 , which is acceptable as the the levels in the fpga for "1" is 2-4.1 volts ,and a 0 is between -0.5,0.8 volts .
i mentioned the internal clock , as it should be faster for sampling the spi clock.
any way this is my code
Code:module SPIslave( output wire MISO, //Master input , Slave output output LEDS, input MOSI, //Master ouput , slave input input SS, //Slave select input SCLK, //Serial clock input CLK , output reg [3:0] ccount, output reg [7:0] dataBUF ); reg [7:0] dataBUF2; reg try; reg [2:0] SCLKr; wire SCLK_falling,SCLK_rising; assign SCLK_rising = (SCLKr[2:1] == 2'b01); assign SCLK_falling = (SCLKr[2:1] == 2'b10); always@ (posedge CLK) SCLKr <= {SCLKr[1:0],SCLK}; initial begin dataBUF = 8'b11001010; dataBUF2 = 8'hF0; ccount = 4'b0000; end always @(posedge CLK) begin if(!SS) begin if(SCLK_rising) begin dataBUF <= {dataBUF[6:0],MOSI}; ccount = ccount + 4'b1; end if(SCLK_falling) begin dataBUF2 <= {dataBUF2[6:0],dataBUF2[7]}; end end end assign LEDS = ((dataBUF ==8'h66)||(dataBUF ==8'hAB)||(dataBUF ==8'hBA))? 1'b1:1'b0; assign MISO = dataBUF2[7]; endmodule
I don't agree. The OP is performing state-of-the-art synchronous edge detection for SCLK. It's supposed to work for fCLK > 2*fSCLK. In my opinion, it's the appropriate solution for a slow clock, it's using a single clock domain, as any FPGA text book would suggest for this case. You should visualize SCLK as well as the derived SCLK_xxx signals in Chipscope. If they look "noisy", a hardware problem should be expected.Wouldn't it be easier to clock the register with SCLK (rising or falling edge)?
The Rx register can the be transfered to the clock domain of the FPGA.
The reason that you don't get a decent output from your Rx process is that you sample several time the same bit of your SPI data.
I don't agree. The OP is performing state-of-the-art synchronous edge detection for SCLK. It's supposed to work for fCLK > 2*fSCLK. In my opinion, it's the appropriate solution for a slow clock, it's using a single clock domain, as any FPGA text book would suggest for this case. You should visualize SCLK as well as the derived SCLK_xxx signals in Chipscope. If they look "noisy", a hardware problem should be expected.
It's a clear design rule to avoid multiple clock domains where they aren't needed, simply because the data path synchronizing effort will be higher than alternative solutions. A low frequency serial slave interface is a clear example where an additional clock domain for the serial clock won't be appropriate. It would be different of course with a 20 or 50 MHz SPI clock.In an ideal world there is only one clock network ... that's why FPGA's have several clock networks right?
if(SCLK_rising)
begin
dataBUF <= {dataBUF[6:0],MOSI}; // This one...
ccount = ccount + 4'b1; // and this one...
end
Also, where are those pictures everyone seems to be seeing? @_@
assign SCLK_rising = (SCLKr[2:1] == 2'b01);
assign SCLK_falling = (SCLKr[2:1] == 2'b10);
I'm not particular familar with XILINX, but I can't imagine, that the problem has anything to do with the said IBUFG. I assume, that it's automatically inserted by the synthesis tool and can't be removed anyway.
can i use BUF_TYPE to assing BUFG to SCLK ,and dont' use the internal CLK ?
FvM said:It's a clear design rule to avoid multiple clock domains where they aren't needed, simply because the data path synchronizing effort will be higher than alternative solutions. A low frequency serial slave interface is a clear example where an additional clock domain for the serial clock won't be appropriate.
reg [3:0] mosi_sr;
reg mosi_filtered;
always (@posedge clk) begin
mosi_sr <= {mosi_sr[2:0], MOSI_IBUF};
if (mosi_filtered == 1'b0) begin
// only change from the current 0 state to a new 1 state if mosi_sr is ALL 1's
mosi_filtered <= (& mosi_sr)
end else begin
// only change from the current 1 state to a new 0 state if mosi_sr is ALL 0's
mosi_filtered <= (| mosi_sr)
end
end
Some interesting points have been discussed in detail. But I don't hear substantial news regarding the original problem of "noisy" (still an understatement) SCLK. (In the waveform, other signals like SS are screwed up too, by the way). Seriously, you shouldn't think about filtering useless digital signals rather than identifying the problem.
Have you tried looking at these 2 lines on a oscilloscope? You mention that the DC levels are good, but that doesn't mean that it will be all dandy during actual data activity..."
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?