Forum Discussion
Altera_Forum
Honored Contributor
13 years ago --- Quote Start --- But then again, I'd take a very different approach to this problem. I'd run my SPI interface logic on SCK, constraining SCK as a clock and constraining nCS and SO in relation to SCK. --- Quote End --- It's interesting that you mention this as this was my initial approach. I had code like so:
if rising_edge(sck) then
--do stuff
However, from discussions here and other forums I was recommended to actually sample the SCK signal with a much faster clock so thats approach I took. I synchronize the SCK signal via two flop flops and then detect their falling and rising edges and do operations based on that. Here is my actual architecture in VHDL: begin
if (nRESET_sync = '0') then
sck_rising <= '0';
sck_falling <= '0';
sck_delay <= '0';
elsif rising_edge(clk) then
if cs_sync = '1' then
sck_delay <= '0';
sck_rising <= '0';
sck_falling <= '0';
else
sck_delay <= sck_sync;
sck_rising <= sck_sync and (not sck_delay);
sck_falling <= (not sck_sync) and sck_delay;
end if;
end if;
end process;
process(clk, nRESET_sync)
begin
if (nRESET_sync = '0') then
cs_rising <= '0';
cs_falling <= '0';
cs_delay <= '0';
elsif rising_edge(clk) then
cs_delay <= cs_sync;
cs_rising <= cs_sync and (not cs_delay);
cs_falling <= (not cs_sync) and cs_delay;
end if;
end process;
process(CLK, nRESET_sync)
begin
if (nRESET_sync = '0') then
tmp <= (others => '0');
elsif rising_edge(CLK) then
if CS_sync = '0' then
if SCK_falling = '1' then
tmp <= tmp(PI'high -1 downto PI'low) & '0';
end if;
elsif CS_sync = '1' then
tmp <= PI;
end if;
end if;
end process;
SO <= tmp(PI'high) when nCS = '0' else 'Z'; Based on your suggestion, I'll also set a false path for SO, like so: set_false_path -from -to Perhaps I should tell you more about the design regarding SO: SO is actually output with combinational logic: SO <= tmp(PI'high) when nCS = '0' else 'Z'; So SO depends upon nCS and tmp(PI'high) depends on the the synced version of the SCK signal (when it's falling, to be exact). Should I still go ahead and set this as a false path? Could you explain why I need to set this as a false path? I also didn't quite understand this bit: --- Quote Start --- Since your 20 MHz clock is way faster than the 2 MHz SCK, you should be able to generate a SO signal which meets the MCUs timing requirements easily. 10 ns tHold => make sure you wait at least 1 clock (of sys_clk) between the rising of SCK and changing SO. 10 ns tSetup => make sure you wait less than 9 clocks between the rising of SCK and changing SO. --- Quote End --- How do I ensure that I wait at least 1 clock cycle between the rising edge of SCK and SO? Do I set a delay for 10 ns for both mix/max? But I thought you said to set SO as a false path? Sorry if I'm way off the path here!