-- File: testccm.vhd -- Author: CHEN, Qihong, Portland State University -- Date: 3/30/97 -- -- Test bench of CCM2 library ieee; use std.textio.all; use ieee.std_logic_textio.all; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.stringpkg.all; use work.ccmtype.all; entity testccm is end testccm; architecture test of testccm is component ccm port ( -- global signals reset, clk : in std_logic; -- the input/output fifos ififo_din : in std_logic_vector (31 downto 0); ofifo_dout : out std_logic_vector (31 downto 0); ififo_we, ofifo_re : in std_logic; ififo_ff, ofifo_ef : buffer std_logic; state : out BIUstate ); end component; constant cmd_filename: string := "test.ccm"; signal clk: std_logic := '0'; signal reset : std_logic; signal ififo_din, ofifo_dout : std_logic_vector (31 downto 0); signal ififo_we, ofifo_re : std_logic := '0'; signal ififo_ff, ofifo_ef : std_logic; signal state : BIUstate; signal init_done : boolean := false; BEGIN u0: ccm port map ( reset=>reset, clk=>clk, ififo_din=>ififo_din, ofifo_dout=>ofifo_dout, ififo_we=>ififo_we, ofifo_re=>ofifo_re, ififo_ff=>ififo_ff, ofifo_ef=>ofifo_ef, state=>state ); -- clock process is used to generated clock signal. clock: process begin clk <= not clk after 50 ns; wait for 50 ns; end process; -- read output FIFO whenever there is a cube in it. read_ofifo : process variable outbuf: line; variable resultno: integer := 0; begin wait for 100 ns; if (init_done) then if (ofifo_re = '1') then resultno := resultno + 1; write(outbuf, string'(" [Time: ")); write(outbuf, now); write(outbuf, string'("] result cube (No.")); write(outbuf, resultno); write(outbuf, string'("): ")); write(outbuf, ofifo_dout(31 downto 30)); write(outbuf, string'("-")); write(outbuf, ofifo_dout(29 downto 22)); write(outbuf, string'("-")); write(outbuf, ofifo_dout(21 downto 14)); write(outbuf, string'("-")); write(outbuf, ofifo_dout(13 downto 6)); write(outbuf, string'("-")); write(outbuf, ofifo_dout(5 downto 0)); writeline(output, outbuf); end if; if (ofifo_ef = '1') then ofifo_re <= '0'; else ofifo_re <= '1'; end if; end if; end process; -- This is the main process of the test bench. verify: process type CCMSymbol is ( -- command symbols ccmSET, ccmENABLE, ccmDISABLE, ccmEXEC, ccmLOOP, -- registers regAddrA, regAddrB, regAddrR, regWater, regRight, regInst, regConf, regACCU, regPRPO, -- tri-buffers tbufAddrA, tbufAddrB, tbufIFifoA, tbufIFifoD, tbufMemARW, tbufMemBRW, tbufIluA, tbufIluB, -- others ccmINVALID ); -- convert ccm assembly command into CCMSymbol. procedure to_command(token: inout line; symID: out CCMSymbol) is variable cmpret : boolean; begin cmp_string(token, string'("SET"), cmpret); if (cmpret) then symID := ccmSET; else cmp_string(token, string'("ENABLE"), cmpret); if (cmpret) then symID := ccmENABLE; else cmp_string(token, string'("DISABLE"), cmpret); if (cmpret) then symID := ccmDISABLE; else cmp_string(token, string'("EXEC"), cmpret); if (cmpret) then symID := ccmEXEC; else cmp_string(token, string'("LOOP"), cmpret); if (cmpret) then symID := ccmLOOP; else symID := ccmINVALID; end if; end if; end if; end if; end if; Deallocate(token); end to_command; -- convert register name into CCMSymbol. procedure to_register(token: inout line; symID: out CCMSymbol) is variable cmpret : boolean; begin cmp_string(token, string'("AddrA"), cmpret); if (cmpret) then symID := regAddrA; else cmp_string(token, string'("AddrB"), cmpret); if (cmpret) then symID := regAddrB; else cmp_string(token, string'("AddrR"), cmpret); if (cmpret) then symID := regAddrR; else cmp_string(token, string'("Water"), cmpret); if (cmpret) then symID := regWater; else cmp_string(token, string'("Right"), cmpret); if (cmpret) then symID := regRight; else cmp_string(token, string'("Inst"), cmpret); if (cmpret) then symID := regInst; else cmp_string(token, string'("Conf"), cmpret); if (cmpret) then symID := regConf; else cmp_string(token, string'("Accu"), cmpret); if (cmpret) then symID := regAccu; else cmp_string(token, string'("Prpo"), cmpret); if (cmpret) then symID := regPRPO; else symID := ccmINVALID; end if; end if; end if; end if; end if; end if; end if; end if; end if; Deallocate(token); end to_register; -- convert tri-state buffer name into CCMSymbol. procedure to_tribuf(token: inout line; symID: out CCMSymbol) is variable cmpret : boolean; begin cmp_string(token, string'("enIFifoA"), cmpret); if (cmpret) then symID := tbufIFifoA; else cmp_string(token, string'("enIFifoD"), cmpret); if (cmpret) then symID := tbufIFifoD; else cmp_string(token, string'("enIluA"), cmpret); if (cmpret) then symID := tbufIluA; else cmp_string(token, string'("enIluB"), cmpret); if (cmpret) then symID := tbufIluB; else cmp_string(token, string'("enAddrA"), cmpret); if (cmpret) then symID := tbufAddrA; else cmp_string(token, string'("enAddrB"), cmpret); if (cmpret) then symID := tbufAddrB; else cmp_string(token, string'("MemARW"), cmpret); if (cmpret) then symID := tbufMemARW; else cmp_string(token, string'("MemBRW"), cmpret); if (cmpret) then symID := tbufMemBRW; else symID := ccmINVALID; end if; end if; end if; end if; end if; end if; end if; end if; Deallocate(token); end to_tribuf; file ifile : text is in cmd_filename; variable inbuf, outbuf, tempstr, token : line; variable good, equal, valid_cmd : boolean := false; variable lineno, state_s0_no : integer := 0; variable ch : character; variable cursymID, argsymID : CCMSymbol; variable vec_addra, vec_addrb, vec_addrr : std_logic_vector(1 to 18); variable vec_water, vec_right : std_logic_vector(1 to 15); variable vec_inst : std_logic_vector(1 to 21); variable vec_conf : std_logic_vector(1 to 9); variable vec_accu, vec_data : std_logic_vector(1 to 30); variable vec_prpo : std_logic_vector(1 to 24); variable encoded_cmd : std_logic_vector(31 downto 0); begin -- initialize the CCM. if (not init_done) then -- ififo_we <= '0'; -- ofifo_re <= '0'; reset <= '1'; wait for 75 ns; reset <= '0'; wait for 30 ns; write(outbuf, string'("Initialize the CCM ...")); writeline(output, outbuf); init_done <= true; end if; -- the following while loop read one line of CCM assembly, converts -- into CCM instruction represented by binary number. If it encounts -- a line of invalid CCM assembly (like comments), it will read next -- line of CCM assembly. while not endfile(ifile) loop write(outbuf, string'("[Time: ")); write(outbuf, now); write(outbuf, string'("] read command")); writeline(output, outbuf); lineno := lineno + 1; readline(ifile, inbuf); tempstr := new string'(inbuf.all); write(outbuf, lineno, right, 3); write(outbuf, string'(". ")); write(outbuf, string'(tempstr.all)); writeline(output, outbuf); read(inbuf, ch, good); if (not good) or (ch /= ' ') then next; end if; get_string(inbuf, token, good); if (not good) then next; end if; -- encoded_cmd := "00000000000000000000000000000000"; encoded_cmd := (others => '0'); valid_cmd := true; to_command(token, cursymID); case cursymID is when ccmSET => get_string(inbuf, token, good); if (not good) then write(outbuf, string'(" CCM ERROR: Invalid set command.")); writeline(output, outbuf); next; end if; encoded_cmd(31 downto 29) := "001"; to_register(token, argsymID); case argsymID is when regAddrA => read_std_logic_vector(inbuf, vec_addra, '0'); encoded_cmd(28 downto 26) := "000"; encoded_cmd(17 downto 0) := vec_addra; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when regAddrB => read_std_logic_vector(inbuf, vec_addrb, '0'); encoded_cmd(28 downto 26) := "001"; encoded_cmd(17 downto 0) := vec_addrb; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when regAddrR => read_std_logic_vector(inbuf, vec_addrr, '0'); encoded_cmd(28 downto 26) := "010"; encoded_cmd(17 downto 0) := vec_addrr; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when regWater => read_std_logic_vector(inbuf, vec_water, '1'); encoded_cmd(28 downto 26) := "011"; encoded_cmd(14 downto 0) := vec_water; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when regRight => read_std_logic_vector(inbuf, vec_right, '0'); encoded_cmd(28 downto 26) := "100"; encoded_cmd(14 downto 0) := vec_right; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when regInst => read_std_logic_vector(inbuf, vec_inst, '0'); encoded_cmd(28 downto 26) := "101"; encoded_cmd(25 downto 23) := vec_inst(1 to 3); encoded_cmd(17 downto 0) := vec_inst(4 to 21); write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when regConf => read_std_logic_vector(inbuf, vec_conf, '0'); encoded_cmd(28 downto 26) := "110"; encoded_cmd(8 downto 0) := vec_conf; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when regAccu => read_std_logic_vector(inbuf, vec_accu, '0'); encoded_cmd(31 downto 30) := "01"; encoded_cmd(29 downto 0) := vec_accu; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when regPRPO => read_std_logic_vector(inbuf, vec_prpo, '0'); encoded_cmd(28 downto 26) := "111"; encoded_cmd(23 downto 0) := vec_prpo; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when others => write(outbuf, string'(" invalid set command. ")); writeline(output, outbuf); valid_cmd := false; end case; when ccmENABLE => get_string(inbuf, token, good); if (not good) then write(outbuf, string'(" CCM ERROR: Invalid enable command.")); writeline(output, outbuf); next; end if; encoded_cmd(31 downto 29) := "000"; encoded_cmd(25) := '1'; to_tribuf(token, argsymID); case argsymID is when tbufAddrA => encoded_cmd(28 downto 26) := "000"; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when tbufAddrB => encoded_cmd(28 downto 26) := "001"; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when tbufIFifoA => encoded_cmd(28 downto 26) := "010"; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when tbufMemARW => encoded_cmd(28 downto 26) := "011"; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when tbufIluA => encoded_cmd(28 downto 26) := "100"; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when tbufIFifoD => encoded_cmd(28 downto 26) := "101"; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when tbufMemBRW => encoded_cmd(28 downto 26) := "110"; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when tbufIluB => encoded_cmd(28 downto 26) := "111"; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when others => write(outbuf, string'(" invalid enable command. ")); writeline(output, outbuf); valid_cmd := false; end case; when ccmDISABLE => get_string(inbuf, token, good); if (not good) then write(outbuf, string'(" CCM ERROR: Invalid disable command.")); writeline(output, outbuf); next; end if; encoded_cmd(31 downto 29) := "000"; to_tribuf(token, argsymID); case argsymID is when tbufAddrA => encoded_cmd(28 downto 26) := "000"; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when tbufAddrB => encoded_cmd(28 downto 26) := "001"; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when tbufIFifoA => encoded_cmd(28 downto 26) := "010"; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when tbufMemARW => encoded_cmd(28 downto 26) := "011"; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when tbufIluA => encoded_cmd(28 downto 26) := "100"; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when tbufIFifoD => encoded_cmd(28 downto 26) := "101"; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when tbufMemBRW => encoded_cmd(28 downto 26) := "110"; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when tbufIluB => encoded_cmd(28 downto 26) := "111"; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when others => write(outbuf, string'(" invalid disable command. ")); writeline(output, outbuf); valid_cmd := false; end case; when ccmEXEC => read_std_logic_vector(inbuf, vec_data, '0'); encoded_cmd(31 downto 30) := "10"; encoded_cmd(29 downto 0) := vec_data; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when ccmLOOP => read_std_logic_vector(inbuf, vec_data, '0'); encoded_cmd(31 downto 30) := "11"; encoded_cmd(29 downto 0) := vec_data; write(outbuf, string'(" encoded command is ")); write(outbuf, encoded_cmd); writeline(output, outbuf); when others => write(outbuf, string'(" invalid command. ")); writeline(output, outbuf); valid_cmd := false; end case; if (not valid_cmd) then next; end if; -- push the command into the input fifo ififo_we <= '1'; ififo_din <= encoded_cmd; wait for 100 ns; end loop; -- read command file ififo_we <= '0'; -- if CCM keeps in state S0 in two continuous clock periods, then -- the simulation is done. while ( state_s0_no < 2 ) loop if (state = s0) then state_s0_no := state_s0_no + 1; else state_s0_no := 0; end if; wait for 100 ns; end loop; -- simulation is done write(outbuf, string'(" Time: ")); write(outbuf, now); writeline(output, outbuf); assert false report "Simulation is done." severity note; wait; end process; END;