diff --git a/rtl/bplib/cmoda7/tb/tb_c7_sram_memctl.vbom b/rtl/bplib/cmoda7/tb/tb_c7_sram_memctl.vbom new file mode 100644 index 00000000..eec9fd76 --- /dev/null +++ b/rtl/bplib/cmoda7/tb/tb_c7_sram_memctl.vbom @@ -0,0 +1,11 @@ +# libs +../../../vlib/slvtypes.vhd +../cmoda7lib.vhd +../../../vlib/simlib/simlib.vhd +# components +../../../vlib/simlib/simclk.vbom +../../../vlib/simlib/simclkcnt.vbom +../../issi/is61wv5128bll.vbom +${uut := ../c7_sram_memctl.vbom} +# design +tb_c7_sram_memctl.vhd diff --git a/rtl/bplib/cmoda7/tb/tb_c7_sram_memctl.vhd b/rtl/bplib/cmoda7/tb/tb_c7_sram_memctl.vhd new file mode 100644 index 00000000..24b5e9dc --- /dev/null +++ b/rtl/bplib/cmoda7/tb/tb_c7_sram_memctl.vhd @@ -0,0 +1,334 @@ +-- $Id: tb_c7_sram_memctl.vhd 984 2018-01-02 20:56:27Z mueller $ +-- +-- Copyright 2017- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 3, or (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, but +-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-- for complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tb_c7_sram_memctl - sim +-- Description: Test bench for c7_sram_memctl +-- +-- Dependencies: vlib/simlib/simclk +-- vlib/simlib/simclkcnt +-- bplib/issi/is61wv5128bll +-- c7_sram_memctl [UUT] +-- +-- To test: c7_sram_memctl +-- +-- Verified (with tb_c7_sram_memctl_stim.dat): +-- Date Rev Code ghdl viv Target Comment +-- 2017-06-11 912 _ssim 0.34 2017.1 xx xx +-- +-- Target Devices: generic +-- Tool versions: viv 2017.1; ghdl 0.34 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2017-06-13 913 1.0 Initial version (derived from tb_s3_sram_memctl) +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; +use work.cmoda7lib.all; +use work.simlib.all; + +entity tb_c7_sram_memctl is +end tb_c7_sram_memctl; + +architecture sim of tb_c7_sram_memctl is + + signal CLK : slbit := '0'; + signal RESET : slbit := '0'; + signal REQ : slbit := '0'; + signal WE : slbit := '0'; + signal BUSY : slbit := '0'; + signal ACK_R : slbit := '0'; + signal ACK_W : slbit := '0'; + signal ACT_R : slbit := '0'; + signal ACT_W : slbit := '0'; + signal ADDR : slv17 := (others=>'0'); + signal BE : slv4 := (others=>'0'); + signal DI : slv32 := (others=>'0'); + signal DO : slv32 := (others=>'0'); + signal O_MEM_CE_N : slbit := '0'; + signal O_MEM_WE_N : slbit := '0'; + signal O_MEM_OE_N : slbit := '0'; + signal O_MEM_ADDR : slv19 := (others=>'0'); + signal IO_MEM_DATA : slv8 := (others=>'0'); + + signal R_MEMON : slbit := '0'; + signal N_CHK_DATA : slbit := '0'; + signal N_REF_DATA : slv32 := (others=>'0'); + signal N_REF_ADDR : slv17 := (others=>'0'); + signal R_CHK_DATA_AL : slbit := '0'; + signal R_REF_DATA_AL : slv32 := (others=>'0'); + signal R_REF_ADDR_AL : slv17 := (others=>'0'); + signal R_CHK_DATA_DL : slbit := '0'; + signal R_REF_DATA_DL : slv32 := (others=>'0'); + signal R_REF_ADDR_DL : slv17 := (others=>'0'); + + signal CLK_STOP : slbit := '0'; + signal CLK_CYCLE : integer := 0; + + constant clock_period : Delay_length := 20 ns; + constant clock_offset : Delay_length := 200 ns; + constant setup_time : Delay_length := 5 ns; + constant c2out_time : Delay_length := 10 ns; + +begin + + CLKGEN : simclk + generic map ( + PERIOD => clock_period, + OFFSET => clock_offset) + port map ( + CLK => CLK, + CLK_STOP => CLK_STOP + ); + + CLKCNT : simclkcnt port map (CLK => CLK, CLK_CYCLE => CLK_CYCLE); + + MEM : entity work.is61wv5128bll + port map ( + CE_N => O_MEM_CE_N, + OE_N => O_MEM_OE_N, + WE_N => O_MEM_WE_N, + ADDR => O_MEM_ADDR, + DATA => IO_MEM_DATA + ); + + UUT : c7_sram_memctl + port map ( + CLK => CLK, + RESET => RESET, + REQ => REQ, + WE => WE, + BUSY => BUSY, + ACK_R => ACK_R, + ACK_W => ACK_W, + ACT_R => ACT_R, + ACT_W => ACT_W, + ADDR => ADDR, + BE => BE, + DI => DI, + DO => DO, + O_MEM_CE_N => O_MEM_CE_N, + O_MEM_WE_N => O_MEM_WE_N, + O_MEM_OE_N => O_MEM_OE_N, + O_MEM_ADDR => O_MEM_ADDR, + IO_MEM_DATA => IO_MEM_DATA + ); + + proc_stim: process + file fstim : text open read_mode is "tb_c7_sram_memctl_stim"; + variable iline : line; + variable oline : line; + variable ok : boolean; + variable dname : string(1 to 6) := (others=>' '); + variable idelta : integer := 0; + variable iaddr : slv17 := (others=>'0'); + variable idata : slv32 := (others=>'0'); + variable ibe : slv4 := (others=>'0'); + variable ival : slbit := '0'; + variable nbusy : integer := 0; + + begin + + wait for clock_offset - setup_time; + + file_loop: while not endfile(fstim) loop + + readline (fstim, iline); + + readcomment(iline, ok); + next file_loop when ok; + + readword(iline, dname, ok); + if ok then + case dname is + when ".memon" => -- .memon + read_ea(iline, ival); + R_MEMON <= ival; + wait for 2*clock_period; + + when ".reset" => -- .reset + write(oline, string'(".reset")); + writeline(output, oline); + RESET <= '1'; + wait for clock_period; + RESET <= '0'; + wait for 9*clock_period; + + when ".wait " => -- .wait + read_ea(iline, idelta); + wait for idelta*clock_period; + + when "read " => -- read + readgen_ea(iline, iaddr, 16); + readgen_ea(iline, idata, 16); + ADDR <= iaddr; + REQ <= '1'; + WE <= '0'; + + writetimestamp(oline, CLK_CYCLE, ": stim read "); + writegen(oline, iaddr, right, 6, 16); + write(oline, string'(" ")); + writegen(oline, idata, right, 9, 16); + + wait for clock_period; + REQ <= '0'; + + N_CHK_DATA <= '1', '0' after clock_period; + N_REF_DATA <= idata; + N_REF_ADDR <= iaddr; + + nbusy := 0; + while BUSY = '1' loop + nbusy := nbusy + 1; + wait for clock_period; + end loop; + + write(oline, string'(" nbusy=")); + write(oline, nbusy, right, 2); + writeline(output, oline); + + when "write " => -- write + readgen_ea(iline, iaddr, 16); + read_ea(iline, ibe); + readgen_ea(iline, idata, 16); + ADDR <= iaddr; + BE <= ibe; + DI <= idata; + REQ <= '1'; + WE <= '1'; + + writetimestamp(oline, CLK_CYCLE, ": stim write"); + writegen(oline, iaddr, right, 6, 16); + writegen(oline, ibe , right, 5, 2); + writegen(oline, idata, right, 9, 16); + + wait for clock_period; + REQ <= '0'; + WE <= '0'; + + nbusy := 0; + while BUSY = '1' loop + nbusy := nbusy + 1; + wait for clock_period; + end loop; + + write(oline, string'(" nbusy=")); + write(oline, nbusy, right, 2); + writeline(output, oline); + + + when others => -- bad directive + write(oline, string'("?? unknown directive: ")); + write(oline, dname); + writeline(output, oline); + report "aborting" severity failure; + end case; + else + report "failed to find command" severity failure; + + end if; + + testempty_ea(iline); + + end loop; -- file fstim + + wait for 10*clock_period; + + writetimestamp(oline, CLK_CYCLE, ": DONE "); + writeline(output, oline); + + CLK_STOP <= '1'; + + wait; -- suspend proc_stim forever + -- clock is stopped, sim will end + + end process proc_stim; + + + proc_moni: process + variable oline : line; + begin + + loop + wait until rising_edge(CLK); + + if ACK_R = '1' then + writetimestamp(oline, CLK_CYCLE, ": moni "); + writegen(oline, DO, right, 9, 16); + if R_CHK_DATA_DL = '1' then + write(oline, string'(" CHECK")); + if R_REF_DATA_DL = DO then + write(oline, string'(" OK")); + else + write(oline, string'(" FAIL, exp=")); + writegen(oline, R_REF_DATA_DL, right, 9, 16); + write(oline, string'(" for a=")); + writegen(oline, R_REF_ADDR_DL, right, 5, 16); + end if; + R_CHK_DATA_DL <= '0'; + end if; + writeline(output, oline); + end if; + + if R_CHK_DATA_AL = '1' then + R_CHK_DATA_DL <= R_CHK_DATA_AL; + R_REF_DATA_DL <= R_REF_DATA_AL; + R_REF_ADDR_DL <= R_REF_ADDR_AL; + R_CHK_DATA_AL <= '0'; + end if; + if N_CHK_DATA = '1' then + R_CHK_DATA_AL <= N_CHK_DATA; + R_REF_DATA_AL <= N_REF_DATA; + R_REF_ADDR_AL <= N_REF_ADDR; + end if; + + end loop; + + end process proc_moni; + + + proc_memon: process + variable oline : line; + begin + + loop + wait until rising_edge(CLK); + + if R_MEMON = '1' then + writetimestamp(oline, CLK_CYCLE, ": mem "); + write(oline, string'(" ce=")); + write(oline, not O_MEM_CE_N, right, 2); + write(oline, string'(" we=")); + write(oline, not O_MEM_WE_N, right); + write(oline, string'(" oe=")); + write(oline, not O_MEM_OE_N, right); + write(oline, string'(" a=")); + writegen(oline, O_MEM_ADDR, right, 5, 16); + write(oline, string'(" d=")); + writegen(oline, IO_MEM_DATA, right, 8, 16); + writeline(output, oline); + end if; + + end loop; + + end process proc_memon; + + +end sim; diff --git a/rtl/bplib/cmoda7/tb/tb_c7_sram_memctl_stim.dat b/rtl/bplib/cmoda7/tb/tb_c7_sram_memctl_stim.dat new file mode 100644 index 00000000..31ab9937 --- /dev/null +++ b/rtl/bplib/cmoda7/tb/tb_c7_sram_memctl_stim.dat @@ -0,0 +1,176 @@ +# $Id: tb_c7_sram_memctl_stim.dat 912 2017-06-11 18:30:03Z mueller $ +# +.memon 0 +# +C write full word 16 cells +# +write 00000 1111 30201000 +write 00001 1111 31211101 +write 00002 1111 32221202 +write 00003 1111 33231303 +write 00004 1111 34241404 +write 00005 1111 35251505 +write 00006 1111 36261606 +write 00007 1111 37271707 +write 00008 1111 38281808 +write 00009 1111 39291909 +write 0000a 1111 3a2a1a0a +write 0000b 1111 3b2b1b0b +write 0000c 1111 3c2c1c0c +write 0000d 1111 3d2d1d0d +write 0000e 1111 3e2e1e0e +write 0000f 1111 3f2f1f0f +# +C read 16 cells +# +read 00000 30201000 +read 00001 31211101 +read 00002 32221202 +read 00003 33231303 +read 00004 34241404 +read 00005 35251505 +read 00006 36261606 +read 00007 37271707 +read 00008 38281808 +read 00009 39291909 +read 0000a 3a2a1a0a +read 0000b 3b2b1b0b +read 0000c 3c2c1c0c +read 0000d 3d2d1d0d +read 0000e 3e2e1e0e +read 0000f 3f2f1f0f +# +C write selected bytes in first 16 cells +# +write 00000 0000 70605040 +write 00001 0001 71615141 +write 00002 0010 72625242 +write 00003 0011 73635343 +write 00004 0100 74645444 +write 00005 0101 75655545 +write 00006 0110 76665646 +write 00007 0111 77675747 +write 00008 1000 78685848 +write 00009 1001 79695949 +write 0000a 1010 7a6a5a4a +write 0000b 1011 7b6b5b4b +write 0000c 1100 7c6c5c4c +write 0000d 1101 7d6d5d4d +write 0000e 1110 7e6e5e4e +write 0000f 1111 7f6f5f4f +# +C read back +# +read 00000 30201000 +read 00001 31211141 +read 00002 32225202 +read 00003 33235343 +read 00004 34641404 +read 00005 35651545 +read 00006 36665606 +read 00007 37675747 +read 00008 78281808 +read 00009 79291949 +read 0000a 7a2a5a0a +read 0000b 7b2b5b4b +read 0000c 7c6c1c0c +read 0000d 7d6d1d4d +read 0000e 7e6e5e0e +read 0000f 7f6f5f4f +# +C read and write with waits +# +.wait 3 +write 00010 1111 30201000 +.wait 2 +write 00011 1111 31211101 +.wait 1 +write 00012 1111 32221202 +write 00013 1111 33231303 +# +.wait 3 +read 00010 30201000 +.wait 2 +read 00011 31211101 +.wait 1 +read 0000e 7e6e5e0e +read 0000f 7f6f5f4f +# +C read and write mixed, with waits +# +.wait 2 +write 00014 1111 34241404 +.wait 2 +read 00012 32221202 +.wait 2 +write 00015 1111 35251505 +.wait 2 +read 00013 33231303 +# +.wait 1 +write 00016 1111 36261606 +.wait 1 +read 00014 34241404 +.wait 1 +write 00017 1111 37271707 +.wait 1 +read 00015 35251505 +# +write 00018 1111 38281808 +read 00016 36261606 +write 00019 1111 39291909 +read 00017 37271707 +# +.wait 2 +write 0001a 1111 3a2a1a0a +write 0001b 1111 3b2b1b0b +.wait 2 +read 00018 38281808 +read 00019 39291909 +.wait 2 +write 0001c 1111 3c2c1c0c +write 0001d 1111 3d2d1d0d +.wait 2 +read 0001a 3a2a1a0a +read 0001b 3b2b1b0b +# +.wait 1 +write 0001e 1111 3e2e1e0e +write 0001f 1111 3f2f1f0f +.wait 1 +read 0001c 3c2c1c0c +read 0001d 3d2d1d0d +.wait 1 +write 00014 0100 74645444 +write 00015 0101 75655545 +.wait 1 +read 0001e 3e2e1e0e +read 0001f 3f2f1f0f +# +write 00016 0110 76665646 +write 00017 0111 77675747 +read 00010 30201000 +read 00011 31211101 +write 00018 1000 78685848 +write 00019 1001 79695949 +read 00012 32221202 +read 00013 33231303 +# +write 0001a 1010 7a6a5a4a +write 0001b 1011 7b6b5b4b +write 0001c 1100 7c6c5c4c +read 00014 34641404 +read 00015 35651545 +read 00016 36665606 +write 0001d 1101 7d6d5d4d +write 0001e 1110 7e6e5e4e +write 0001f 1111 7f6f5f4f +read 00017 37675747 +read 00018 78281808 +read 00019 79291949 +read 0001a 7a2a5a0a +read 0001b 7b2b5b4b +read 0001c 7c6c1c0c +read 0001d 7d6d1d4d +read 0001e 7e6e5e0e +read 0001f 7f6f5f4f