URL
https://opencores.org/ocsvn/axi4_tlm_bfm/axi4_tlm_bfm/trunk
Subversion Repositories axi4_tlm_bfm
Compare Revisions
- This comparison shows the changes necessary to convert path
/axi4_tlm_bfm/trunk/rtl
- from Rev 10 to Rev 11
- ↔ Reverse comparison
Rev 10 → Rev 11
/axi4-stream-bfm-master.vhdl
56,7 → 56,7
-- axiSlave_out:buffer tAxi4Transactor_s2m; |
|
symbolsPerTransfer:in t_cnt; |
outstandingTransactions:out t_cnt |
outstandingTransactions:buffer t_cnt |
|
/* Debug ports. */ |
-- dbg_cnt:out unsigned(9 downto 0); |
/user.vhdl
36,6 → 36,10
*/ |
library ieee; use ieee.std_logic_1164.all, ieee.numeric_std.all; use ieee.math_real.all; |
library tauhop; use tauhop.transactor.all, tauhop.axiTransactor.all; --TODO just use axiTransactor here as transactor should already be wrapped up. |
|
/* TODO remove once generic packages are supported. */ |
--library tauhop; use tauhop.tlm.all, tauhop.axiTLM.all; |
|
/* synthesis translate_off */ |
library osvvm; use osvvm.RandomPkg.all; use osvvm.CoveragePkg.all; |
/* synthesis translate_on */ |
42,7 → 46,7
|
entity user is port( |
/* Comment-out for simulation. */ |
-- clk,reset:in std_ulogic; |
-- clk,nReset:in std_ulogic; |
|
/* AXI Master interface */ |
-- axiMaster_in:in t_axi4StreamTransactor_s2m; |
66,14 → 70,13
|
type txStates is (idle,transmitting); |
signal txFSM,i_txFSM:txStates; |
--signal response,i_response:boolean; |
|
/* Tester signals. */ |
/* synthesis translate_off */ |
signal clk,reset:std_ulogic:='0'; |
signal axiMaster_in:t_axi4StreamTransactor_s2m; |
signal clk,nReset:std_ulogic:='0'; |
/* synthesis translate_on */ |
|
signal axiMaster_in:t_axi4StreamTransactor_s2m; |
signal irq_write:std_ulogic; -- clock gating. |
|
begin |
80,7 → 83,7
/* Bus functional models. */ |
axiMaster: entity work.axiBfmMaster(rtl) |
port map( |
aclk=>irq_write, n_areset=>not reset, |
aclk=>irq_write, n_areset=>nReset, |
|
readRequest=>readRequest, writeRequest=>writeRequest, |
readResponse=>readResponse, writeResponse=>writeResponse, |
92,15 → 95,15
); |
|
/* Interrupt-request generator. */ |
irq_write<=clk when not reset else '0'; |
irq_write<=clk when nReset else '0'; |
|
/* Simulation Tester. */ |
/* synthesis translate_off */ |
clk<=not clk after 10 ps; |
process is begin |
reset<='0'; wait for 1 ps; |
reset<='1'; wait for 500 ps; |
reset<='0'; |
nReset<='1'; wait for 1 ps; |
nReset<='0'; wait for 500 ps; |
nReset<='1'; |
wait; |
end process; |
/* synthesis translate_on */ |
111,6 → 114,7
/* Stimuli sequencer. TODO move to tester/stimuli. |
This emulates the AXI4-Stream Slave. |
*/ |
/* Simulation-only stimuli sequencer. */ |
/* synthesis translate_off */ |
process is begin |
/* Fast read. */ |
156,8 → 160,11
end process; |
/* synthesis translate_on */ |
|
/* Synthesisable stimuli sequencer. */ |
|
|
/* Data transmitter. */ |
sequencer: process(reset,irq_write) is |
sequencer: process(nReset,irq_write) is |
/* Local procedures to map BFM signals with the package procedure. */ |
procedure read(address:in t_addr) is begin |
read(readRequest,address); |
169,23 → 176,36
|
variable isPktError:boolean; |
|
/* Tester variables. */ |
/* Synthesis-only randomisation. */ |
|
/* Simulation-only randomisation. */ |
/* synthesis translate_off */ |
variable rv0:RandomPType; |
/* synthesis translate_on */ |
|
begin |
if reset then |
if not nReset then |
/*simulation only. */ |
/* synthesis translate_off */ |
rv0.InitSeed(rv0'instance_name); |
/* synthesis translate_on */ |
|
txFSM<=idle; |
elsif falling_edge(irq_write) then |
case txFSM is |
when idle=> |
if outstandingTransactions>0 then |
/* synthesis translate_off */ |
write(rv0.RandSigned(axiMaster_out.tData'length)); |
/* synthesis translate_on */ |
txFSM<=transmitting; |
end if; |
when transmitting=> |
if writeResponse.trigger then |
/* synthesis translate_off */ |
write(rv0.RandSigned(axiMaster_out.tData'length)); |
/* synthesis translate_on */ |
end if; |
|
if axiMaster_out.tLast then |
197,17 → 217,23
end process sequencer; |
|
/* Reset symbolsPerTransfer to new value (prepare for new transfer) after current transfer has been completed. */ |
process(reset,irq_write) is |
process(nReset,irq_write) is |
/* synthesis translate_off */ |
variable rv0:RandomPType; |
/* synthesis translate_on */ |
begin |
if reset then |
if not nReset then |
/* synthesis translate_off */ |
rv0.InitSeed(rv0'instance_name); |
symbolsPerTransfer<=120x"0" & rv0.RandUnsigned(8); |
report "symbols per transfer = 0x" & ieee.numeric_std.to_hstring(rv0.RandUnsigned(axiMaster_out.tData'length)); |
/* synthesis translate_on */ |
elsif rising_edge(irq_write) then |
if axiMaster_out.tLast then |
/* synthesis translate_off */ |
symbolsPerTransfer<=120x"0" & rv0.RandUnsigned(8); |
report "symbols per transfer = 0x" & ieee.numeric_std.to_hstring(rv0.RandUnsigned(axiMaster_out.tData'length)); |
/* synthesis translate_on */ |
end if; |
end if; |
end process; |
/quartus-synthesis/axi4-stream-bfm-master.vhdl
38,16 → 38,13
library ieee; use ieee.std_logic_1164.all, ieee.numeric_std.all; |
--library tauhop; use tauhop.transactor.all, tauhop.axiTransactor.all; |
|
/* TODO remove once generic packages are supported. */ |
--/* TODO remove once generic packages are supported. */ |
library tauhop; use tauhop.tlm.all, tauhop.axiTLM.all; |
|
entity axiBfmMaster is --generic(constant maxTransactions:positive); |
port(aclk,n_areset:in std_ulogic; |
/* User trigger. */ |
trigger:in boolean; |
|
/* BFM signalling. */ |
readRequest,writeRequest:in t_bfm:=((others=>'X'),(others=>'X'),false); -- this is tauhop.transactor.t_bfm. |
readRequest,writeRequest:in t_bfm:=((others=>'X'),(others=>'X'),false); -- this is tauhop.transactor.t_bfm. |
readResponse,writeResponse:buffer t_bfm; -- use buffer until synthesis tools support reading from out ports. |
|
/* AXI Master interface */ |
72,24 → 69,21
/* Finite-state Machines. */ |
signal axiTxState,next_axiTxState:axiBfmStatesTx:=idle; |
|
/* General pipelines. */ |
signal i_axiMaster_out:t_axi4StreamTransactor_m2s; |
|
/* BFM signalling. */ |
signal i_readRequest:t_bfm:=((others=>'0'),(others=>'0'),false); |
signal i_writeRequest:t_bfm:=((others=>'0'),(others=>'0'),false); |
|
signal response,i_response:boolean; |
signal i_readResponse,i_writeResponse:t_bfm; |
|
begin |
/* Transaction counter. */ |
process(n_areset,symbolsPerTransfer,aclk) is begin |
if not n_areset then outstandingTransactions<=symbolsPerTransfer; |
elsif rising_edge(aclk) then |
if outstandingTransactions>0 then outstandingTransactions<=outstandingTransactions-1; |
else |
elsif falling_edge(aclk) then |
if outstandingTransactions<1 then |
outstandingTransactions<=symbolsPerTransfer; |
report "No more pending transactions." severity note; |
elsif axiMaster_in.tReady then outstandingTransactions<=outstandingTransactions-1; |
end if; |
end if; |
end process; |
98,14 → 92,15
axi_bfmTx_ns: process(all) is begin |
axiTxState<=next_axiTxState; |
|
if not n_areset then axiTxState<=idle; |
elsif writeRequest.trigger xor i_writeRequest.trigger then axiTxState<=payload; |
end if; |
if not n_areset then axiTxState<=idle; end if; |
|
case next_axiTxState is |
when idle=>null; |
when idle=> |
if writeRequest.trigger xor i_writeRequest.trigger then axiTxState<=payload; end if; |
when payload=> |
if outstandingTransactions<1 then axiTxState<=idle; end if; |
if outstandingTransactions<1 then axiTxState<=endOfTx; end if; |
when endOfTx=> |
axiTxState<=idle; |
when others=>axiTxState<=idle; |
end case; |
end process axi_bfmTx_ns; |
112,15 → 107,30
|
/* output logic for AXI4-Stream Master Tx BFM. */ |
axi_bfmTx_op: process(all) is begin |
axiMaster_out<=i_axiMaster_out; |
i_writeResponse<=writeResponse; |
|
axiMaster_out.tValid<=false; |
axiMaster_out.tLast<=false; |
axiMaster_out.tData<=(others=>'Z'); |
i_writeResponse.trigger<=false; |
|
case next_axiTxState is |
when idle=> |
if writeRequest.trigger xor i_writeRequest.trigger then |
axiMaster_out.tData<=writeRequest.message; |
axiMaster_out.tValid<=true; |
end if; |
when payload=> |
axiMaster_out.tValid<=true; |
axiMaster_out.tData<=writeRequest.message; |
|
if axiMaster_in.tReady then |
axiMaster_out.tData<=writeRequest.message; |
i_writeResponse.trigger<=true; |
end if; |
when others=> axiMaster_out.tValid<=false; axiMaster_out.tData<=(others=>'Z'); --TODO: set 'Z' to '0' for synthesis. |
|
/* TODO change to a flag at user.vhdl. Move outstandingTransactions to user.vhdl. */ |
if outstandingTransactions<1 then axiMaster_out.tLast<=true; end if; |
when others=> null; |
end case; |
end process axi_bfmTx_op; |
|
128,12 → 138,15
/* state registers and pipelines for AXI4-Stream Tx BFM. */ |
process(n_areset,aclk) is begin |
if not n_areset then next_axiTxState<=idle; |
elsif rising_edge(aclk) then |
elsif falling_edge(aclk) then |
next_axiTxState<=axiTxState; |
i_axiMaster_out<=axiMaster_out; |
i_writeRequest<=writeRequest; |
end if; |
end process; |
|
-- dbg_axiTxFsm<=axiTxState; |
process(aclk) is begin |
if rising_edge(aclk) then |
writeResponse<=i_writeResponse; |
end if; |
end process; |
end architecture rtl; |
/quartus-synthesis/user.vhdl
66,45 → 66,34
signal outstandingTransactions:t_cnt; |
|
/* BFM signalling. */ |
signal readRequest,next_readRequest:t_bfm:=((others=>'0'),(others=>'0'),false); |
signal writeRequest,next_writeRequest:t_bfm:=((others=>'0'),(others=>'0'),false); |
signal readResponse,next_readResponse:t_bfm; |
signal writeResponse,next_writeResponse:t_bfm; |
signal readRequest:t_bfm:=((others=>'0'),(others=>'0'),false); |
signal writeRequest:t_bfm:=((others=>'0'),(others=>'0'),false); |
signal readResponse:t_bfm; |
signal writeResponse:t_bfm; |
|
type txStates is (idle,transmitting); |
signal txFSM,i_txFSM:txStates; |
|
/* Tester signals. */ |
/* synthesis translate_off */ |
signal clk,nReset:std_ulogic:='0'; |
/* synthesis translate_on */ |
signal trigger:boolean; |
--signal trigger:boolean; |
signal anlysr_dataIn:std_logic_vector(127 downto 0); |
signal anlysr_trigger:std_ulogic; |
|
/* Signal preservations for SignalTap II probing. */ |
attribute keep:boolean; |
attribute keep of trigger:signal is true; |
--attribute keep:boolean; |
--attribute keep of trigger:signal is true; |
|
signal axiMaster_in:t_axi4StreamTransactor_s2m; |
signal irq_write:std_ulogic; -- clock gating. |
|
begin |
/* pipelines. */ |
process(clk) is begin |
if rising_edge(clk) then |
next_readRequest<=readRequest; |
next_writeRequest<=writeRequest; |
next_readResponse<=readResponse; |
next_writeResponse<=writeResponse; |
end if; |
end process; |
|
|
/* Bus functional models. */ |
axiMaster: entity work.axiBfmMaster(rtl) |
-- generic map(maxTransactions=>maxSymbols) |
port map( |
aclk=>irq_write, n_areset=>nReset, |
trigger=>irq_write='1', |
|
readRequest=>readRequest, writeRequest=>writeRequest, |
readResponse=>readResponse, writeResponse=>writeResponse, |
180,9 → 169,59
|
|
|
/* Stimuli sequencer. */ |
/* Stimuli sequencer. TODO move to tester/stimuli. |
This emulates the AXI4-Stream Slave. |
*/ |
/* Simulation-only stimuli sequencer. */ |
/* synthesis translate_off */ |
process is begin |
/* Fast read. */ |
while not axiMaster_out.tLast loop |
/* Wait for tValid to assert. */ |
while not axiMaster_out.tValid loop |
wait until falling_edge(clk); |
end loop; |
|
axiMaster_in.tReady<=true; |
|
wait until falling_edge(clk); |
axiMaster_in.tReady<=false; |
end loop; |
|
wait until falling_edge(clk); |
|
/* Normal read. */ |
while not axiMaster_out.tLast loop |
/* Wait for tValid to assert. */ |
while not axiMaster_out.tValid loop |
wait until falling_edge(clk); |
end loop; |
|
wait until falling_edge(clk); |
axiMaster_in.tReady<=true; |
|
wait until falling_edge(clk); |
axiMaster_in.tReady<=false; |
end loop; |
|
for i in 0 to 10 loop |
wait until falling_edge(clk); |
end loop; |
|
/* One-shot read. */ |
axiMaster_in.tReady<=true; |
|
wait until falling_edge(clk); |
axiMaster_in.tReady<=false; |
|
wait; |
end process; |
/* synthesis translate_on */ |
|
/* Synthesisable stimuli sequencer. */ |
axiMaster_in.tReady<=true when axiMaster_out.tValid and falling_edge(clk); |
|
/* Data transmitter. */ |
sequencer: process(nReset,irq_write) is |
/* Local procedures to map BFM signals with the package procedure. */ |
procedure read(address:in t_addr) is begin |
197,46 → 236,68
|
/* Tester variables. */ |
/* Synthesis-only randomisation. */ |
variable seed0,seed1:positive:=1; |
--variable rand0:real; |
variable rand0:signed(63 downto 0); |
/* Simulation-only randomisation. */ |
/* synthesis translate_off */ |
variable rv0,rv1:RandomPType; |
variable rv0:RandomPType; |
/* synthesis translate_on */ |
|
begin |
if not nReset then |
/* synthesis only. */ |
seed0:=1; seed1:=1; |
--uniform(seed0,seed1,rand0); |
rand0:=(others=>'0'); |
|
--symbolsPerTransfer<=120x"0" & to_unsigned(integer(rand0 * 2.0**8),8); |
symbolsPerTransfer<=128x"8"; |
|
|
/* simulation only. */ |
/* synthesis translate_off */ |
rv0.InitSeed(rv0'instance_name); |
rv1.InitSeed(rv1'instance_name); |
/* synthesis translate_on */ |
|
txFSM<=idle; |
elsif falling_edge(irq_write) then |
case txFSM is |
when idle=> |
if outstandingTransactions>0 then |
/* synthesis translate_off */ |
write(rv0.RandSigned(axiMaster_out.tData'length)); |
/* synthesis translate_on */ |
write(rand0); |
|
txFSM<=transmitting; |
end if; |
when transmitting=> |
if writeResponse.trigger then |
/* synthesis translate_off */ |
write(rv0.RandSigned(axiMaster_out.tData'length)); |
/* synthesis translate_on */ |
write(rand0); |
rand0:=rand0+1; |
end if; |
|
if axiMaster_out.tLast then |
txFSM<=idle; |
end if; |
when others=>null; |
end case; |
end if; |
end process sequencer; |
|
/* Reset symbolsPerTransfer to new value (prepare for new transfer) after current transfer has been completed. */ |
process(nReset,irq_write) is |
/* synthesis translate_off */ |
variable rv0:RandomPType; |
/* synthesis translate_on */ |
begin |
if not nReset then |
/* synthesis translate_off */ |
rv0.InitSeed(rv0'instance_name); |
symbolsPerTransfer<=120x"0" & rv0.RandUnsigned(8); |
report "symbols per transfer = 0x" & ieee.numeric_std.to_hstring(rv0.RandUnsigned(axiMaster_out.tData'length)); |
/* synthesis translate_on */ |
elsif falling_edge(irq_write) then |
--write(64x"abcd1234"); |
if outstandingTransactions>0 then |
|
symbolsPerTransfer<=128x"8"; |
elsif rising_edge(irq_write) then |
if axiMaster_out.tLast then |
/* synthesis only. */ |
--uniform(seed0,seed1,rand0); |
--write(to_signed(integer(rand0 * 2.0**31),64)); |
write(rand0); |
rand0:=rand0+1; |
|
/* simulation only. */ |
/* synthesis translate_off */ |
write(rv1.RandUnsigned(axiMaster_out.tData'length)); |
/* synthesis translate_on */ |
else |
/* synthesis only. */ |
/* Testcase 1: number of symbols per transfer becomes 0 after first stream transfer. */ |
--symbolsPerTransfer<=(others=>'0'); |
|
244,16 → 305,15
--uniform(seed0,seed1,rand0); |
--symbolsPerTransfer<=120x"0" & to_unsigned(integer(rand0 * 2.0**8),8); --symbolsPerTransfer'length |
--report "symbols per transfer = " & ieee.numeric_std.to_hstring(to_unsigned(integer(rand0 * 2.0**8),8)); --axiMaster_out.tData'length)); |
symbolsPerTransfer<=128x"8"; |
|
|
/* Truncate symbolsPerTransfer to 8 bits, so that it uses a "small" value for simulation. */ |
/* simulation only. */ |
|
/* synthesis translate_off */ |
symbolsPerTransfer<=120x"0" & rv0.RandSigned(64); |
symbolsPerTransfer<=120x"0" & rv0.RandUnsigned(8); |
report "symbols per transfer = 0x" & ieee.numeric_std.to_hstring(rv0.RandUnsigned(axiMaster_out.tData'length)); |
/* synthesis translate_on */ |
|
symbolsPerTransfer<=128x"8"; |
end if; |
end if; |
end process sequencer; |
end process; |
end architecture rtl; |