diff options
Diffstat (limited to 'PIC/tb_pic.vhd')
| -rw-r--r-- | PIC/tb_pic.vhd | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/PIC/tb_pic.vhd b/PIC/tb_pic.vhd new file mode 100644 index 0000000..067e154 --- /dev/null +++ b/PIC/tb_pic.vhd @@ -0,0 +1,83 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.read_intel_hex_pack.all; + +entity tb_pic is +end entity tb_pic; + +architecture behavioural of tb_pic is + constant T_clk : time := 20 ns; -- 50M + constant HEX_FILE : string := "program.hex"; + constant SIM_CYCLES : integer := 800_000; + + signal clk : std_logic := '0'; + signal reset : std_logic := '1'; + signal opcode : std_logic_vector(13 downto 0); + + signal program_counter : std_logic_vector(12 downto 0); + signal instruction_return : std_logic; + signal work_reg : std_logic_vector(7 downto 0); + signal status : std_logic_vector(2 downto 0); + signal port_a : std_logic_vector(7 downto 0); + signal port_b : std_logic_vector(7 downto 0); + + signal done : boolean := false; + + signal uart_tx : std_logic; + signal uart_rx : std_logic := '1'; -- idle high (no incoming bytes) + + -- program memory: 1024 x 14-bit + signal prog_mem : program_array := (others => (others => '0')); + +begin + + clk <= not clk after T_clk / 2 when not done else unaffected; + + -- drive opcode from program memory using PC + opcode <= prog_mem(to_integer(unsigned(program_counter))); + + dut : entity work.PIC(rtl) + generic map ( + CLK_FREQ => 50_000_000 -- 10 MHz, matches T_clk = 100 ns + ) + port map ( + clk => clk, + reset => reset, + opcode => opcode, + program_counter => program_counter, + instruction_return => instruction_return, + work_reg => work_reg, + status => status, + port_a => port_a, + port_b => port_b, + uart_tx => uart_tx, + uart_rx => uart_rx + ); + + stimulus : process is + variable mem : program_array; + begin + -- load hex file into program memory + read_ihex_file(HEX_FILE, mem); + prog_mem <= mem; + + -- reset pulse + reset <= '1'; + wait for T_clk * 2; + reset <= '0'; + + -- run for SIM_CYCLES instruction cycles + for i in 0 to SIM_CYCLES - 1 loop + wait until rising_edge(clk); + end loop; + + report "simulation done. port_a=" & integer'image(to_integer(unsigned(port_a))) + & " port_b=" & integer'image(to_integer(unsigned(port_b))) + severity note; + + done <= true; + wait; + end process stimulus; + +end architecture behavioural; |
