diff --git a/documentation/CAN_testdata/data_read.tdf b/documentation/CAN_testdata/data_read.tdf new file mode 100644 index 0000000..1df864c --- /dev/null +++ b/documentation/CAN_testdata/data_read.tdf @@ -0,0 +1,4 @@ +20 +21 +22 +23 \ No newline at end of file diff --git a/documentation/CAN_testdata/data_send.tdf b/documentation/CAN_testdata/data_send.tdf new file mode 100644 index 0000000..8768f7e --- /dev/null +++ b/documentation/CAN_testdata/data_send.tdf @@ -0,0 +1,5 @@ +10 10101010 +11 11000010 +12 10101010 +13 00001111 +1 00000001 \ No newline at end of file diff --git a/documentation/CAN_testdata/default_setup.tdf b/documentation/CAN_testdata/default_setup.tdf new file mode 100644 index 0000000..7feff40 --- /dev/null +++ b/documentation/CAN_testdata/default_setup.tdf @@ -0,0 +1,6 @@ +4 00000000 +5 11111111 +6 10000000 +7 01001000 +8 00000010 +0 11111110 \ No newline at end of file diff --git a/documentation/guides.tex b/documentation/guides.tex index 98c2175..0f449ae 100644 --- a/documentation/guides.tex +++ b/documentation/guides.tex @@ -32,3 +32,133 @@ lookuptable_ptr: ld32 rZ,rX // load from pointer with offset //... \end{asm} + +\clearpage +\section{How to test a design using the CAN test package} +%Designs that use a CAN controller as a peripheral device, are often complex and therefor hard to debug. +%This is especially true, if providing valid input data via the CAN bus is necessary in order to verify correct behavior. +The platform includes a foreign CAN controller IP component. +To ease integration and testing, a test package is provided with the platform source code. +With its help, input data and behavior of a CAN network can be modeled more easily. + +The test package is located in \verb=can_tp.vhd= and a application demonstration is given as a testbench in \verb=can_demo_tb.vhd= in the testbench directory. + +In this guide, two approaches on verifying a design are presented. + +%In those situations, the need for tools occurs, that reliably provide input data and model the behavior of a CAN network, +%connected to the designs CAN interface. +%The CAN test package is a collection of VHDL functions and procedures that implement such tools. +%And this guide will explain their proper use. + +%There are two basic approaches, recommended by this guide, on how to do so. +%They are described in the two following parts. +%The third part gives some hints on how to use these methods in a test bench. + + + +\subsection{Simulating a CAN transmission} +The first approach focuses on generating CAN transmissions, that can be used as input for the design under test. This is achieved by unsing the procedure \verb=simulate_can_transmission= (Listing ~\ref{lst:interface_01}), which is configurable to any data and timing, your CAN interface uses. The user has not to worry about bit stuffing, crc and error detection. + +The \verb=id= and \verb=data= parameters are bit vectors (\verb=std_logic_vector=) that specify the CAN ID and DATA bits of the message. + +The actual length of the data part is configurable by the \verb=datasize= parameter. It is an integer specifying the amount of Bytes of the \verb=data= parameter, that will be included in the CAN transmission. The rest of \verb=data= will simply be ignored. + +The timing is controlled by the \verb=t_bit= parameter, which is of VDHL type time. +It stands for the correct overall length of one CAN symbol (this value has to be calculated from the timing configuration of the tested CAN controller). + +The \verb=rx= and \verb=tx= signals have to be connected to a simulated CAN bus. See Section ~\ref{subsec:int_tb} for more information. The signal \verb=tx= is the actual output of the procedure. + +The \verb=test_result= parameter is a diagnostic output of an enumeration type that shows whether the transmission was successful, a CAN error occurs, the arbitration is lost or whether the tested CAN controller is not acknowledging the transmission. + +\begin{vhdl}[Interface]{lst:interface_01} +procedure simulate_can_transmission( + constant id : in std_logic_vector(10 downto 0); + constant data : in std_logic_vector (0 to 63); + constant datasize : in integer; + constant t_bit : in time; + signal rx : in std_logic; + signal tx : inout std_logic; + signal test_result : out rx_check_result) +\end{vhdl} + +\subsection{Creating a test network} +While the first approach is limited to transmitting can messages, this one aims at providing one or more fully functioning can nodes in a test network. Each node is implemented by an instantiation of \verb=can_vhdl_top=, but instead of steering them with a LT16soc design, functions of the can test package will do the job: + +If a certain register in a CAN node should be written to, the procedure \verb=can_wb_write_reg= (Listing ~\ref{lst:interface_02}) comes in handy. Its parameter signals \verb=wbs_in= and \verb=wbs_out= must be connected to the CAN controller's Wishbone interface. The parameter \verb=addr= is an integer specifying the target register of the write and the parameter data is a bit vector containing the data. And finally a clock signal \verb=clk= is needed as input, in order to write to the CAN controller. (This must be the same clock used for operating the CAN node.) + +\begin{vhdl}[Interface]{lst:interface_02} +procedure can_wb_write_reg( + signal wbs_in : out wb_slv_in_type; + signal wbs_out : in wb_slv_out_type; + constant addr : integer; + constant data : in std_logic_vector(7 downto 0); + signal clk : in std_logic) +\end{vhdl} + +For extracting certain register contents, the procedure \verb=can_wb_read_reg= (Listing ~\ref{lst:interface_03}) is provided. It is used with the same parameters like \verb=can_wb_write_reg=, except a data input bit vector. Instead, a data output signal is provided, to access the read register contents. + +\begin{vhdl}[Interface]{lst:interface_03} +procedure can_wb_read_reg( + signal wbs_in : out wb_slv_in_type; + signal wbs_out : in wb_slv_out_type; + constant addr : integer; + signal data : out std_logic_vector(7 downto 0); + signal clk : in std_logic) +\end{vhdl} + +If successive writes are needed, the procedure \verb=write_regs_from_file= (Listing ~\ref{lst:interface_04}) is a convenient way to do this. The first Parameter is a path to a text file. Each line in the file stands for a CAN register, that should be written, and consits of a integer for the desired target register number and eight binary digits ('0' or '1') for the data. Both numbers are separated by one SPACE. See ~\ref{lst:default_setup} for an example. + +\begin{vhdl}[Interface]{lst:interface_04} + procedure write_regs_from_file( + constant filename : in string; + signal wbs_in : out wb_slv_in_type; + signal wbs_out : in wb_slv_out_type; + signal clk : in std_logic) +\end{vhdl} + +Successive reading can be done in a similar way with \verb=read_regs_with_fileaddr= (Listing ~\ref{lst:interface_05}). Here, the data part in each line of the file is ignored. If the registers written to should be read, the same file can be used. The parameter \verb=out_filename= determines an additional file, that is used to store the read register contents. + +\begin{vhdl}[Interface]{lst:interface_05} +procedure read_regs_with_fileaddr( + constant filename : in string; + constant out_filename : in string; + signal wbs_in : out wb_slv_in_type; + signal wbs_out : in wb_slv_out_type; + signal clk : in std_logic) +\end{vhdl} + + +\subsection{Integrating the approaches in a test bench} +\label{subsec:int_tb} +In order to use the two presented approaches in a test bench, some details have to be considered: + +\begin{itemize} +\item Connecting CAN nodes or transmitting custom messages requires the simulation of a CAN network. A VHDL design that does exactly this is provided: \verb=phys_can_sim= (Listing ~\ref{lst:interface_06}). The individual tx and rx signals of the connected can nodes are merged into two vectors. Thier size is determind by the generic parameter \verb=peer_num=, which should be equal to the number of clients connected to the CAN network. +\item When using the \verb=simulate_can_transmission= procedure, the \verb=tx= signal is only handled while the procedure is working. For all other times the signal has to be assigned manually. +\item When simulating the test bench with ISim, the relative file path in \verb=write_regs_from_file= and \verb=read_regs_with_fileaddr= has its root in the project folder. An example file, containing initialization data for a can node is shown in Listing ~\ref{lst:default_setup}. +\item When instantiating \verb=can_vhdl_top= (a CAN node without a lt16soc), do not forget to initialize its \verb=wbs_in= port signal porperly. This can be done by assigning the constant \verb=wbs_in_default= from the CAN test package to it. +\item A demo test bench using all the mechanics described in the two approaches is provided: \verb=can_demo_tb=. +\end{itemize} + + +\begin{vhdl}[Interface]{lst:interface_06} +entity phys_can_sim + generic( + peer_num : integer ); + port( + rst : in std_logic; + rx_vector : out std_logic_vector(peer_num - 1 downto 0); + tx_vector : in std_logic_vector(peer_num - 1 downto 0) ); +end entity phys_can_sim; +\end{vhdl} + + + +\begin{vhdl}[default\_setup.tdf]{lst:default_setup} +4 00000000 +5 11111111 +6 10000000 +7 01001000 +8 00000010 +0 11111110 +\end{vhdl} diff --git a/soc/lib/can_tp.vhd b/soc/lib/can_tp.vhd index 8ffe6d3..71e64bc 100644 --- a/soc/lib/can_tp.vhd +++ b/soc/lib/can_tp.vhd @@ -8,7 +8,18 @@ use ieee.std_logic_textio.all; package can_tp is type rx_check_result is (success, can_error, arbitration_lost, no_ack); - + + constant wbs_in_default : wb_slv_in_type := ( + (others=>'-'), -- adr + (others=>'-'), -- dat + '-', -- we + (others => '-'), -- sel + '0', -- stb + '0', -- cyc + "000", -- cti + "00" -- bte + ); + procedure can_wb_write_reg( signal wbs_in : out wb_slv_in_type; signal wbs_out : in wb_slv_out_type; @@ -22,14 +33,28 @@ package can_tp is constant addr : in integer; signal clk : in std_logic); + procedure can_wb_read_reg( + signal wbs_in : out wb_slv_in_type; + signal wbs_out : in wb_slv_out_type; + constant addr : in integer; + signal data : out std_logic_vector(7 downto 0); + signal clk : in std_logic); + procedure write_regs_from_file( constant filename : in string; signal wbs_in : out wb_slv_in_type; signal wbs_out : in wb_slv_out_type; signal clk : in std_logic); + +-- procedure read_regs_with_fileaddr( +-- constant filename : in string; +-- signal wbs_in : out wb_slv_in_type; +-- signal wbs_out : in wb_slv_out_type; +-- signal clk : in std_logic); procedure read_regs_with_fileaddr( constant filename : in string; + constant out_filename : in string; signal wbs_in : out wb_slv_in_type; signal wbs_out : in wb_slv_out_type; signal clk : in std_logic); @@ -46,6 +71,11 @@ package can_tp is constant data : std_logic_vector(7 downto 0) ) return std_logic_vector; + function canwb2data( + constant data_in : std_logic_vector(63 downto 0); + constant sel : std_logic_vector(3 downto 0) + ) return std_logic_vector; + function can_crc( constant data: in std_logic_vector(0 to 63); constant datasize: in integer)return std_logic_vector; @@ -119,7 +149,23 @@ package body can_tp is return wbcan_data; end data2canwb; - --does a asynchronous wb-single-write-handshake and writes to an register of the can controller + function canwb2data( + constant data_in : std_logic_vector(31 downto 0); + constant sel : std_logic_vector(3 downto 0) + ) return std_logic_vector is + variable data_out : std_logic_vector(7 downto 0); + begin + case sel is + when "1000" => data_out := data_in (31 downto 24); + when "0100" => data_out := data_in(23 downto 16); + when "0010" => data_out := data_in(15 downto 8); + when "0001" => data_out := data_in(7 downto 0); + when others => data_out := "0000"; -- should not occour + end case; + return data_out; + end canwb2data; + + --does a synchronous wb-single-write-handshake with waitstates and writes to an register of the can controller procedure can_wb_write_reg( signal wbs_in : out wb_slv_in_type; signal wbs_out : in wb_slv_out_type; @@ -169,6 +215,18 @@ package body can_tp is wbs_in.dat <= (others=>'-'); wbs_in.adr <= (others=>'-'); + end can_wb_read_reg; + + + procedure can_wb_read_reg( + signal wbs_in : out wb_slv_in_type; + signal wbs_out : in wb_slv_out_type; + constant addr : integer; + signal data : out std_logic_vector(7 downto 0); + signal clk : in std_logic) is + begin + can_wb_read_reg(wbs_in, wbs_out, addr, clk); + data <= canwb2data(wbs_out.dat, canint2sel(addr)); end can_wb_read_reg; @@ -190,25 +248,57 @@ package body can_tp is can_wb_write_reg(wbs_in, wbs_out, addr, data, clk); wait for 50 ns; end loop; + file_close(sourcefile); end procedure write_regs_from_file; +-- procedure read_regs_with_fileaddr( +-- constant filename : in string; +-- signal wbs_in : out wb_slv_in_type; +-- signal wbs_out : in wb_slv_out_type; +-- signal clk : in std_logic) is +-- +-- file sourcefile : text open read_mode is filename; +-- variable input_line : line; +-- variable output_line : line; +-- variable addr : integer; +-- begin +-- while not endfile(sourcefile) loop +-- readline(sourcefile, input_line); --read line +-- read(input_line, addr); --read addr of register +-- can_wb_read_reg(wbs_in, wbs_out, addr, clk); +-- wait for 50 ns; +-- end loop; +-- file_close(sourcefile); +-- end procedure read_regs_with_fileaddr; + + procedure read_regs_with_fileaddr( constant filename : in string; + constant out_filename : in string; signal wbs_in : out wb_slv_in_type; signal wbs_out : in wb_slv_out_type; signal clk : in std_logic) is file sourcefile : text open read_mode is filename; + file targetfile : text open write_mode is out_filename; variable input_line : line; + variable output_line : line; variable addr : integer; begin while not endfile(sourcefile) loop readline(sourcefile, input_line); --read line read(input_line, addr); --read addr of register can_wb_read_reg(wbs_in, wbs_out, addr, clk); + --wait for 1 ns; + write(output_line,addr); + write(output_line, ' ' ); + write(output_line,canwb2data(wbs_out.dat, canint2sel(addr))); + writeline(targetfile,output_line); wait for 50 ns; end loop; + file_close(sourcefile); + file_close(targetfile); end procedure read_regs_with_fileaddr; function can_crc( diff --git a/soc/lib/wb_tp.vhd b/soc/lib/wb_tp.vhd index 4b6fcd3..d07a2f4 100644 --- a/soc/lib/wb_tp.vhd +++ b/soc/lib/wb_tp.vhd @@ -1086,8 +1086,8 @@ package body wb_tp is msto.dat <= enc_wb_dat(adr(1 downto 0),size,writedata); wait until rising_edge(clk); - wait until slvo.ack = '1' for 1 ps; - assert slvo.ack = '1' report "Slave did not ACK the write properly"; + wait until slvo.ack = '1' for 100 ns; + assert slvo.ack = '1' report "Slave did not ACK the write properly within 10 wait states"; wait until rising_edge(clk); @@ -1180,8 +1180,8 @@ package body wb_tp is msto.adr <= adr; wait until rising_edge(clk); - wait until slvo.ack='1' for 1 ps; - assert slvo.ack='1' report "Slave did not ACK the read properly"; + wait until slvo.ack='1' for 100 ns; + assert slvo.ack='1' report "Slave did not ACK the read properly within 10 wait states"; if slvo.ack='1' then readdata <= dec_wb_dat(sel,slvo.dat); else diff --git a/soc/testbench/can_demo_tb.vhd b/soc/testbench/can_demo_tb.vhd new file mode 100644 index 0000000..a6df930 --- /dev/null +++ b/soc/testbench/can_demo_tb.vhd @@ -0,0 +1,195 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.wishbone.all; +use work.can_tp.all; +use work.config.all; + +entity can_demo_tb is +end entity can_demo_tb; + +architecture RTL of can_demo_tb is + + + component can_vhdl_top is + generic( + memaddr : generic_addr_type; + addrmask : generic_mask_type + ); + port( + clk : in std_logic; + rstn : in std_logic; + wbs_i : in wb_slv_in_type; + wbs_o : out wb_slv_out_type; + rx_i : in std_logic; + tx_o : out std_logic; + irq_on : out std_logic + ); + end component can_vhdl_top; + + + component phys_can_sim + generic( + peer_num : integer ); + port( + rst : in std_logic; + rx_vector : out std_logic_vector(peer_num - 1 downto 0); + tx_vector : in std_logic_vector(peer_num - 1 downto 0) ); + end component phys_can_sim; + + + -- management signal + signal clk : std_logic := '0'; + signal rst : std_logic := '1'; + signal test_result: rx_check_result; + --signal tx_frame: std_logic_vector(0 to 108); + + -- signals to/from controller 1 + signal wbs_i1 : wb_slv_in_type := wbs_in_default; + signal wbs_o1 : wb_slv_out_type; + signal irq_on1 : std_logic; + signal data_out : std_logic_vector(7 downto 0) := (others => '0'); + + -- signals to/from controller 2 + signal wbs_i2 : wb_slv_in_type:= wbs_in_default; + signal wbs_o2 : wb_slv_out_type; + signal irq_on2 : std_logic; + + --signals can interconnect + constant peer_num_inst : integer := 3; + signal rx_vector : std_logic_vector(peer_num_inst - 1 downto 0); + signal tx_vector : std_logic_vector(peer_num_inst - 1 downto 0); + +begin + + + can_inst_1 : component can_vhdl_top + generic map( + memaddr=>CFG_BADR_MEM, + addrmask=>CFG_MADR_FULL + ) + port map( + clk => clk, + rstn => rst, + wbs_i => wbs_i1, + wbs_o => wbs_o1, + rx_i => rx_vector(0), + tx_o => tx_vector(0), + irq_on => irq_on1); + + can_inst_2 : component can_vhdl_top + generic map( + memaddr=>CFG_BADR_MEM, + addrmask=>CFG_MADR_FULL + ) + port map( + clk => clk, + rstn => rst, + wbs_i => wbs_i2, + wbs_o => wbs_o2, + rx_i => rx_vector(1), + tx_o => tx_vector(1), + irq_on => irq_on2); + + can_interconnect : component phys_can_sim + generic map( peer_num => peer_num_inst) + port map( rst => rst, + rx_vector => rx_vector, + tx_vector => tx_vector); + + -- stimuli + stimuli: process is + begin + report "begin stimuli" severity warning; + --this tx line is used manually + tx_vector(2) <= '1'; + + wait for 40 ns; + rst <= '0'; + + + --setup both can nodes + write_regs_from_file( "./testdata/default_setup.tdf", wbs_i1, wbs_o1, clk); + --wait for 1000 ns; + write_regs_from_file( "./testdata/default_setup.tdf", wbs_i2, wbs_o2, clk); + + wait for 1000 ns; + --setup and execute a 2 byte transmission in controller 1 + write_regs_from_file( "./testdata/data_send.tdf", wbs_i1, wbs_o1, clk); + tx_vector(2) <= tx_vector(1); + + --manual ack by copying controler 2's ack + wait on tx_vector(1); + tx_vector(2) <= '0'; + wait for 300 ns; + tx_vector(2) <= '1'; + + wait on irq_on2; + + --read status register of controller 1 + can_wb_read_reg(wbs_i1, wbs_o1, 2, data_out ,clk); + --read from controller 2's read buffer + --read_regs_with_fileaddr("./testdata/data_read.tdf", wbs_i2, wbs_o2, clk); + read_regs_with_fileaddr("./testdata/data_read.tdf", "./results/read_data0.tdf", wbs_i2, wbs_o2, clk); + + wait for 1200 ns; + --release receive buffer of controller 2 + can_wb_write_reg(wbs_i2, wbs_o2, 1, "00000100", clk); + + wait for 1200 ns; + + --manually transmit a 2 byte message on tx line 2 (tx_vector(2)) + simulate_can_transmission("11100010111", x"770F000000000000", 2, 300 ns, rx_vector(2), tx_vector(2), test_result); + tx_vector(2) <= '1'; + + wait on irq_on2; + + --read from both receive buffers + read_regs_with_fileaddr("./testdata/data_read.tdf", "./results/read_data1.tdf", wbs_i1, wbs_o1, clk); + read_regs_with_fileaddr("./testdata/data_read.tdf", "./results/read_data2.tdf", wbs_i2, wbs_o2, clk); + wait for 2400 ns; + --release both receive buffers + can_wb_write_reg(wbs_i1, wbs_o1, 1, "00000100", clk); + can_wb_write_reg(wbs_i2, wbs_o2, 1, "00000100", clk); + + wait for 1200 ns; + report "end stimuli" severity failure; + wait; + + end process stimuli; + + + -- clock generation + clock : process is + begin + clk <= not clk; + wait for 10 ns / 2; + end process clock; + +-- input files used in this testbench: +-- +-- default_setup.tdf: +-- 4 00000000 +-- 5 11111111 +-- 6 10000000 +-- 7 01001000 +-- 8 00000010 +-- 0 11111110 +-- +-- data_send.tdf: +-- 10 10101010 +-- 11 11000010 +-- 12 10101010 +-- 13 00001111 +-- 1 00000001 +-- +-- data_read.tdf: +-- 20 +-- 21 +-- 22 +-- 23 + +end architecture RTL; diff --git a/soc/testbench/can_tx_sim_tb.vhd b/soc/testbench/can_tx_sim_tb.vhd deleted file mode 100644 index 18ba811..0000000 --- a/soc/testbench/can_tx_sim_tb.vhd +++ /dev/null @@ -1,128 +0,0 @@ - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use work.wishbone.all; -use work.can_tp.all; - -entity can_tx_sim_tb is -end entity can_tx_sim_tb; - -architecture RTL of can_tx_sim_tb is - - - component can_vhdl_top is - generic( - memaddr : generic_addr_type; - addrmask : generic_mask_type; - ); - port( - clk : in std_logic; - rstn : in std_logic; - wbs_i : in wb_slv_in_type; - wbs_o : out wb_slv_out_type; - rx_i : in std_logic; - tx_o : out std_logic; - irq_on : out std_logic - ); - end component can_vhdl_top; - - - component phys_can_sim - generic( - peer_num : integer ); - port( - rst : in std_logic; - rx_vector : out std_logic_vector(peer_num - 1 downto 0); - tx_vector : in std_logic_vector(peer_num - 1 downto 0) ); - end component phys_can_sim; - - - -- management signal - signal clk : std_logic := '0'; - signal rst : std_logic := '1'; - signal test_result: rx_check_result; - signal tx_frame: std_logic_vector(0 to 108); - - -- signals main controller - signal wbs_i : wb_slv_in_type; - signal wbs_o : wb_slv_out_type; - signal irq_on : std_logic; - - - --signals can interconnect - constant peer_num_inst : integer := 2; - signal rx_vector : std_logic_vector(peer_num_inst - 1 downto 0); - signal tx_vector : std_logic_vector(peer_num_inst - 1 downto 0); - -begin - - - can_inst_main : component can_vhdl_top - generic map( - memaddr=>CFG_BADR_MEM, - addrmask=>CFG_MADR_FULL - ) - port map( - clk => clk, - rstn => rst, - wbs_i => wbs_i, - wbs_o => wbs_o, - rx_i => rx_vector(0), - tx_o => tx_vector(0), - irq_on => irq_on); - - can_interconnect : component phys_can_sim - generic map( peer_num => peer_num_inst) - port map( rst => rst, - rx_vector => rx_vector, - tx_vector => tx_vector); - - - - -- stimuli - stimuli: process is - --variable data : std_logic_vector (7 downto 0); - --variable addr : integer; - begin - wait for 10 ns; - rst <= '1'; - wait for 40 ns; - rst <= '0'; - - tx_vector(1) <= '1'; - write_regs_from_file( "./testdata/default_setup.tdf", wbs_i, wbs_o, clk); - wait for 8400 ns; - simulate_can_transmission("10101010111", x"770F0F0F00000000", 1, 300 ns, rx_vector(1), tx_vector(1), test_result); - wait for 2400 ns; - simulate_can_transmission("11100010111", x"770F0F0F00000000", 3, 300 ns, rx_vector(1), tx_vector(1), test_result); - wait for 8400 ns; - simulate_can_transmission("00000000011", x"770F0F0F00000000", 5, 300 ns, rx_vector(1), tx_vector(1), test_result); - wait for 8400 ns; - simulate_can_transmission("10111110011", x"770F0F0F00000000", 8, 300 ns, rx_vector(1), tx_vector(1), test_result); - tx_vector(1) <= '1'; - wait; - - report "end stimuli" severity warning; - - end process stimuli; - - sub_programm_test: process is - - begin - tx_frame <= buildframe("00000000000", x"770F0F0F00000000", 1); - wait; - end process; - - - - -- clock generation - clock : process is - begin - clk <= not clk; - wait for 10 ns / 2; - end process clock; - - - -end architecture RTL; diff --git a/soc/testbench/phys_can_sim.vhd b/soc/testbench/phys_can_sim.vhd new file mode 100644 index 0000000..877307d --- /dev/null +++ b/soc/testbench/phys_can_sim.vhd @@ -0,0 +1,47 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity phys_can_sim is + generic( + peer_num : integer --number of can participants connected to the bus + ); + port( + rst : in std_logic; + + rx_vector : out std_logic_vector(peer_num - 1 downto 0); --vector containing all rx_signals + tx_vector : in std_logic_vector(peer_num - 1 downto 0) --vector containing all tx_signals + ); +end entity; + +architecture behav of phys_can_sim is + + +begin + + + process(tx_vector, rst) + + variable value : std_logic := '1'; + variable i : integer; + + begin + if rst = '1' then + rx_vector <= (others => '1'); + else + value := '1'; + for i in 0 to peer_num - 1 loop + value := value and tx_vector(i); + end loop; + if value = '1' then + + rx_vector <= (others => '1'); + else + rx_vector <= (others => '0'); + end if; + end if; + end process; + + +end architecture; + +--TODO: physical transmission delay simulation if needed (in a later simulation stage) \ No newline at end of file diff --git a/warmup2.pdf b/warmup2.pdf index 8ebc7bc..cc3e682 100644 Binary files a/warmup2.pdf and b/warmup2.pdf differ