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