summaryrefslogtreecommitdiffstats
path: root/PIC/tb_pic.vhd
diff options
context:
space:
mode:
Diffstat (limited to 'PIC/tb_pic.vhd')
-rw-r--r--PIC/tb_pic.vhd83
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;