1 ------------------------------------------------------------------------------
3 ---- Testbench for the ZPU Small connection to the FPGA ----
5 ---- http://www.opencores.org/ ----
8 ---- This is a testbench to simulate the ZPU_Small1 core as used in the ----
9 ---- *_small1.vhdl ----
11 ---- ...plus the JTAG debugger proof of concept for the Small core.
17 ---- - Salvador E. Tropea, salvador inti.gob.ar ----
18 ---- Modifications for core debug signal testing
19 ---- - Martin Strubel <hackfin@section5.ch>
21 ------------------------------------------------------------------------------
23 ---- Copyright (c) 2008 Salvador E. Tropea <salvador inti.gob.ar> ----
24 ---- Copyright (c) 2008 Instituto Nacional de TecnologĂa Industrial ----
26 ---- Distributed under the BSD license ----
28 ------------------------------------------------------------------------------
30 ---- Design unit: HWDbg_Small1_TB(Behave) (Entity and architecture) ----
31 ---- File name: small1_tb.vhdl ----
33 ---- Limitations: None known ----
34 ---- Errors: None known ----
35 ---- Library: work ----
36 ---- Dependencies: IEEE.std_logic_1164 ----
37 ---- IEEE.numeric_std ----
39 ---- zpu.txt_util ----
40 ---- work.zpu_memory ----
41 ---- Target FPGA: Spartan 3 (XC3S1500-4-FG456) ----
42 ---- Language: VHDL ----
43 ---- Wishbone: No ----
44 ---- Synthesis tools: N/A ----
45 ---- Simulation tools: Isim
46 ---- Text editor: gvim
48 ------------------------------------------------------------------------------
51 use IEEE.std_logic_1164.all;
52 use IEEE.numeric_std.all;
59 use work.zpu_memory.all;
61 entity HWDbg_Small1_TB is
62 end entity HWDbg_Small1_TB;
64 architecture Behave of HWDbg_Small1_TB is
65 constant WORD_SIZE : natural:=32; -- 32 bits data path
66 constant ADDR_W : natural:=18; -- 18 bits address space=256 kB, 128 kB I/O
67 constant BRAM_W : natural:=14; -- 15 bits RAM space=32 kB
68 constant D_CARE_VAL : std_logic:='0'; -- Fill value
69 constant CLK_FREQ : positive:=50; -- 50 MHz clock
70 constant CLK_S_PER : time:=1 us/(2.0*real(CLK_FREQ)); -- Clock semi period
71 constant BRATE : positive:=115200;
73 -- Opcode to leave emulation:
74 constant OPCODE_LEAVE_EMULATION : unsigned(3 downto 0) := OPCODE_BREAK;
77 generic (EMUDAT_SIZE : natural;
78 EMUIR_SIZE : natural);
86 emuexec : out std_logic; -- Execute opcode on rising edge
87 emurequest : out std_logic; -- Emulation request to core
88 emuack : in std_logic; -- Core has acknowledged EMULATION request
89 emurdy : in std_logic; -- Core ready to execute next instruction
90 -- Program Counter without going to emulation.
91 dbgpc : in std_logic_vector(32-1 downto 0);
93 emudata_i : in std_logic_vector(32-1 downto 0);
94 emudata_o : out std_logic_vector(32-1 downto 0);
95 emudat_wr : in std_logic;
96 emudat_rd : in std_logic;
97 emuir : out std_logic_vector(OPCODE_W-1 downto 0)
101 component ZPU_Small1 is
103 WORD_SIZE : natural:=32; -- 32 bits data path
104 D_CARE_VAL : std_logic:='0'; -- Fill value
105 CLK_FREQ : positive:=50; -- 50 MHz clock
106 BRATE : positive:=115200; -- RS232 baudrate
107 ADDR_W : natural:=16; -- 16 bits address space=64 kB, 32 kB I/O
108 BRAM_W : natural:=15); -- 15 bits RAM space=32 kB
110 clk_i : in std_logic; -- CPU clock
111 rst_i : in std_logic; -- Reset
114 emureq_i : in std_logic;
115 emuexec_i : in std_logic;
116 emuack_o : out std_logic;
117 emurdy_o : out std_logic;
118 emuir : in std_logic_vector(OPCODE_W-1 downto 0);
120 break_o : out std_logic; -- Break executed
121 dbg_o : out zpu_dbgo_t; -- Debug info
122 rs232_tx_o : out std_logic; -- UART Tx
123 rs232_rx_i : in std_logic); -- UART Rx
124 end component ZPU_Small1;
126 signal clk : std_logic;
127 signal reset : std_logic:='1';
129 signal emureq : std_logic := '0';
130 signal emuexec : std_logic := '0';
131 signal emuack : std_logic;
132 signal emurdy : std_logic := '0';
133 signal emuir : std_logic_vector(OPCODE_W-1 downto 0);
135 signal break : std_logic := '0';
136 signal dbg : zpu_dbgo_t; -- Debug info
137 signal rs232_tx : std_logic;
138 signal rs232_rx : std_logic;
142 signal terminate : std_logic := '0';
143 signal mismatch : std_logic := '0';
144 signal finish : std_logic;
145 signal save_sp : unsigned(31 downto 0);
151 WORD_SIZE => WORD_SIZE, D_CARE_VAL => D_CARE_VAL,
152 CLK_FREQ => CLK_FREQ, BRATE => BRATE, ADDR_W => ADDR_W,
155 clk_i => clk, rst_i => reset, rs232_tx_o => rs232_tx,
156 emureq_i => emureq, emuexec_i => emuexec,
157 emuack_o => emuack, emurdy_o => emurdy,
159 rs232_rx_i => rs232_rx, break_o => break, dbg_o => dbg);
163 ADDR_W => ADDR_W, WORD_SIZE => WORD_SIZE,
164 LOG_FILE => "dbg_small1_trace.log")
166 clk_i => clk, dbg_i => dbg, emu_i => emuack, stop_i => '0',
177 print("* Finish asserted, end of test");
178 if terminate = '1' then
179 print("* Reason: Terminate");
181 if mismatch = '1' then
182 print("* Reason: Mismatch");
185 print("* Reason: Breakpoint");
189 end process do_clock;
194 wait until rising_edge(clk);
196 end process do_reset;
200 procedure execute_opcode(
201 code: unsigned(OPCODE_W-1 downto 0)
204 emuir <= std_logic_vector(code);
206 wait until rising_edge(clk);
208 wait until rising_edge(clk);
213 procedure push_imm32(
214 imm: unsigned(31 downto 0)
217 execute_opcode(OPCODE_IM & "000" & imm(31 downto 28));
218 execute_opcode(OPCODE_IM & imm(27 downto 21));
219 execute_opcode(OPCODE_IM & imm(20 downto 14));
220 execute_opcode(OPCODE_IM & imm(13 downto 7));
221 execute_opcode(OPCODE_IM & imm(6 downto 0));
226 execute_opcode(OPCODE_SHORT & OPCODE_PUSHSP); -- Restore context
227 execute_opcode(OPCODE_SHORT & OPCODE_NOP);
228 print("sp: " & hstr(dbg.stk_a));
229 -- execute_opcode(OPCODE_LOADSP & '1' & x"1"); -- Restore context
230 execute_opcode(OPCODE_SHORT & OPCODE_POPSP); -- Restore context
234 addr: unsigned(31 downto 0)
237 execute_opcode(OPCODE_SHORT & OPCODE_PUSHSP); -- Restore context
238 -- Save current SP for for reference. Note the dbg.sp is not yet
239 -- updated to the above command.
242 execute_opcode(OPCODE_SHORT & OPCODE_LOAD); -- Load indirect
243 execute_opcode(OPCODE_SHORT & OPCODE_NOP);
244 print("value: " & hstr(dbg.stk_a));
245 execute_opcode(OPCODE_LOADSP & '1' & x"1"); -- Restore context
246 execute_opcode(OPCODE_SHORT & OPCODE_POPSP); -- Restore context
247 execute_opcode(OPCODE_SHORT & OPCODE_NOP);
249 if (dbg.sp /= save_sp) then
251 print("* ERROR: Stack pointers don't match");
252 print("sp: " & hstr(dbg.sp) & " SAVE_SP: " & hstr(save_sp));
260 emuir <= "00001011"; -- NOP
263 -- It is IMPORTANT to wait after an emu request
264 wait until emurdy = '1' and break ='1';
267 ----------------------------------------------------------------------------
273 for i in 0 to 200 loop
275 execute_opcode(OPCODE_SHORT & OPCODE_LEAVE_EMULATION);
279 ----------------------------------------------------------------------------
280 -- Save context here:
282 execute_opcode(OPCODE_SHORT & OPCODE_PUSHSP); -- Restore context
283 -- Save current SP for for reference. Note the dbg.sp is not yet
284 -- updated to the above command.
287 -- Now do your stuff and count the pushes, including the above
291 push_imm32(x"000008d8");
293 -- execute_opcode(OPCODE_LOADSP & '1' & x"0");
294 execute_opcode(OPCODE_SHORT & OPCODE_LOAD); -- Load indirect
296 execute_opcode(OPCODE_SHORT & OPCODE_NOP);
297 print("value: " & hstr(dbg.stk_a));
299 -- Now we should see the data from the address above in
304 -- Restore old stack:
307 -- execute_opcode(OPCODE_SHORT & OPCODE_PUSHSP);
309 -- execute_opcode(OPCODE_IM & "000" & x"8");
310 -- execute_opcode(OPCODE_SHORT & OPCODE_ADD);
311 execute_opcode(OPCODE_LOADSP & '1' & x"1"); -- Restore context
312 execute_opcode(OPCODE_SHORT & OPCODE_POPSP); -- Restore context
313 -- push_imm32(save_sp);
315 -- Need one NOP to update dbg.sp (for sanity check):
316 execute_opcode(OPCODE_SHORT & OPCODE_NOP);
318 if (dbg.sp /= save_sp) then
320 print("* MEM_READ ERROR: Stack pointers don't match");
321 print("sp: " & hstr(dbg.sp) & " SAVE_SP: " & hstr(save_sp));
324 ----------------------------------------------------------------------------
326 execute_opcode(OPCODE_SHORT & OPCODE_PUSHSP); -- Restore context
327 -- Save current SP for for reference. Note the dbg.sp is not yet
328 -- updated to the above command.
331 push_imm32(x"deadbeef");
332 execute_opcode(OPCODE_SHORT & OPCODE_NOP);
333 push_imm32(x"000008d8");
334 execute_opcode(OPCODE_SHORT & OPCODE_STORE); -- Store indirect
336 execute_opcode(OPCODE_LOADSP & '1' & x"0"); -- Restore context
337 execute_opcode(OPCODE_SHORT & OPCODE_POPSP); -- Restore context
339 -- Need one NOP to update dbg.sp (for sanity check):
340 execute_opcode(OPCODE_SHORT & OPCODE_NOP);
342 if (dbg.sp /= save_sp) then
344 print("* MEM_WRITE ERROR: Stack pointers don't match");
345 print("sp: " & hstr(dbg.sp) & " SAVE_SP: " & hstr(save_sp));
348 ----------------------------------------------------------------------------
350 mem_read(x"000008d8");
352 ----------------------------------------------------------------------------
354 push_imm32(x"00000000");
355 execute_opcode(OPCODE_SHORT & OPCODE_POPPC); -- Restore context
356 ----------------------------------------------------------------------------
359 execute_opcode(OPCODE_SHORT & OPCODE_NOP);
369 finish <= mismatch or terminate; -- or break;
371 end architecture Behave; -- Entity: HWDbg_Small1_TB