interface - Input Signal Edge Detection on FPGA -
i trying interface virtex 4 (ml401) fpga , tiva c series board using 4 wire spi (cs, sclk, miso, mosi). tiva acts master , fpga slave. able receive spi data master , display data on leds present on fpga (method 2). however, need find rising , falling transitions of chip select signal (required application synchronization purposes). have tried many methods fifo's (that work in simulation) don't work on fpga, shown:
note: spi_cs asynchronous spi chip select signal input fpga tiva board, while other signals (spi_cs_s, spi_cs_ss, spi_cs_h2l, spi_cs_l2h, etc) created internally on fpga.
method 1)
prc_sync_cs: process(clk) begin if (clk'event , clk = '1') spi_cs_s <= spi_cs; end if; end process prc_sync_cs; spi_cs_l2h <= not (spi_cs_s) , spi_cs; spi_cs_h2l <= not (spi_cs) , spi_cs_s;
method 2)
process (spi_cs) begin if (spi_cs = '0' or spi_cs = '1') -- update ledss new mosi on rising edge of cs spi_cs_ss <= spi_cs_s; spi_cs_s <= spi_cs; --leds <= spi_wdata; --leds display received data on fpga (saved spi_wdata in process) -- works on fgpa edge detection doesn't. why? end if; end process; spi_cs_h2l <= '1' when (spi_cs_s = '0' , spi_cs_ss = '1') else '0'; spi_cs_l2h <= '1' when (spi_cs_s = '1' , spi_cs_ss = '0') else '0'; leds <= "000000" & spi_cs_h2l & spi_cs_l2h; -- leds off (i,e both transitions '0' always).
method 3)
prc_sync_cs: process(clk) begin if (clk'event , clk = '1') spi_cs_ss <= spi_cs_s; spi_cs_s <= spi_cs; end if; end process prc_sync_cs; prc_edge_cs: process(clk) begin if (clk'event , clk = '1') spi_cs_ss_del <= spi_cs_ss; end if; end process prc_edge_cs; spi_cs_h2l <= '1' when (spi_cs_ss_del = '1' , spi_cs_ss = '0') else '0'; spi_cs_l2h <= '1' when (spi_cs_ss_del = '0' , spi_cs_ss = '1') else '0';
all methods work in simulation not when downloaded on fpga. wrote process monitor transitions more closely (to monitor metastable values, if any):
led_test: process(spi_cs_h2l, spi_cs_l2h) begin if spi_cs_h2l = '1' or spi_cs_l2h = '1' leds <= "111100" & spi_cs_h2l & spi_cs_l2h; elsif spi_cs_h2l = 'x' or spi_cs_h2l = 'u' or spi_cs_h2l = 'z' or spi_cs_l2h = 'x' or spi_cs_l2h = 'u' or spi_cs_l2h = 'z' leds <= "00001111"; else leds <= "10101010"; end if; end process led_test;
the leds "10101010" i.e else case both spi_cs_h2l , spi_cs_l2h = '0'. missing ?? pointers helpful stuck issue since many days.
update
using method 3 of clock domain crossing (as suggested jeff), , initializing leds , signals zero, process light leds changed follows:
led_test: process(spi_cs_h2l) begin if rising_edge(clk) if spi_cs_h2l = '1' leds <= "11110011"; end if; end if; end process led_test;
at least 1 high low transition of chip select pin expected light leds. spi chip select pin receiving '1' , when fpga started/reset, leds light up. how possible? how can false high low transition occur ?
method 1
this not perform sort of clock domain crossing on spi_cs
signal, , not reliable circuit.
method 2
the line if (spi_cs = '0' or spi_cs = '1') then
true in synthesised design, wouldn't expect able detect edge using this
method 3
this provide clock domain crossing spi_cs
, , in general looks pretty good. reason see "10101010"
on leds, because show different 1 clk
period @ time, @ start or end of spi transaction. faster can see naked eye on leds.
additionally, line elsif spi_cs_h2l = 'x' or spi_cs_h2l = 'u' or spi_cs_h2l = 'z' or spi_cs_l2h = 'x' or spi_cs_l2h = 'u' or spi_cs_l2h = 'z' then
not translate real hardware in fpga, because real hardware not have way check 'u'
, 'z'
, etc.
method 3 update
it sounds spi_cs
active low. need make sure initial values signals spi_cs_s
, spi_cs_ss
correct. in case, think should initialise them '1'
, seems normal state spi_cs
. signal declarations signal spi_cs_s : std_logic := '1'
. should able see behaving in simulation.
Comments
Post a Comment