From 2addbb3f09a69049fa892c83dda88cbe57a5bf73 Mon Sep 17 00:00:00 2001 From: rs <> Date: Tue, 11 Nov 2025 14:56:22 -0600 Subject: [PATCH] Add simulated STM host --- libraries/simulated/dev_stmhost.vhd | 209 ++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 libraries/simulated/dev_stmhost.vhd diff --git a/libraries/simulated/dev_stmhost.vhd b/libraries/simulated/dev_stmhost.vhd new file mode 100644 index 0000000..b2876b4 --- /dev/null +++ b/libraries/simulated/dev_stmhost.vhd @@ -0,0 +1,209 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.sim_utility.all; + + +entity stmhost is + port ( + -- Ports to peripheral + ifclk: out std_logic; + slcs: out std_logic; + flaga: out std_logic; + flagb: out std_logic; + slrd: in std_logic; + slwr: in std_logic; + sloe: in std_logic; + pktend: in std_logic; + fifoadr: in std_logic_vector(1 downto 0); + db: inout std_logic_vector(7 downto 0); + + -- Values to enqueue/dequeue host-side + host_dl_data: in std_logic_vector(7 downto 0); -- Assign to trigger downloading of a byte + host_ul_count: in integer -- Assign to expect more upload bytes + ); +end stmhost; + + +architecture behavioral of stmhost is + + ---------------------------------------------------------------------------- + -- Timing constants + + constant T_IFCLK: time := 20.83 ns; -- IFCLK Period + + constant T_SRD: time := 18.7 ns; -- SLRD to Clock Set-up Time + constant T_RDH: time := 0 ns; -- SLRD Hold Time + constant T_SWR: time := 18.7 ns; -- SLWR to Clock Set-up Time + constant T_WRH: time := 0 ns; -- SLWR Hold Time + constant T_SPE: time := 14.6 ns; -- PKTEND to Clock Set-up Time + constant T_PEH: time := 0 ns; -- Clock to PKTEND Hold Time + constant T_SFD: time := 9.2 ns; -- FIFO Data to Clock Set-up Time + constant T_FDH: time := 0 ns; -- Clock to FIFO Data Hold Time + constant T_SFA: time := 25 ns; -- FIFOADR[1:0] to Clock Set-up Time + constant T_FAH: time := 10 ns; -- Clock to FIFOADR[1:0] Hold Time + + constant T_OEON: time := 10.5 ns; -- SLOE Turn-on to FIFO Data Valid + constant T_OEOFF: time := 10.5 ns; -- SLOE Turn-off to FIFO Data Hold + constant T_XFLG: time := 9.5 ns; -- Clock to FLAGS Output Propagation Delay + constant T_XFD_C: time := 11 ns; -- Clock to FIFO Output Propagation Delay + constant T_XFD_A: time := 14.3 ns; -- FIFOADR[1:0] to FIFODATA Output Propagation Delay + + ---------------------------------------------------------------------------- + -- Output value + + shared variable dl_queue: queue_t; + shared variable head: integer := 0; + shared variable tail: integer := 0; + + signal value: std_logic_vector(7 downto 0); + signal zmask_sloe: std_logic; + + ---------------------------------------------------------------------------- + -- Handshake signalling and bookkeeping + + signal slcs_int: std_logic; + + ---------------------------------------------------------------------------- + -- Clock generation + + signal ifclk_int: std_logic; + signal adr_gate: std_logic; -- For testing fifoadr setup and hold times + signal db_gate: std_logic; -- For testing DB setup and hold times + +begin + + slcs_int <= '1'; + slcs <= slcs_int; + + ---------------------------------------------------------------------------- + -- Output value + + process + begin + dl_queue := queue_create; + wait; + end process; + + process (ifclk_int, host_dl_data'quiet, host_ul_count'quiet) + variable temp: std_logic_vector(7 downto 0); + variable ul_expected: integer := 0; + begin + -- Host enqueues items to download + if not host_dl_data'quiet then + report "DL FIFO insert " & integer'image(to_integer(unsigned(host_dl_data))); + queue_enq(dl_queue, host_dl_data); + value <= queue_peek(dl_queue) after T_XFD_C; + end if; + + -- Host sets number of expected upload bytes + if not host_ul_count'quiet then + report "UL FIFO expect " & integer'image(host_ul_count) & " more bytes"; + ul_expected := ul_expected + host_ul_count; + end if; + + -- Device access + if rising_edge(ifclk_int) then + -- Device downloads items + if slrd = '0' and queue_len(dl_queue) > 0 then + report "DL FIFO remove"; + queue_deq(dl_queue, temp); + value <= queue_peek(dl_queue) after T_XFD_C; + end if; + + -- Device uploads items + if slwr = '0' and ul_expected > 0 then + report "STM host received uploaded byte " & integer'image(to_integer(unsigned(db))); + ul_expected := ul_expected - 1; + end if; + + -- Download queue empty flag + if queue_len(dl_queue) = 0 then + flaga <= '1' after T_XFLG; + else + flaga <= '0' after T_XFLG; + end if; + + -- Upload queue full flag + if ul_expected = 0 then + flagb <= '1' after T_XFLG; + else + flagb <= '0' after T_XFLG; + end if; + end if; + end process; + + e_zmask_sloe: entity work.delay_edges + generic map (D_RISE => T_OEOFF, D_FALL => T_OEON) + port map (sig_in => sloe, sig_out => zmask_sloe); + + db <= (others => 'Z') when zmask_sloe = '1' else value; + + + ---------------------------------------------------------------------------- + -- IFCLK generation + + p_ifclk: process + begin + ifclk_int <= '1'; + wait for T_IFCLK / 2; + ifclk_int <= '0'; + wait for T_IFCLK / 2; + end process; + ifclk <= ifclk_int; + + + ---------------------------------------------------------------------------- + -- Timing and usage assertions + + process (slcs_int, slrd, slwr, fifoadr) + begin + -- Signals are only valid when SLCS asserted + if slcs_int = '1' then + assert not (slrd = '0' and slwr = '0') + report "SLRD and SLWR asserted at the same time" + severity error; + + assert fifoadr /= "01" and fifoadr /= "11" + report "Invalid FIFOADR value" + severity error; + + if slrd = '0' then + assert fifoadr = "00" + report "Reading from non-download FIFO" + severity error; + end if; + + if slwr = '0' then + assert fifoadr = "10" + report "Writing to non-upload FIFO" + severity error; + end if; + end if; + end process; + + e_setuphold_slrd: entity work.assert_setuphold + generic map (LEVEL => '1', T_SETUP => T_SRD, T_HOLD => T_RDH, NAME_REF => "IFCLK", NAME_SIG => "SLRD") + port map (ref => ifclk_int, sig => slrd, gate => slcs_int); + + e_setuphold_slwr: entity work.assert_setuphold + generic map (LEVEL => '1', T_SETUP => T_SWR, T_HOLD => T_WRH, NAME_REF => "IFCLK", NAME_SIG => "SLWR") + port map (ref => ifclk_int, sig => slwr, gate => slcs_int); + + e_setuphold_pktend: entity work.assert_setuphold + generic map (LEVEL => '1', T_SETUP => T_SPE, T_HOLD => T_PEH, NAME_REF => "IFCLK", NAME_SIG => "PKTEND") + port map (ref => ifclk_int, sig => pktend, gate => slcs_int); + + db_gate <= '1' when sloe = '0' and slcs_int = '1' else '0'; + e_setuphold_db: entity work.assert_setuphold_vec + generic map (LEVEL => '1', T_SETUP => T_SFD, T_HOLD => T_FDH, NAME_REF => "IFCLK", NAME_SIG => "DB") + port map (ref => ifclk_int, sig => db, gate => db_gate); + + adr_gate <= '1' when (slrd = '0' or slwr = '0') and slcs_int = '1' else '0'; + e_setup_adr: entity work.assert_setuphold_vec + generic map (LEVEL => '1', T_SETUP => T_SFA, T_HOLD => T_FAH, NAME_REF => "IFCLK", NAME_SIG => "FIFOADR") + port map (ref => ifclk_int, sig => fifoadr, gate => adr_gate); + +end behavioral; -- 2.43.0