summaryrefslogtreecommitdiffstats
path: root/PIC
diff options
context:
space:
mode:
authorVaino Kauppila <vaino@vke.fi>2026-04-19 12:32:58 +0300
committerVaino Kauppila <vaino@vke.fi>2026-04-19 12:32:58 +0300
commiteb8643ddbef43547eb7bfe58789a3908926c7258 (patch)
treefadfba88a1c71b266b8c67df166a3a6ead6b30d1 /PIC
parent129a1c975dbd0c042576010b1f6eb40d19fc5733 (diff)
downloadvhdl_pic-eb8643ddbef43547eb7bfe58789a3908926c7258.tar.gz
vhdl_pic-eb8643ddbef43547eb7bfe58789a3908926c7258.zip
refactor dir structure, add fib.c
Diffstat (limited to 'PIC')
-rw-r--r--PIC/ALU.vhd216
-rw-r--r--PIC/PIC.vhd181
-rw-r--r--PIC/blink.c35
-rw-r--r--PIC/common.vhd10
-rw-r--r--PIC/decoder.vhd155
-rw-r--r--PIC/dpram.vhd110
-rw-r--r--PIC/fifo.vhd75
-rw-r--r--PIC/hdl-prj.json24
-rw-r--r--PIC/hexfile_reader.vhd342
-rw-r--r--PIC/pic_top.vhd81
-rw-r--r--PIC/prog_rom.vhd1045
-rw-r--r--PIC/stack.vhd51
-rw-r--r--PIC/state_machine.vhd222
-rw-r--r--PIC/tb_pic.vhd83
-rw-r--r--PIC/tb_stack.vhd121
-rw-r--r--PIC/test_uart.c67
-rw-r--r--PIC/uart.vhd195
17 files changed, 0 insertions, 3013 deletions
diff --git a/PIC/ALU.vhd b/PIC/ALU.vhd
deleted file mode 100644
index b7c0344..0000000
--- a/PIC/ALU.vhd
+++ /dev/null
@@ -1,216 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-use work.alu_types.all;
-
-entity alu is
- port (
- a, b : in std_logic_vector(7 downto 0); -- inputs to ALU. In
- -- general here 'a' is
- -- a value from working
- -- register W and 'b'
- -- is from a file
- -- register.
-
- op : in alu_op; -- ALU operation which
- -- one to use
-
- bit_select : in std_logic_vector(2 downto 0); -- this is the 'b' signal in
- -- the datasheet.
-
- status_in : in std_logic_vector(2 downto 0); -- status before ALU operation.
-
- status : out std_logic_vector(2 downto 0); -- status after ALU operation.
-
- result : out std_logic_vector(7 downto 0); -- result of the ALU
- -- operation. This is
- -- then either stored
- -- in file register f
- -- or work register W.
-
-
- skip : out std_logic -- SKIP signal.
-
- -- the status register is of form:
- -- IRP RP1 RP0 ~TO ~PD Z DC C
- -- 7 6 5 4 3 2 1 0
- -- ALU only operates on 3 least significant bits.
- );
-
-end entity alu;
-
-architecture rtl of alu is
-
- -- ternary op; returns x1 if cond is true, x2 otherwise.
- pure function sel(cond : boolean; x1, x2 : std_logic) return std_logic is
- begin
- if cond then return x1; else return x2; end if;
- end function;
-
- -- return status with the given flag set to val, all other bits same
- pure function set_flag(flag : alu_flag; val : std_logic; stat : std_logic_vector(2 downto 0)) return std_logic_vector is
- variable s_out : std_logic_vector(2 downto 0) := stat;
- begin
- case flag is
- when FLAG_Z => s_out(2) := val;
- when FLAG_DC => s_out(1) := val;
- when FLAG_C => s_out(0) := val;
- end case;
- return s_out;
- end function;
-
- -- Computes val +/- 1, drives result and either sets Z flag or skip signal.
- procedure inc_dec(
- val : in std_logic_vector(7 downto 0);
- inc : in boolean; -- true = increment, false = decrement
- do_skip : in boolean; -- true for *FSZ variants
- signal res : out std_logic_vector(7 downto 0);
- signal stat : out std_logic_vector(2 downto 0);
- signal do_skip_out : out std_logic;
- stat_in : in std_logic_vector(2 downto 0)
- ) is
- variable t : std_logic_vector(7 downto 0);
- begin
- if inc then
- t := std_logic_vector(unsigned(val) + 1);
- else
- t := std_logic_vector(unsigned(val) - 1);
- end if;
- res <= t;
- if do_skip then
- if unsigned(t) = 0 then
- do_skip_out <= '1';
- else
- do_skip_out <= '0';
- end if;
- else
- stat <= set_flag(FLAG_Z, sel(unsigned(t) = 0, '1', '0'), stat_in);
- end if;
- end procedure;
-
-begin
- process(a, b, op, bit_select, status_in)
- variable tmp : std_logic_vector(7 downto 0);
- variable tmp_extended : std_logic_vector(8 downto 0);
-
- variable tmp_status : std_logic_vector(2 downto 0);
- begin
-
- -- DEFAULT case (NOP)
- result <= (others => '0'); -- default: zero result
- skip <= '0'; -- default: no skip
- status <= status_in; -- default: pass status thru
-
- case op is
- when NOP => -- nothing
-
-
- when ADDWF | ADDLW =>
- -- addition
- tmp_extended := std_logic_vector(unsigned('0' & a) + unsigned('0' & b));
-
- -- DC
- tmp(4 downto 0) := std_logic_vector(('0' & unsigned(a(3 downto 0))) + ('0' & unsigned(b(3 downto 0))));
-
- -- flags
- tmp_status := set_flag(FLAG_Z, sel(unsigned(tmp_extended(7 downto 0)) = 0, '1', '0'), status_in);
- tmp_status := set_flag(FLAG_C, tmp_extended(8), tmp_status);
- tmp_status := set_flag(FLAG_DC, tmp(4), tmp_status);
-
- status <= tmp_status;
- result <= tmp_extended(7 downto 0);
-
- when SUBLW | SUBWF =>
- -- PIC16F84A: SUBWF = f - W, SUBLW = k - W → dest = b - a
- tmp_extended := std_logic_vector(unsigned('0' & b) - unsigned('0' & a));
-
- -- DC: borrow out of lower nibble
- tmp(4 downto 0) := std_logic_vector(('0' & unsigned(b(3 downto 0))) - ('0' & unsigned(a(3 downto 0))));
-
- tmp_status := set_flag(FLAG_Z, sel(unsigned(tmp_extended(7 downto 0)) = 0, '1', '0'), status_in);
- tmp_status := set_flag(FLAG_C, not tmp_extended(8), tmp_status);
- tmp_status := set_flag(FLAG_DC, not tmp(4), tmp_status);
-
- status <= tmp_status;
- result <= tmp_extended(7 downto 0);
-
- when IORLW | IORWF =>
- tmp := a or b;
- result <= tmp;
- status <= set_flag(FLAG_Z, sel(unsigned(tmp) = 0, '1', '0'), status_in);
-
- when ANDWF | ANDLW =>
- tmp := a and b;
- result <= tmp;
- status <= set_flag(FLAG_Z, sel(unsigned(tmp) = 0, '1', '0'), status_in);
-
- when XORLW | XORWF =>
- tmp := a xor b;
- result <= tmp;
- status <= set_flag(FLAG_Z, sel(unsigned(tmp) = 0, '1', '0'), status_in);
-
- when COMF =>
- tmp := not b;
- result <= tmp;
- status <= set_flag(FLAG_Z, sel(unsigned(tmp) = 0, '1', '0'), status_in);
-
- when DECF => inc_dec(b, false, false, result, status, skip, status_in);
- when DECFSZ => inc_dec(b, false, true, result, status, skip, status_in);
- when INCF => inc_dec(b, true, false, result, status, skip, status_in);
- when INCFSZ => inc_dec(b, true, true, result, status, skip, status_in);
-
- when RLF =>
- tmp := std_logic_vector(shift_left(unsigned(b), 1));
- tmp(0) := status_in(0);
- status(0) <= b(7);
- result <= tmp;
-
- when RRF =>
- tmp := std_logic_vector(shift_right(unsigned(b), 1));
- tmp(7) := status_in(0);
- status(0) <= b(0);
- result <= tmp;
-
-
-
- when BCF =>
- result <= b;
- result(to_integer(unsigned(bit_select))) <= '0';
-
- when BTFSC =>
- skip <= not b(to_integer(unsigned(bit_select)));
-
- when BSF =>
- result <= b;
- result(to_integer(unsigned(bit_select))) <= '1';
-
- when BTFSS =>
- skip <= b(to_integer(unsigned(bit_select)));
-
- when SWAPF =>
- tmp(7 downto 4) := b(3 downto 0);
- tmp(3 downto 0) := b(7 downto 4);
- result <= tmp;
-
-
- when CLRF | CLRW =>
- result <= (others => '0');
- status <= set_flag(FLAG_Z, '1', status_in);
-
- when MOVF =>
- result <= b;
- status <= set_flag(FLAG_Z, sel(unsigned(b) = 0, '1', '0'), status_in);
- when MOVWF => result <= a;
- when MOVLW => result <= b;
-
-
-
-
- when CALL => null;
- when GOTO => null;
- when RETLW => result <= b;
- when RETUR => null;
-
- end case;
- end process;
-end architecture rtl;
diff --git a/PIC/PIC.vhd b/PIC/PIC.vhd
deleted file mode 100644
index a31bec7..0000000
--- a/PIC/PIC.vhd
+++ /dev/null
@@ -1,181 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-use work.alu_types.all;
-
-entity PIC is
- generic (
- CLK_FREQ : positive := 50_000_000; -- 50M, GW5A clock
- BAUD_RATE : positive := 115_200
- );
- port (
- clk : in std_logic;
- reset : in std_logic;
- opcode : in std_logic_vector(13 downto 0);
-
- program_counter : out std_logic_vector(12 downto 0) := (others => '0');
- instruction_return : out std_logic := '0';
- work_reg : out std_logic_vector(7 downto 0) := (others => '0');
- status : out std_logic_vector(2 downto 0) := (others => '0');
- port_a : out std_logic_vector(7 downto 0) := (others => '0');
- port_b : out std_logic_vector(7 downto 0) := (others => '0');
-
- -- UART physical pins
- uart_tx : out std_logic;
- uart_rx : in std_logic
- );
-end entity PIC;
-
-architecture rtl of PIC is
- signal W : std_logic_vector(7 downto 0) := (others => '0');
-
- signal alu_operation : alu_op;
- signal alu_result : std_logic_vector(7 downto 0);
- signal alu_skip : std_logic;
-
- signal mem_q : std_logic_vector(7 downto 0);
- signal mem_qstatus : std_logic_vector(2 downto 0);
- signal mem_we : std_logic;
- signal mem_re : std_logic;
-
- signal bit_select : std_logic_vector(2 downto 0);
- signal addr : std_logic_vector(6 downto 0);
- signal sm_data : std_logic_vector(7 downto 0);
- signal sm_pc : std_logic_vector(12 downto 0);
- signal we_w : std_logic;
- signal instr_ret : std_logic;
- signal alu_status : std_logic_vector(2 downto 0);
-
- signal use_literal : std_logic;
- signal we_status : std_logic;
- signal b_operand : std_logic_vector(7 downto 0);
-
- signal stack_push : std_logic;
- signal stack_pop : std_logic;
- signal stack_din : std_logic_vector(12 downto 0);
- signal stack_dout : std_logic_vector(12 downto 0);
-
- -- UART <-> dpram bridge signals
- signal uart_tx_byte : std_logic_vector(7 downto 0);
- signal uart_tx_send : std_logic;
- signal uart_tx_done : std_logic;
- signal uart_rx_byte : std_logic_vector(7 downto 0);
- signal uart_rx_rd_en : std_logic;
- signal uart_rx_empty : std_logic;
- signal uart_rx_full : std_logic;
-
-begin
-
- work_reg <= W;
- program_counter <= sm_pc;
- instruction_return <= instr_ret;
- status <= alu_status;
-
- b_operand_select : process(use_literal, sm_data, mem_q)
- begin
- if use_literal = '1' then
- b_operand <= sm_data;
- else
- b_operand <= mem_q;
- end if;
- end process;
-
- w_reg : process(clk)
- begin
- if rising_edge(clk) then
- if we_w = '1' then
- W <= alu_result;
- end if;
- end if;
- end process w_reg;
-
- sm : entity work.state_machine(rtl)
- port map (
- clk => clk,
- opcode => opcode,
- reset => reset,
- op => alu_operation,
- we_mem => mem_we,
- re_mem => mem_re,
- we_w => we_w,
- instr_ret => instr_ret,
- bit_select => bit_select,
- data => sm_data,
- pc => sm_pc,
- addr => addr,
- use_literal => use_literal,
- we_status => we_status,
- stack_push => stack_push,
- stack_pop => stack_pop,
- stack_din => stack_din,
- stack_dout => stack_dout,
- alu_skip => alu_skip,
- alu_result => alu_result
- );
-
- alu : entity work.alu(rtl)
- port map (
- a => W,
- b => b_operand,
- op => alu_operation,
- bit_select => bit_select,
- status_in => mem_qstatus,
- result => alu_result,
- status => alu_status,
- skip => alu_skip
- );
-
- stk : entity work.stack(rtl)
- port map (
- clk => clk,
- reset => reset,
- push => stack_push,
- pop => stack_pop,
- din => stack_din,
- dout => stack_dout
- );
-
- mem : entity work.dpram(rtl)
- generic map (DEPTH => 128)
- port map (
- clk => clk,
- we => mem_we,
- re => mem_re,
- d => alu_result,
- d_status => "00000" & alu_status,
- addr => addr,
- q => mem_q,
- q_status => mem_qstatus,
- port_a => port_a,
- port_b => port_b,
- we_status => we_status,
- uart_tx_byte => uart_tx_byte,
- uart_tx_send => uart_tx_send,
- uart_tx_done => uart_tx_done,
- uart_rx_byte => uart_rx_byte,
- uart_rx_rd_en => uart_rx_rd_en,
- uart_rx_empty => uart_rx_empty,
- uart_rx_full => uart_rx_full
- );
-
- uart_inst : entity work.uart
- generic map (
- CLK_FREQ => CLK_FREQ,
- BAUD_RATE => BAUD_RATE,
- CLKS_PER_BIT => CLK_FREQ / BAUD_RATE
- )
- port map (
- clk => clk,
- tx_should_send => uart_tx_send,
- byte_in => uart_tx_byte,
- tx_done => uart_tx_done,
- baud_tick => open,
- uart_tx => uart_tx,
- uart_rx => uart_rx,
- rd_en => uart_rx_rd_en,
- rx_data => uart_rx_byte,
- rx_empty => uart_rx_empty,
- rx_full => uart_rx_full
- );
-
-end architecture rtl;
diff --git a/PIC/blink.c b/PIC/blink.c
deleted file mode 100644
index 6789b0a..0000000
--- a/PIC/blink.c
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <pic16f84a.h>
-
-typedef unsigned char uint8_t;
-
-// Global volatile so sdcc cannot optimise the delay loops away.
-static volatile uint8_t _d0, _d1, _d2;
-
-// Busy-wait ~500 ms at 50 MHz.
-// 200 × 256 × 256 = 13 107 200 inner iterations.
-// Each iteration ≈ 3 uint8_t instructions × 20 ns = 60 ns.
-// Total ≈ 786 ms (tune outer count _d0 < N to taste).
-static void delay(void) {
- _d0 = 0;
- do {
- _d1 = 0;
- do {
- _d2 = 0;
- do { _d2++; } while (_d2 != 0);
- } while (++_d1 != 30);
- _d0++;
- } while (_d0 != 116);
-}
-
-void main(void) {
- // port_b(0) drives activity_led at E8 on the Tang Primer 25K.
- // port_a(0) drives led at L6. Both ports are always outputs in this CPU.
- while (1) {
- PORTB = 0x01; // activity_led (E8) on
- PORTA = 0x01; // led (L6) on
- delay();
- PORTB = 0x00; // activity_led (E8) off
- PORTA = 0x00; // led (L6) off
- delay();
- }
-}
diff --git a/PIC/common.vhd b/PIC/common.vhd
deleted file mode 100644
index c986ec5..0000000
--- a/PIC/common.vhd
+++ /dev/null
@@ -1,10 +0,0 @@
-package alu_types is
- type alu_op is (ADDWF, ANDWF, ADDLW, ANDLW, BCF, BTFSC,
- BSF, BTFSS, CLRF, CLRW, COMF, DECF,
- DECFSZ, INCF, INCFSZ, IORLW, MOVF, MOVWF, CALL,
- GOTO, MOVLW, RETLW, RETUR, IORWF, NOP,
- RLF, RRF, SUBLW, SUBWF, SWAPF, XORLW, XORWF);
-
- -- Status register bits: Z=2, DC=1, C=0
- type alu_flag is (FLAG_Z, FLAG_DC, FLAG_C);
-end package;
diff --git a/PIC/decoder.vhd b/PIC/decoder.vhd
deleted file mode 100644
index 5a1eb2c..0000000
--- a/PIC/decoder.vhd
+++ /dev/null
@@ -1,155 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use work.alu_types.all;
-
-package decoder is
- type instruction_class_t is (
- BIT_OP,
- BYTE_OP,
- LITERAL_OP,
- CONTROL_OP,
- UNKNOWN
- );
-
- type instruction_t is record
- class : instruction_class_t;
- op : alu_op;
- f : std_logic_vector(6 downto 0);
- b : std_logic_vector(2 downto 0);
- d : std_logic;
- k : std_logic_vector(10 downto 0);
- end record;
-
- pure function instruction_get_class(opc : std_logic_vector(13 downto 0)) return instruction_class_t;
-
- pure function instruction_get_operation(
- opc : std_logic_vector(13 downto 0);
- instr_class : instruction_class_t)
- return alu_op;
-
- pure function instruction_decode(opc : std_logic_vector(13 downto 0)) return instruction_t;
-
-end package;
-
-package body decoder is
-
- pure function instruction_decode(opc : std_logic_vector(13 downto 0))
- return instruction_t is
- variable instr : instruction_t;
- begin
- instr.class := instruction_get_class(opc);
- instr.op := instruction_get_operation(opc, instr.class);
-
- instr.f := (others => '0');
- instr.b := (others => '0');
- instr.d := '0';
- instr.k := (others => '0');
-
- case instr.class is
- when BIT_OP =>
- instr.b := opc(9 downto 7);
- instr.f := opc(6 downto 0);
- when BYTE_OP =>
- instr.f := opc(6 downto 0);
- instr.d := opc(7);
- when LITERAL_OP | CONTROL_OP =>
- instr.k := opc(10 downto 0);
- when UNKNOWN =>
- end case;
-
- return instr;
- end function;
-
- pure function instruction_get_class(opc : std_logic_vector(13 downto 0))
- return instruction_class_t is
- begin
- -- RETURN (0x0008) has bits[13:12]="00" but must be treated as LITERAL_OP
- if opc = "00000000001000" then return LITERAL_OP; end if;
- case opc(13 downto 12) is
- -- byte-oriented file-register operations
- when "00" =>
- return BYTE_OP;
- when "01" =>
- return BIT_OP;
- when "10" =>
- return CONTROL_OP;
- when "11" =>
- return LITERAL_OP;
- when others =>
- return UNKNOWN;
- end case;
- end function;
-
- pure function instruction_get_operation(
- opc : std_logic_vector(13 downto 0);
- instr_class : instruction_class_t)
- return alu_op is
- begin
- case instr_class is
-
- when BYTE_OP =>
- case opc(11 downto 8) is
- when "0000" =>
- if opc(7) = '1' then return MOVWF;
- else return NOP;
- end if;
- when "0001" =>
- if opc(7) = '1' then return CLRF;
- else return CLRW;
- end if;
- when "0010" => return SUBWF;
- when "0011" => return DECF;
- when "0100" => return IORWF;
- when "0101" => return ANDWF;
- when "0110" => return XORWF;
- when "0111" => return ADDWF;
- when "1000" => return MOVF;
- when "1001" => return COMF;
- when "1010" => return INCF;
- when "1011" => return DECFSZ;
- when "1100" => return RRF;
- when "1101" => return RLF;
- when "1110" => return SWAPF;
- when "1111" => return INCFSZ;
- when others => return NOP;
- end case;
-
- when BIT_OP =>
- case opc(11 downto 10) is
- when "00" => return BCF;
- when "01" => return BSF;
- when "10" => return BTFSC;
- when "11" => return BTFSS;
- when others => return NOP;
- end case;
-
- when CONTROL_OP =>
- if opc(11) = '1' then return GOTO;
- else return CALL;
- end if;
-
- when LITERAL_OP =>
- -- fixed full-word patterns first (fall inside 00xx space)
- -- if opc(11 downto 0) = "000000000001" then return RETFIE;
- if opc(11 downto 0) = "000000001000" then return RETUR;
- -- elsif opc(11 downto 0) = "000000000011" then return SLEEP;
- -- elsif opc(11 downto 0) = "000000000100" then return CLRWDT;
- else
- case? opc(11 downto 8) is
- when "00--" => return MOVLW;
- when "01--" => return RETLW;
- when "1000" => return IORLW;
- when "1001" => return ANDLW;
- when "1010" => return XORLW;
- when "110-" => return SUBLW;
- when "111-" => return ADDLW;
- when others => return NOP;
- end case?;
- end if;
-
- when others => return NOP;
-
- end case;
- end function;
-
-end decoder;
diff --git a/PIC/dpram.vhd b/PIC/dpram.vhd
deleted file mode 100644
index 44d7adf..0000000
--- a/PIC/dpram.vhd
+++ /dev/null
@@ -1,110 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- Data memory with UART memory-mapped registers.
--- Addresses 0x70-0x72 are used (unimplemented in real PIC16F84A, no header conflict):
--- 0x70 UART_TX write: send byte (held until tx_done)
--- 0x71 UART_RX read: current FIFO head (FWFT), pulses rd_en to pop
--- 0x72 UART_STATUS read: "00000" & rx_full & rx_empty & tx_busy
-
-entity dpram is
- generic (DEPTH : positive := 128);
- port (
- clk : in std_logic;
- we : in std_logic;
- re : in std_logic;
- d : in std_logic_vector(7 downto 0);
- d_status : in std_logic_vector(7 downto 0);
- addr : in std_logic_vector(6 downto 0);
- q : out std_logic_vector(7 downto 0);
- q_status : out std_logic_vector(2 downto 0);
-
- port_a : out std_logic_vector(7 downto 0);
- port_b : out std_logic_vector(7 downto 0);
- we_status : in std_logic;
-
- -- UART interface
- uart_tx_byte : out std_logic_vector(7 downto 0) := (others => '0');
- uart_tx_send : out std_logic := '0';
- uart_tx_done : in std_logic;
- uart_rx_byte : in std_logic_vector(7 downto 0);
- uart_rx_rd_en : out std_logic := '0';
- uart_rx_empty : in std_logic;
- uart_rx_full : in std_logic
- );
-end entity dpram;
-
-architecture rtl of dpram is
- type mem_t is
- array (0 to DEPTH - 1)
- of std_logic_vector(7 downto 0);
-
- signal mem : mem_t := (others => (others => '0'));
- signal uart_tx_pending : std_logic := '0';
-
-begin
- -- STATUS output is combinatorial
- q_status <= mem(16#03#)(2 downto 0);
-
- port_a <= mem(16#05#);
- port_b <= mem(16#06#);
-
- -- tx_send is high while a transmission is in progress
- uart_tx_send <= uart_tx_pending;
-
- -- SR: set when CPU writes to 0x08, clear when UART asserts tx_done
- tx_ctrl : process(clk)
- begin
- if rising_edge(clk) then
- if we = '1' and addr = "1110000" then -- 0x70 UART_TX
- uart_tx_byte <= d;
- uart_tx_pending <= '1';
- elsif uart_tx_done = '1' then
- uart_tx_pending <= '0';
- end if;
- end if;
- end process tx_ctrl;
-
- read : process(clk)
- begin
- if rising_edge(clk) then
- uart_rx_rd_en <= '0'; -- default: no pop
- if re = '1' then
- if addr = "1110001" then -- 0x71 UART_RX
- q <= uart_rx_byte; -- FWFT head, valid combinatorially
- if uart_rx_empty = '0' then
- uart_rx_rd_en <= '1'; -- advance FIFO pointer
- end if;
- elsif addr = "1110010" then -- 0x72 UART_STATUS
- q <= "00000" & uart_rx_full & uart_rx_empty & uart_tx_pending;
- else
- q <= mem(to_integer(unsigned(addr)));
- end if;
- end if;
- end if;
- end process read;
-
- write : process(clk)
- begin
- if rising_edge(clk) then
- if we_status = '1' then
- mem(16#03#) <= d_status;
- end if;
- if we = '1' then
- if addr = "0000011" then -- 0x03 STATUS: direct write
- mem(16#03#) <= d;
- elsif addr = "1110000" or -- 0x70 UART_TX
- addr = "1110001" or -- 0x71 UART_RX (read-only but handled gracefully)
- addr = "1110010" then -- 0x72 UART_STATUS (read-only)
- -- UART-mapped addresses: don't write to RAM; still update STATUS
- mem(16#03#) <= d_status;
- else
- mem(16#03#) <= d_status;
- mem(to_integer(unsigned(addr))) <= d;
- end if;
- end if;
- end if;
- end process write;
-
-end architecture rtl;
diff --git a/PIC/fifo.vhd b/PIC/fifo.vhd
deleted file mode 100644
index 9dd8523..0000000
--- a/PIC/fifo.vhd
+++ /dev/null
@@ -1,75 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- First-word fall-through (FWFT) FIFO.
--- dout always presents the current head combinatorially (no read latency).
--- rd_en advances the read pointer; the next head is visible on the same cycle.
--- DEPTH must be a power of 2; ADDR_BITS = log2(DEPTH).
-
-entity fifo is
- generic (
- DEPTH : positive := 16;
- ADDR_BITS : positive := 4;
- WIDTH : positive := 8
- );
- port (
- clk : in std_logic;
- wr_en : in std_logic;
- rd_en : in std_logic;
- din : in std_logic_vector(WIDTH - 1 downto 0);
- dout : out std_logic_vector(WIDTH - 1 downto 0);
- full : out std_logic;
- empty : out std_logic
- );
-end entity fifo;
-
-architecture rtl of fifo is
-
- -- MSB pointer trick: pointers are ADDR_BITS+1 wide.
- -- Empty: read_ptr = write_ptr
- -- Full: (read_ptr XOR write_ptr) = DEPTH (MSBs differ, lower bits equal)
- signal read_ptr : unsigned(ADDR_BITS downto 0) := (others => '0');
- signal write_ptr : unsigned(ADDR_BITS downto 0) := (others => '0');
-
- type mem_t is
- array (0 to DEPTH - 1)
- of std_logic_vector(WIDTH - 1 downto 0);
-
- signal mem : mem_t := (others => (others => '0'));
-
- signal empty_i : std_logic;
- signal full_i : std_logic;
-
-begin
-
- empty_i <= '1' when read_ptr = write_ptr else '0';
- full_i <= '1' when (read_ptr xor write_ptr) = to_unsigned(DEPTH, ADDR_BITS + 1)
- else '0';
-
- empty <= empty_i;
- full <= full_i;
-
- -- FWFT: head is always visible without asserting rd_en
- dout <= mem(to_integer(read_ptr(ADDR_BITS - 1 downto 0)));
-
- enqueue : process(clk)
- begin
- if rising_edge(clk) then
- if wr_en = '1' and full_i = '0' then
- mem(to_integer(write_ptr(ADDR_BITS - 1 downto 0))) <= din;
- write_ptr <= write_ptr + 1;
- end if;
- end if;
- end process enqueue;
-
- dequeue : process(clk)
- begin
- if rising_edge(clk) then
- if rd_en = '1' and empty_i = '0' then
- read_ptr <= read_ptr + 1;
- end if;
- end if;
- end process dequeue;
-
-end architecture rtl;
diff --git a/PIC/hdl-prj.json b/PIC/hdl-prj.json
deleted file mode 100644
index b557c2b..0000000
--- a/PIC/hdl-prj.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "options": {
- "ghdl_analysis": [
- "-fexplicit",
- "--std=08"
- ]
- },
- "files": [
- { "file": "common.vhd", "language": "vhdl" },
- { "file": "decoder.vhd", "language": "vhdl" },
- { "file": "hexfile_reader.vhd", "language": "vhdl" },
- { "file": "fifo.vhd", "language": "vhdl" },
- { "file": "uart.vhd", "language": "vhdl" },
- { "file": "ALU.vhd", "language": "vhdl" },
- { "file": "stack.vhd", "language": "vhdl" },
- { "file": "dpram.vhd", "language": "vhdl" },
- { "file": "state_machine.vhd", "language": "vhdl" },
- { "file": "PIC.vhd", "language": "vhdl" },
- { "file": "prog_rom.vhd", "language": "vhdl" },
- { "file": "pic_top.vhd", "language": "vhdl" },
- { "file": "tb_stack.vhd", "language": "vhdl" },
- { "file": "tb_pic.vhd", "language": "vhdl" }
- ]
-}
diff --git a/PIC/hexfile_reader.vhd b/PIC/hexfile_reader.vhd
deleted file mode 100644
index 143a264..0000000
--- a/PIC/hexfile_reader.vhd
+++ /dev/null
@@ -1,342 +0,0 @@
--------------------------------------------------------------------------------
---Usage of the reader:
---
---CONSTANT ihex_data : STRING :=
---"/home/pro/autosub/erkka/digital/matlab/esim.HEX;
---VARIABLE memory : program_array := (OTHERS => (OTHERS => '0'));
---
---read_ihex_file(ihex_data, memory);
---
--- If some constant definitions are missing, try to figure them out.
--- If you can't contact Erkka Laulainen, elaulain@ecdl.tkk.fi, room I313A
--------------------------------------------------------------------------------
-
-LIBRARY ieee;
-USE ieee.std_logic_1164.ALL;
---USE ieee.std_logic_arith.ALL;
-USE ieee.numeric_std.ALL;
-USE std.textio.ALL;
-USE ieee.std_logic_textio.ALL;
-USE ieee.std_logic_misc.ALL;
-
-
-PACKAGE read_intel_hex_pack IS
- CONSTANT debug : BOOLEAN := true;
-
- ------------------------------------------------------------------------------
- ----- Design Parameters -----------------------------------------------------
- ------------------------------------------------------------------------------
-
- CONSTANT Inst_bits : INTEGER := 14;
- CONSTANT data_bits : INTEGER := 8;
- CONSTANT inst_mem_size : INTEGER := 1024;
- TYPE program_array IS ARRAY (0 TO inst_mem_size-1) OF STD_LOGIC_VECTOR(Inst_bits-1 DOWNTO 0);
-
- ------------------------------------------------------------------------------
- ----- Reset Values -----------------------------------------------------------
- ------------------------------------------------------------------------------
-
--- CONSTANT W_RESET : STD_ULOGIC_VECTOR(data_bits-1 DOWNTO 0) := "XXXXXXXX";
--- CONSTANT INDF_RESET : STD_ULOGIC_VECTOR(data_bits-1 DOWNTO 0) := "--------";
--- CONSTANT TMR0_RESET : STD_ULOGIC_VECTOR(data_bits-1 DOWNTO 0) := "XXXXXXXX";
--- CONSTANT PCL_RESET : STD_ULOGIC_VECTOR(data_bits-1 DOWNTO 0) := "00000000";
--- CONSTANT STATUS_RESET : STD_ULOGIC_VECTOR(data_bits-1 DOWNTO 0) := "00011XXX";
--- CONSTANT FSR_RESET : STD_ULOGIC_VECTOR(data_bits-1 DOWNTO 0) := "XXXXXXXX";
--- CONSTANT PORTA_RESET : STD_ULOGIC_VECTOR(4 DOWNTO 0) := "XXXXX";
--- CONSTANT PORTB_RESET : STD_ULOGIC_VECTOR(data_bits-1 DOWNTO 0) := "XXXXXXXX";
--- CONSTANT EEDATA_RESET : STD_ULOGIC_VECTOR(data_bits-1 DOWNTO 0) := "XXXXXXXX";
--- CONSTANT EEADR_RESET : STD_ULOGIC_VECTOR(data_bits-1 DOWNTO 0) := "XXXXXXXX";
--- CONSTANT PCLATH_RESET : STD_ULOGIC_VECTOR(4 DOWNTO 0) := "00000";
--- CONSTANT INTCON_RESET : STD_ULOGIC_VECTOR(data_bits-1 DOWNTO 0) := "0000000X";
--- CONSTANT OPTION_REG_RESET : STD_ULOGIC_VECTOR(data_bits-1 DOWNTO 0) := "11111111";
--- CONSTANT TRISA_RESET : STD_ULOGIC_VECTOR(4 DOWNTO 0) := "11111";
--- CONSTANT TRISB_RESET : STD_ULOGIC_VECTOR(data_bits-1 DOWNTO 0) := "11111111";
--- CONSTANT EECON1_RESET : STD_ULOGIC_VECTOR(4 DOWNTO 0) := "0X000";
--- CONSTANT EECON2_RESET : STD_ULOGIC_VECTOR(data_bits-1 DOWNTO 0) := "--------";
-
- ------------------------------------------------------------------------------
- ----- Operations Codes -------------------------------------------------------
- ------------------------------------------------------------------------------
-
- ----- BYTE-ORIENTED FILE REGISTER OPERATIONS ---------------------------------
-
--- CONSTANT ADDWF : STD_ULOGIC_VECTOR := "000111--------";
--- CONSTANT ANDWF : STD_ULOGIC_VECTOR := "000101--------";
--- CONSTANT CLRF : STD_ULOGIC_VECTOR := "0000011-------";
--- CONSTANT CLRW : STD_ULOGIC_VECTOR := "0000010-------";
--- CONSTANT COMF : STD_ULOGIC_VECTOR := "001001--------";
--- CONSTANT DECF : STD_ULOGIC_VECTOR := "000011--------";
--- CONSTANT DECFSZ : STD_ULOGIC_VECTOR := "001011--------";
--- CONSTANT INCF : STD_ULOGIC_VECTOR := "001010--------";
--- CONSTANT INCFSZ : STD_ULOGIC_VECTOR := "001111--------";
--- CONSTANT IORWF : STD_ULOGIC_VECTOR := "000100--------";
--- CONSTANT MOVF : STD_ULOGIC_VECTOR := "001000--------";
--- CONSTANT MOVWF : STD_ULOGIC_VECTOR := "0000001-------";
--- CONSTANT NOP : STD_ULOGIC_VECTOR := "0000000--00000";
--- CONSTANT RLF : STD_ULOGIC_VECTOR := "001101--------";
--- CONSTANT RRF : STD_ULOGIC_VECTOR := "001100--------";
--- CONSTANT SUBWF : STD_ULOGIC_VECTOR := "000010--------";
--- CONSTANT SWAPF : STD_ULOGIC_VECTOR := "001110--------";
--- CONSTANT XORWF : STD_ULOGIC_VECTOR := "000110--------";
-
- ----- BIT-ORIENTED FILE REGISTER OPERATIONS ----------------------------------
-
--- CONSTANT BCF : STD_ULOGIC_VECTOR := "0100----------";
--- CONSTANT BSF : STD_ULOGIC_VECTOR := "0101----------";
--- CONSTANT BTFSC : STD_ULOGIC_VECTOR := "0110----------";
--- CONSTANT BTFSS : STD_ULOGIC_VECTOR := "0111----------";
-
- ----- LITERAL AND CONTROL OPERATIONS -----------------------------------------
-
--- CONSTANT ADDLW : STD_ULOGIC_VECTOR := "11111---------";
--- CONSTANT ANDLW : STD_ULOGIC_VECTOR := "111001--------";
--- CONSTANT CALL : STD_ULOGIC_VECTOR := "100-----------";
--- CONSTANT CLRWDT : STD_ULOGIC_VECTOR := "00000001100100";
--- CONSTANT GOTO : STD_ULOGIC_VECTOR := "101-----------";
--- CONSTANT IORLW : STD_ULOGIC_VECTOR := "111000--------";
--- CONSTANT MOVLW : STD_ULOGIC_VECTOR := "1100----------";
--- CONSTANT RETFIE : STD_ULOGIC_VECTOR := "00000000001001";
--- CONSTANT RETLW : STD_ULOGIC_VECTOR := "1101----------";
--- CONSTANT RET : STD_ULOGIC_VECTOR := "00000000001000";
--- CONSTANT SLEEP : STD_ULOGIC_VECTOR := "00000001100011";
--- CONSTANT SUBLW : STD_ULOGIC_VECTOR := "11110---------";
--- CONSTANT XORLW : STD_ULOGIC_VECTOR := "111010--------";
-
- ------------------------------------------------------------------------------
- ----- Special Function Register Address --------------------------------------
- ------------------------------------------------------------------------------
-
--- CONSTANT INDF_ADR : STD_ULOGIC_VECTOR := "-0000000";
--- CONSTANT TMR0_ADR : STD_ULOGIC_VECTOR := "00000001";
--- CONSTANT PCL_ADR : STD_ULOGIC_VECTOR := "-0000010";
--- CONSTANT STATUS_ADR : STD_ULOGIC_VECTOR := "-0000011";
--- CONSTANT FSR_ADR : STD_ULOGIC_VECTOR := "-0000100";
--- CONSTANT PORTA_ADR : STD_ULOGIC_VECTOR := "00000101";
--- CONSTANT PORTB_ADR : STD_ULOGIC_VECTOR := "00000110";
--- CONSTANT EEDATA_ADR : STD_ULOGIC_VECTOR := "00001000";
--- CONSTANT EEARD_ADR : STD_ULOGIC_VECTOR := "00001001";
--- CONSTANT PCLATH_ADR : STD_ULOGIC_VECTOR := "-0001010";
--- CONSTANT INTCON_ADR : STD_ULOGIC_VECTOR := "-0001011";
--- CONSTANT OPTION_ADR : STD_ULOGIC_VECTOR := "10000001";
--- CONSTANT TRISA_ADR : STD_ULOGIC_VECTOR := "10000101";
--- CONSTANT TRISB_ADR : STD_ULOGIC_VECTOR := "10000110";
--- CONSTANT EECON1_ADR : STD_ULOGIC_VECTOR := "10001000";
--- CONSTANT EECON2_ADR : STD_ULOGIC_VECTOR := "10001001";
-
- ------------------------------------------------------------------------------
- ----- STATUS Register Constants ----------------------------------------------
- ------------------------------------------------------------------------------
-
--- CONSTANT RP0_BIT : INTEGER := 5;
--- CONSTANT TO_BIT : INTEGER := 4;
--- CONSTANT PD_BIT : INTEGER := 3;
--- CONSTANT Z_BIT : INTEGER := 2;
--- CONSTANT DC_BIT : INTEGER := 1;
--- CONSTANT CARRY_BIT : INTEGER := 0;
-
- ------------------------------------------------------------------------------
- ----- INTCON Register Constants ----------------------------------------------
- ------------------------------------------------------------------------------
-
--- CONSTANT GIE_BIT : INTEGER := 7;
--- CONSTANT EEIE_BIT : INTEGER := 6;
--- CONSTANT T0IE_BIT : INTEGER := 5;
--- CONSTANT INTE_BIT : INTEGER := 4;
--- CONSTANT RBIE_BIT : INTEGER := 3;
--- CONSTANT T0IF_BIT : INTEGER := 2;
--- CONSTANT INTF_BIT : INTEGER := 1;
--- CONSTANT RBIF_BIT : INTEGER := 0;
-
- ------------------------------------------------------------------------------
- ----- OPTION Register Constants ----------------------------------------------
- ------------------------------------------------------------------------------
-
--- CONSTANT RBPU_BIT : INTEGER := 7;
--- CONSTANT INTEDG_BIT : INTEGER := 6;
--- CONSTANT T0CS_BIT : INTEGER := 5;
--- CONSTANT T0SE_BIT : INTEGER := 4;
--- CONSTANT PSA_BIT : INTEGER := 3;
--- CONSTANT PS2_BIT : INTEGER := 2;
--- CONSTANT PS1_BIT : INTEGER := 1;
--- CONSTANT PS0_BIT : INTEGER := 0;
-
- PROCEDURE read_ihex_file (program_name : IN STRING; memory : OUT program_array);
-
-END PACKAGE read_intel_hex_pack;
-
-PACKAGE BODY read_intel_hex_pack IS
-
- PROCEDURE str_to_hex (str : IN STRING; result : INOUT NATURAL) IS
- VARIABLE ch : CHARACTER;
- BEGIN
- result := 0;
- FOR i IN 1 TO str'LENGTH LOOP
- ch := str(i);
- IF '0' <= ch and ch <= '9' THEN
- result := result*16 + character'pos(ch) - character'pos('0');
- ELSIF 'A' <= ch and ch <= 'F' THEN
- result := result*16 + character'pos(ch) - character'pos('A') + 10;
- ELSIF 'a' <= ch and ch <= 'f' THEN
- result := result*16 + character'pos(ch) - character'pos('a') + 10;
- ELSE
- -- ASSERT 1; REPORT "FAILURE: str_to_hex: Non-hex character encountered!"; SEVERITY FAILURE;
- END IF;
- END LOOP;
- END str_to_hex;
-
- PROCEDURE read_line_header (L : INOUT LINE; byte_count : INOUT INTEGER; address : INOUT INTEGER; record_type : INOUT INTEGER) IS
- VARIABLE byte_count_str : STRING(1 to 2);
- VARIABLE address_str : STRING(1 to 4);
- VARIABLE record_type_str : STRING(1 to 2);
- BEGIN
- -- Read byte count
- FOR i IN 1 TO 2 LOOP
- READ(L, byte_count_str(i));
- END LOOP;
- str_to_hex(byte_count_str, byte_count);
- -- ASSERT debug; REPORT "DEBUG read_line_header: byte count is" & byte_count; SEVERITY NOTE;
- -- Read address
- FOR i IN 1 TO 4 LOOP
- READ(L, address_str(i));
- END LOOP;
- str_to_hex(address_str, address);
- -- ASSERT debug; REPORT "DEBUG read_line_header: address is" & address; SEVERITY NOTE;
- -- Read record type
- FOR i IN 1 TO 2 LOOP
- READ(L, record_type_str(i));
- END LOOP;
- str_to_hex(record_type_str, record_type);
- -- ASSERT debug; REPORT "DEBUG read_line_header: record type is" & recod_type; SEVERITY NOTE;
- END read_line_header;
-
-
- PROCEDURE read_instruction (L : INOUT LINE; instruction_hex : INOUT INTEGER) IS
- VARIABLE instruction_str : STRING(1 TO 4);
- VARIABLE instruction_str_tmp : STRING(1 TO 4);
- VARIABLE ch : CHARACTER;
- BEGIN
- -- L pointer is pointing to the instruction we want to read
- -- Thus, no need to update pointer
-
- -- Read instruction
- FOR i IN 1 TO 4 LOOP
- READ(L, instruction_str(i));
- END LOOP;
-
- -- Swap 2 lower and 2 higher byte: 1234 -> 3412
- instruction_str_tmp(1 TO 2) := instruction_str(1 to 2);
- instruction_str(1 TO 2) := instruction_str(3 to 4);
- instruction_str(3 TO 4) := instruction_str_tmp(1 TO 2);
- str_to_hex(instruction_str, instruction_hex);
- -- ASSERT debug; REPORT "DEBUG read_instruction: instruction " & instruction_no & "is " & instruction_hex; SEVERITY NOTE;
- END read_instruction;
-
-
- PROCEDURE read_ihex_file (program_name : IN STRING; memory : OUT program_array) IS
- FILE program : TEXT open READ_MODE is program_name;
- VARIABLE L : LINE;
- VARIABLE byte_count : INTEGER := 0;
- VARIABLE address : NATURAL := 0;
- VARIABLE record_type : INTEGER := 0;
- -- VARIABLE base_address : INTEGER := 0;
- -- VARIABLE current_address : INTEGER := 0;
- VARIABLE instruction : INTEGER := 0;
- VARIABLE ch : CHARACTER;
- BEGIN
- WHILE NOT ENDFILE(program) LOOP
- byte_count := 0;
- address := 0;
- record_type := 0;
-
- READLINE(program, L);
-
- -- Move line pointer over semicolon
- READ(L, ch);
- -- Read first byte count, address and record type on the line
- read_line_header(L, byte_count, address, record_type);
-
- CASE record_type IS
-
- WHEN 0 => -- Data record
- FOR i IN 1 TO byte_count/2 LOOP -- toimiiko jos byte count == 1?
- read_instruction(L, instruction);
- memory(address/2+i-1) := STD_LOGIC_VECTOR(to_unsigned(instruction, Inst_bits)); -- XXX
- END LOOP;
-
- WHEN 1 => -- EOF record
- NULL;
-
- WHEN 2 => -- Extended Segment Address Record
- -- ASSERT 1; REPORT "Extended Segment Address record type 0x02 not implemented"; SEVERITY FAILURE;
-
- WHEN 3 => -- Start Segment Address Record
- -- ASSERT 1; REPORT "Start Segment Address record type 0x03 not implemented"; SEVERITY FAILURE;
-
- WHEN 4 => --
- -- FOR i IN 0 TO 1 LOOP
- read_instruction(L, instruction);
- -- ASSERT (instruction /= 0); REPORT "Extended Linear Address Record not zero";SEVERITY FAILURE;
- -- END LOOP;
-
- WHEN 5 => -- Start Linear Address Record
- -- ASSERT 1; REPORT "Start Linear Address record type 0x05 not implemented"; SEVERITY FAILURE;
-
- WHEN OTHERS =>
- -- ASSERT 1; REPORT "Invalid Intel HEX format record type"; SEVERITY FAILURE;
-
- END CASE;
-
- END LOOP; -- Read file
- END PROCEDURE read_ihex_file;
-
-END PACKAGE BODY read_intel_hex_pack;
-
---PROCEDURE read_ihex_file (program_name : IN STRING; memory : OUT program_array) IS -- pitaako maaritella tyyppi muualla??
--- FILE program : TEXT IS IN "/home/pro/autosub/erkka/digital/modelsim/" & program_name; -- saako program namen?
--- TYPE program_array IS ARRAY (0 TO inst_mem_size-1) OF STD_LOGIC_VECTOR(Inst_bits-1 DOWNTO 0);
--- VARIABLE L : LINE;
--- VARIABLE byte_count : INTEGER := 0;
--- VARIABLE address : INTEGER := 0;
--- VARIABLE record_type : INTEGER := 0;
--- VARIABLE base_address : INTEGER := 0;
--- -- VARIABLE current_address : INTEGER := 0;
--- VARIABLE instruction : INTEGER := 0;
---BEGIN
--- WHILE NOT ENDFILE(program) LOOP
--- READLINE(program, L);
--- read_line_header(L, byte_count, address, record_type);
---
--- CASE record_type IS
---
--- WHEN X"00" => -- Data record
--- FOR i IN 0 TO byte_count-1 LOOP -- toimiiko jos byte count == 1?
--- read_instruction(L, i, instruction);
--- program_array(address/2 + i) := instruction; -- tsekkaa
--- END LOOP;
---
--- WHEN X"01" => -- EOF record
--- NULL;
---
--- WHEN X"02" => -- Extended Segment Address Record
--- ASSERT 1; REPORT "Extended Segment Address record type 0x02 not implemented"; SEVERITY FAILURE;
---
--- WHEN X"03" => -- Start Segment Address Record
--- ASSERT 1; REPORT "Start Segment Address record type 0x03 not implemented"; SEVERITY FAILURE;
---
--- WHEN X"04" => --
--- FOR i IN 0 TO 1 LOOP
--- read_instruction(L, i, instruction);
--- ASSERT (instruction /= 0); REPORT "Extended Linear Address Record not zero";SEVERITY FAILURE;
--- END LOOP;
---
--- WHEN X"05" => -- Start Linear Address Record
--- ASSERT 1; REPORT "Start Linear Address record type 0x05 not implemented"; SEVERITY FAILURE;
---
--- WHEN OTHERS =>
--- ASSERT 1; REPORT "Invalid Intel HEX format record type"; SEVERITY FAILURE;
---
--- END CASE;
---
--- END LOOP; -- Read file
---END PROCESS read_ihex_file;
---
diff --git a/PIC/pic_top.vhd b/PIC/pic_top.vhd
deleted file mode 100644
index f0cb4bd..0000000
--- a/PIC/pic_top.vhd
+++ /dev/null
@@ -1,81 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- FPGA top-level for the Tang Primer 25K (GW5A-LV25MG121).
--- Pin assignments live in primer25k.cst.
--- The prog_rom entity holds the compiled program; swap its 'rom' constant
--- to deploy a new program without changing anything else.
-
-entity pic_top is
- port (
- clk : in std_logic; -- 50 MHz board clock (E2)
- reset_btn : in std_logic; -- H11 user button, active high, pulled down
- uart_rx : in std_logic; -- B3
- uart_tx : out std_logic; -- C3
- activity_led : out std_logic; -- E8 — driven by port_b(0)
- led : out std_logic -- L6 — driven by port_a(0), blink from C
- );
-end entity pic_top;
-
-architecture rtl of pic_top is
-
- constant CLK_FREQ : positive := 50_000_000;
-
- -- Power-on reset: hold reset for 64 cycles then release
- signal rst_cnt : unsigned(5 downto 0) := (others => '0');
- signal reset : std_logic := '1';
-
- signal pc : std_logic_vector(12 downto 0);
- signal opcode : std_logic_vector(13 downto 0);
- signal port_a : std_logic_vector(7 downto 0);
- signal port_b : std_logic_vector(7 downto 0);
- signal work_reg : std_logic_vector(7 downto 0);
- signal status : std_logic_vector(2 downto 0);
- signal instr_ret : std_logic;
-
-begin
-
- por : process(clk)
- begin
- if rising_edge(clk) then
- if reset_btn = '1' then
- rst_cnt <= (others => '0'); -- re-arm counter while button held
- reset <= '1';
- elsif rst_cnt(5) = '0' then
- rst_cnt <= rst_cnt + 1;
- reset <= '1';
- else
- reset <= '0';
- end if;
- end if;
- end process por;
-
- activity_led <= port_b(0);
- led <= port_a(0);
-
- rom : entity work.prog_rom
- port map (
- addr => pc,
- data => opcode
- );
-
- cpu : entity work.PIC
- generic map (
- CLK_FREQ => CLK_FREQ
- )
- port map (
- clk => clk,
- reset => reset,
- opcode => opcode,
- program_counter => pc,
- instruction_return => instr_ret,
- work_reg => work_reg,
- status => status,
- port_a => port_a,
- port_b => port_b,
- uart_tx => uart_tx,
- uart_rx => uart_rx
- );
-
-end architecture rtl;
diff --git a/PIC/prog_rom.vhd b/PIC/prog_rom.vhd
deleted file mode 100644
index f3dcf64..0000000
--- a/PIC/prog_rom.vhd
+++ /dev/null
@@ -1,1045 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
-entity prog_rom is
- generic (
- DEPTH : positive := 1024
- );
- port (
- addr : in std_logic_vector(12 downto 0);
- data : out std_logic_vector(13 downto 0)
- );
-end entity prog_rom;
-
-architecture rtl of prog_rom is
- type rom_t is array (0 to 1024 - 1) of std_logic_vector(13 downto 0);
- constant rom : rom_t := (
- 0 => "00000000000000",
- 1 => "10100000000010",
- 2 => "11000001101111",
- 3 => "00000010011010",
- 4 => "11000000000001",
- 5 => "00000010011011",
- 6 => "11000010000000",
- 7 => "00000000000000",
- 8 => "00000000000000",
- 9 => "10000100010010",
- 10 => "00000000000000",
- 11 => "00000000000000",
- 12 => "01001010000011",
- 13 => "00000000000000",
- 14 => "00000010011101",
- 15 => "00100000011011",
- 16 => "00000010011100",
- 17 => "11000001110001",
- 18 => "00000010011110",
- 19 => "11000000000001",
- 20 => "00000010011111",
- 21 => "01001010000011",
- 22 => "00000000000000",
- 23 => "00100000011100",
- 24 => "00000010100000",
- 25 => "00100000011101",
- 26 => "00000010100001",
- 27 => "11000011111111",
- 28 => "00011110011100",
- 29 => "01110000000011",
- 30 => "00001110011101",
- 31 => "00100000100001",
- 32 => "00010000100000",
- 33 => "01100100000011",
- 34 => "10100010011010",
- 35 => "11000000000100",
- 36 => "00011100011110",
- 37 => "00000010100000",
- 38 => "00000110100001",
- 39 => "00110110100001",
- 40 => "00100000011111",
- 41 => "00011110100001",
- 42 => "00100000100000",
- 43 => "00000010011010",
- 44 => "00100000100001",
- 45 => "00000010011011",
- 46 => "11000010000000",
- 47 => "00000000000000",
- 48 => "00000000000000",
- 49 => "10000100010010",
- 50 => "00000000000000",
- 51 => "00000000000000",
- 52 => "01001010000011",
- 53 => "00000000000000",
- 54 => "00000010100011",
- 55 => "00100000011011",
- 56 => "00000010100010",
- 57 => "00100000011110",
- 58 => "00000010011010",
- 59 => "00100000011111",
- 60 => "00000010011011",
- 61 => "11000010000000",
- 62 => "00000000000000",
- 63 => "00000000000000",
- 64 => "10000100010010",
- 65 => "00000000000000",
- 66 => "00000000000000",
- 67 => "01001010000011",
- 68 => "00000000000000",
- 69 => "00000010100101",
- 70 => "00000010100001",
- 71 => "00100000011011",
- 72 => "00000010100000",
- 73 => "00000010100100",
- 74 => "11000000000010",
- 75 => "00011100011110",
- 76 => "00000010100000",
- 77 => "00000110100001",
- 78 => "00110110100001",
- 79 => "00100000011111",
- 80 => "00011110100001",
- 81 => "00100000100000",
- 82 => "00000010011010",
- 83 => "00100000100001",
- 84 => "00000010011011",
- 85 => "11000010000000",
- 86 => "00000000000000",
- 87 => "00000000000000",
- 88 => "10000100010010",
- 89 => "00000000000000",
- 90 => "00000000000000",
- 91 => "01001010000011",
- 92 => "00000000000000",
- 93 => "00000010100001",
- 94 => "00000010100111",
- 95 => "00100000011011",
- 96 => "00000010100110",
- 97 => "00000010100000",
- 98 => "01001010000011",
- 99 => "00000000000000",
- 100 => "00100000100010",
- 101 => "00000010100110",
- 102 => "00100000100011",
- 103 => "00000010100111",
- 104 => "11000011111111",
- 105 => "00011110100010",
- 106 => "01110000000011",
- 107 => "00001110100011",
- 108 => "00100000100111",
- 109 => "00010000100110",
- 110 => "01100100000011",
- 111 => "10100010010011",
- 112 => "00100000100100",
- 113 => "00000010011010",
- 114 => "00100000100101",
- 115 => "00000010011011",
- 116 => "11000010000000",
- 117 => "00000000000000",
- 118 => "00000000000000",
- 119 => "10000100110011",
- 120 => "00000000000000",
- 121 => "00000000000000",
- 122 => "01001010000011",
- 123 => "00000000000000",
- 124 => "00000010100110",
- 125 => "00100000100000",
- 126 => "01001010000011",
- 127 => "01001100000011",
- 128 => "00000010000100",
- 129 => "01001110000011",
- 130 => "01001010000011",
- 131 => "00000000000000",
- 132 => "01100000100001",
- 133 => "01011110000011",
- 134 => "00100000100110",
- 135 => "01001010000011",
- 136 => "01001100000011",
- 137 => "00000010000000",
- 138 => "01001010000011",
- 139 => "00000000000000",
- 140 => "00101010100100",
- 141 => "01100100000011",
- 142 => "00101010100101",
- 143 => "00101010100000",
- 144 => "01100100000011",
- 145 => "00101010100001",
- 146 => "10100001100010",
- 147 => "11000000000110",
- 148 => "01001010000011",
- 149 => "00000000000000",
- 150 => "00011110011110",
- 151 => "01100000000011",
- 152 => "00101010011111",
- 153 => "10100000010101",
- 154 => "00000000000000",
- 155 => "00000000000000",
- 156 => "10100010011110",
- 157 => "00000000001000",
- 158 => "00000110110101",
- 159 => "11000000000001",
- 160 => "00000010101111",
- 161 => "11000001100111",
- 162 => "00000010101110",
- 163 => "11000010000000",
- 164 => "00000010110000",
- 165 => "00100000101110",
- 166 => "00000010011010",
- 167 => "00100000101111",
- 168 => "00000010011011",
- 169 => "00100000110000",
- 170 => "10000101000110",
- 171 => "11000001000011",
- 172 => "10000101011110",
- 173 => "11000000111010",
- 174 => "10000101011110",
- 175 => "00100000110101",
- 176 => "00000010101110",
- 177 => "00000110101111",
- 178 => "11000011001000",
- 179 => "00001000101110",
- 180 => "01110000000011",
- 181 => "10100011000000",
- 182 => "11000000110010",
- 183 => "10000101011110",
- 184 => "00100000101110",
- 185 => "00000010110000",
- 186 => "11000000111000",
- 187 => "00011100110000",
- 188 => "00000010101110",
- 189 => "11000000000001",
- 190 => "00000010101111",
- 191 => "10100011001101",
- 192 => "11000001100100",
- 193 => "00001000101110",
- 194 => "01110000000011",
- 195 => "10100011001101",
- 196 => "11000000110001",
- 197 => "10000101011110",
- 198 => "00100000101110",
- 199 => "00000010110000",
- 200 => "11000010011100",
- 201 => "00011100110000",
- 202 => "00000010101110",
- 203 => "11000000000001",
- 204 => "00000010101111",
- 205 => "11000000110000",
- 206 => "00000010110000",
- 207 => "11000000001010",
- 208 => "00001000101110",
- 209 => "01110000000011",
- 210 => "10100011011010",
- 211 => "00100000101110",
- 212 => "00000010110001",
- 213 => "11000011110110",
- 214 => "00011100110001",
- 215 => "00000010101110",
- 216 => "00101010110000",
- 217 => "10100011001111",
- 218 => "00100000110000",
- 219 => "00000010110001",
- 220 => "00100000101111",
- 221 => "01110100000011",
- 222 => "10100011100011",
- 223 => "00100000110000",
- 224 => "11101000110000",
- 225 => "01100100000011",
- 226 => "10100011100101",
- 227 => "00100000110001",
- 228 => "10000101011110",
- 229 => "00100000101110",
- 230 => "00000010101111",
- 231 => "11000000110000",
- 232 => "00011100101111",
- 233 => "00000010101110",
- 234 => "10000101011110",
- 235 => "11000000000001",
- 236 => "00000010101111",
- 237 => "11000001110111",
- 238 => "00000010101110",
- 239 => "11000010000000",
- 240 => "00000010110000",
- 241 => "00100000101110",
- 242 => "00000010011010",
- 243 => "00100000101111",
- 244 => "00000010011011",
- 245 => "00100000110000",
- 246 => "10000101000110",
- 247 => "00101010110101",
- 248 => "00000110110010",
- 249 => "00000110110011",
- 250 => "00000110110100",
- 251 => "00100000110100",
- 252 => "00000010101000",
- 253 => "00101000101000",
- 254 => "00000010110100",
- 255 => "00100000110100",
- 256 => "01110100000011",
- 257 => "10100011111011",
- 258 => "00101000110011",
- 259 => "00000010101000",
- 260 => "00000010110011",
- 261 => "00100000101000",
- 262 => "11101000011110",
- 263 => "01110100000011",
- 264 => "10100011111010",
- 265 => "00100000110010",
- 266 => "00000010101000",
- 267 => "00101000101000",
- 268 => "00000010110010",
- 269 => "11101001110100",
- 270 => "01110100000011",
- 271 => "10100011111001",
- 272 => "10100010101011",
- 273 => "00000000001000",
- 274 => "11101000000000",
- 275 => "01100100000011",
- 276 => "10100100011010",
- 277 => "11101010000000",
- 278 => "01100100000011",
- 279 => "10100100100100",
- 280 => "00000110011011",
- 281 => "11010000000000",
- 282 => "00100000011010",
- 283 => "00000010000100",
- 284 => "01001110000011",
- 285 => "01100000011011",
- 286 => "01011110000011",
- 287 => "00100000000000",
- 288 => "00000010011011",
- 289 => "00101010000100",
- 290 => "00100000000000",
- 291 => "00000000001000",
- 292 => "00000000000000",
- 293 => "00000000000000",
- 294 => "10000101000001",
- 295 => "00000010011001",
- 296 => "00111110011010",
- 297 => "00001110011011",
- 298 => "00101010011011",
- 299 => "00000000000000",
- 300 => "00000000000000",
- 301 => "10000101000001",
- 302 => "00000010011000",
- 303 => "00100000011001",
- 304 => "00000010011011",
- 305 => "00100000011000",
- 306 => "00000000001000",
- 307 => "11101000000000",
- 308 => "01100100000011",
- 309 => "10100100111010",
- 310 => "11101010000000",
- 311 => "01100100000011",
- 312 => "10100101000001",
- 313 => "11010000000000",
- 314 => "00100000011010",
- 315 => "00000010000100",
- 316 => "01001110000011",
- 317 => "01100000011011",
- 318 => "01011110000011",
- 319 => "00100000000000",
- 320 => "00000000001000",
- 321 => "00100000011011",
- 322 => "00000010001010",
- 323 => "00100000011010",
- 324 => "00000010000010",
- 325 => "00000000001000",
- 326 => "00000010101100",
- 327 => "00100000011011",
- 328 => "00000010101011",
- 329 => "00100000011010",
- 330 => "00000010101010",
- 331 => "00100000101010",
- 332 => "00000010011010",
- 333 => "00100000101011",
- 334 => "00000010011011",
- 335 => "00100000101100",
- 336 => "10000100110011",
- 337 => "00000010101101",
- 338 => "00100000101101",
- 339 => "01100100000011",
- 340 => "10100101011101",
- 341 => "00100000101101",
- 342 => "10000101011110",
- 343 => "00101010101010",
- 344 => "01100100000011",
- 345 => "00101010101011",
- 346 => "01100100000011",
- 347 => "00101010101100",
- 348 => "10100101001011",
- 349 => "00000000001000",
- 350 => "00000010101000",
- 351 => "01001010000011",
- 352 => "00100001110010",
- 353 => "00000010101001",
- 354 => "01100000101001",
- 355 => "10100101011111",
- 356 => "00100000101000",
- 357 => "00000011110000",
- 358 => "00000000001000",
- 359 => "11010001001000",
- 360 => "11010001100101",
- 361 => "11010001101100",
- 362 => "11010001101100",
- 363 => "11010001101111",
- 364 => "11010000001101",
- 365 => "11010000001010",
- 366 => "11010000000000",
- 367 => "11010000000001",
- 368 => "11010000000000",
- 369 => "11010001111010",
- 370 => "11010000000001",
- 371 => "11010000110110",
- 372 => "11010000000000",
- 373 => "11010000000001",
- 374 => "11010000000000",
- 375 => "11010000001101",
- 376 => "11010000001010",
- 377 => "11010000000000",
- 378 => "11010000000000",
- 379 => "00000000000000",
- 380 => "00000000000000",
- 381 => "00000000000000",
- 382 => "00000000000000",
- 383 => "00000000000000",
- 384 => "00000000000000",
- 385 => "00000000000000",
- 386 => "00000000000000",
- 387 => "00000000000000",
- 388 => "00000000000000",
- 389 => "00000000000000",
- 390 => "00000000000000",
- 391 => "00000000000000",
- 392 => "00000000000000",
- 393 => "00000000000000",
- 394 => "00000000000000",
- 395 => "00000000000000",
- 396 => "00000000000000",
- 397 => "00000000000000",
- 398 => "00000000000000",
- 399 => "00000000000000",
- 400 => "00000000000000",
- 401 => "00000000000000",
- 402 => "00000000000000",
- 403 => "00000000000000",
- 404 => "00000000000000",
- 405 => "00000000000000",
- 406 => "00000000000000",
- 407 => "00000000000000",
- 408 => "00000000000000",
- 409 => "00000000000000",
- 410 => "00000000000000",
- 411 => "00000000000000",
- 412 => "00000000000000",
- 413 => "00000000000000",
- 414 => "00000000000000",
- 415 => "00000000000000",
- 416 => "00000000000000",
- 417 => "00000000000000",
- 418 => "00000000000000",
- 419 => "00000000000000",
- 420 => "00000000000000",
- 421 => "00000000000000",
- 422 => "00000000000000",
- 423 => "00000000000000",
- 424 => "00000000000000",
- 425 => "00000000000000",
- 426 => "00000000000000",
- 427 => "00000000000000",
- 428 => "00000000000000",
- 429 => "00000000000000",
- 430 => "00000000000000",
- 431 => "00000000000000",
- 432 => "00000000000000",
- 433 => "00000000000000",
- 434 => "00000000000000",
- 435 => "00000000000000",
- 436 => "00000000000000",
- 437 => "00000000000000",
- 438 => "00000000000000",
- 439 => "00000000000000",
- 440 => "00000000000000",
- 441 => "00000000000000",
- 442 => "00000000000000",
- 443 => "00000000000000",
- 444 => "00000000000000",
- 445 => "00000000000000",
- 446 => "00000000000000",
- 447 => "00000000000000",
- 448 => "00000000000000",
- 449 => "00000000000000",
- 450 => "00000000000000",
- 451 => "00000000000000",
- 452 => "00000000000000",
- 453 => "00000000000000",
- 454 => "00000000000000",
- 455 => "00000000000000",
- 456 => "00000000000000",
- 457 => "00000000000000",
- 458 => "00000000000000",
- 459 => "00000000000000",
- 460 => "00000000000000",
- 461 => "00000000000000",
- 462 => "00000000000000",
- 463 => "00000000000000",
- 464 => "00000000000000",
- 465 => "00000000000000",
- 466 => "00000000000000",
- 467 => "00000000000000",
- 468 => "00000000000000",
- 469 => "00000000000000",
- 470 => "00000000000000",
- 471 => "00000000000000",
- 472 => "00000000000000",
- 473 => "00000000000000",
- 474 => "00000000000000",
- 475 => "00000000000000",
- 476 => "00000000000000",
- 477 => "00000000000000",
- 478 => "00000000000000",
- 479 => "00000000000000",
- 480 => "00000000000000",
- 481 => "00000000000000",
- 482 => "00000000000000",
- 483 => "00000000000000",
- 484 => "00000000000000",
- 485 => "00000000000000",
- 486 => "00000000000000",
- 487 => "00000000000000",
- 488 => "00000000000000",
- 489 => "00000000000000",
- 490 => "00000000000000",
- 491 => "00000000000000",
- 492 => "00000000000000",
- 493 => "00000000000000",
- 494 => "00000000000000",
- 495 => "00000000000000",
- 496 => "00000000000000",
- 497 => "00000000000000",
- 498 => "00000000000000",
- 499 => "00000000000000",
- 500 => "00000000000000",
- 501 => "00000000000000",
- 502 => "00000000000000",
- 503 => "00000000000000",
- 504 => "00000000000000",
- 505 => "00000000000000",
- 506 => "00000000000000",
- 507 => "00000000000000",
- 508 => "00000000000000",
- 509 => "00000000000000",
- 510 => "00000000000000",
- 511 => "00000000000000",
- 512 => "00000000000000",
- 513 => "00000000000000",
- 514 => "00000000000000",
- 515 => "00000000000000",
- 516 => "00000000000000",
- 517 => "00000000000000",
- 518 => "00000000000000",
- 519 => "00000000000000",
- 520 => "00000000000000",
- 521 => "00000000000000",
- 522 => "00000000000000",
- 523 => "00000000000000",
- 524 => "00000000000000",
- 525 => "00000000000000",
- 526 => "00000000000000",
- 527 => "00000000000000",
- 528 => "00000000000000",
- 529 => "00000000000000",
- 530 => "00000000000000",
- 531 => "00000000000000",
- 532 => "00000000000000",
- 533 => "00000000000000",
- 534 => "00000000000000",
- 535 => "00000000000000",
- 536 => "00000000000000",
- 537 => "00000000000000",
- 538 => "00000000000000",
- 539 => "00000000000000",
- 540 => "00000000000000",
- 541 => "00000000000000",
- 542 => "00000000000000",
- 543 => "00000000000000",
- 544 => "00000000000000",
- 545 => "00000000000000",
- 546 => "00000000000000",
- 547 => "00000000000000",
- 548 => "00000000000000",
- 549 => "00000000000000",
- 550 => "00000000000000",
- 551 => "00000000000000",
- 552 => "00000000000000",
- 553 => "00000000000000",
- 554 => "00000000000000",
- 555 => "00000000000000",
- 556 => "00000000000000",
- 557 => "00000000000000",
- 558 => "00000000000000",
- 559 => "00000000000000",
- 560 => "00000000000000",
- 561 => "00000000000000",
- 562 => "00000000000000",
- 563 => "00000000000000",
- 564 => "00000000000000",
- 565 => "00000000000000",
- 566 => "00000000000000",
- 567 => "00000000000000",
- 568 => "00000000000000",
- 569 => "00000000000000",
- 570 => "00000000000000",
- 571 => "00000000000000",
- 572 => "00000000000000",
- 573 => "00000000000000",
- 574 => "00000000000000",
- 575 => "00000000000000",
- 576 => "00000000000000",
- 577 => "00000000000000",
- 578 => "00000000000000",
- 579 => "00000000000000",
- 580 => "00000000000000",
- 581 => "00000000000000",
- 582 => "00000000000000",
- 583 => "00000000000000",
- 584 => "00000000000000",
- 585 => "00000000000000",
- 586 => "00000000000000",
- 587 => "00000000000000",
- 588 => "00000000000000",
- 589 => "00000000000000",
- 590 => "00000000000000",
- 591 => "00000000000000",
- 592 => "00000000000000",
- 593 => "00000000000000",
- 594 => "00000000000000",
- 595 => "00000000000000",
- 596 => "00000000000000",
- 597 => "00000000000000",
- 598 => "00000000000000",
- 599 => "00000000000000",
- 600 => "00000000000000",
- 601 => "00000000000000",
- 602 => "00000000000000",
- 603 => "00000000000000",
- 604 => "00000000000000",
- 605 => "00000000000000",
- 606 => "00000000000000",
- 607 => "00000000000000",
- 608 => "00000000000000",
- 609 => "00000000000000",
- 610 => "00000000000000",
- 611 => "00000000000000",
- 612 => "00000000000000",
- 613 => "00000000000000",
- 614 => "00000000000000",
- 615 => "00000000000000",
- 616 => "00000000000000",
- 617 => "00000000000000",
- 618 => "00000000000000",
- 619 => "00000000000000",
- 620 => "00000000000000",
- 621 => "00000000000000",
- 622 => "00000000000000",
- 623 => "00000000000000",
- 624 => "00000000000000",
- 625 => "00000000000000",
- 626 => "00000000000000",
- 627 => "00000000000000",
- 628 => "00000000000000",
- 629 => "00000000000000",
- 630 => "00000000000000",
- 631 => "00000000000000",
- 632 => "00000000000000",
- 633 => "00000000000000",
- 634 => "00000000000000",
- 635 => "00000000000000",
- 636 => "00000000000000",
- 637 => "00000000000000",
- 638 => "00000000000000",
- 639 => "00000000000000",
- 640 => "00000000000000",
- 641 => "00000000000000",
- 642 => "00000000000000",
- 643 => "00000000000000",
- 644 => "00000000000000",
- 645 => "00000000000000",
- 646 => "00000000000000",
- 647 => "00000000000000",
- 648 => "00000000000000",
- 649 => "00000000000000",
- 650 => "00000000000000",
- 651 => "00000000000000",
- 652 => "00000000000000",
- 653 => "00000000000000",
- 654 => "00000000000000",
- 655 => "00000000000000",
- 656 => "00000000000000",
- 657 => "00000000000000",
- 658 => "00000000000000",
- 659 => "00000000000000",
- 660 => "00000000000000",
- 661 => "00000000000000",
- 662 => "00000000000000",
- 663 => "00000000000000",
- 664 => "00000000000000",
- 665 => "00000000000000",
- 666 => "00000000000000",
- 667 => "00000000000000",
- 668 => "00000000000000",
- 669 => "00000000000000",
- 670 => "00000000000000",
- 671 => "00000000000000",
- 672 => "00000000000000",
- 673 => "00000000000000",
- 674 => "00000000000000",
- 675 => "00000000000000",
- 676 => "00000000000000",
- 677 => "00000000000000",
- 678 => "00000000000000",
- 679 => "00000000000000",
- 680 => "00000000000000",
- 681 => "00000000000000",
- 682 => "00000000000000",
- 683 => "00000000000000",
- 684 => "00000000000000",
- 685 => "00000000000000",
- 686 => "00000000000000",
- 687 => "00000000000000",
- 688 => "00000000000000",
- 689 => "00000000000000",
- 690 => "00000000000000",
- 691 => "00000000000000",
- 692 => "00000000000000",
- 693 => "00000000000000",
- 694 => "00000000000000",
- 695 => "00000000000000",
- 696 => "00000000000000",
- 697 => "00000000000000",
- 698 => "00000000000000",
- 699 => "00000000000000",
- 700 => "00000000000000",
- 701 => "00000000000000",
- 702 => "00000000000000",
- 703 => "00000000000000",
- 704 => "00000000000000",
- 705 => "00000000000000",
- 706 => "00000000000000",
- 707 => "00000000000000",
- 708 => "00000000000000",
- 709 => "00000000000000",
- 710 => "00000000000000",
- 711 => "00000000000000",
- 712 => "00000000000000",
- 713 => "00000000000000",
- 714 => "00000000000000",
- 715 => "00000000000000",
- 716 => "00000000000000",
- 717 => "00000000000000",
- 718 => "00000000000000",
- 719 => "00000000000000",
- 720 => "00000000000000",
- 721 => "00000000000000",
- 722 => "00000000000000",
- 723 => "00000000000000",
- 724 => "00000000000000",
- 725 => "00000000000000",
- 726 => "00000000000000",
- 727 => "00000000000000",
- 728 => "00000000000000",
- 729 => "00000000000000",
- 730 => "00000000000000",
- 731 => "00000000000000",
- 732 => "00000000000000",
- 733 => "00000000000000",
- 734 => "00000000000000",
- 735 => "00000000000000",
- 736 => "00000000000000",
- 737 => "00000000000000",
- 738 => "00000000000000",
- 739 => "00000000000000",
- 740 => "00000000000000",
- 741 => "00000000000000",
- 742 => "00000000000000",
- 743 => "00000000000000",
- 744 => "00000000000000",
- 745 => "00000000000000",
- 746 => "00000000000000",
- 747 => "00000000000000",
- 748 => "00000000000000",
- 749 => "00000000000000",
- 750 => "00000000000000",
- 751 => "00000000000000",
- 752 => "00000000000000",
- 753 => "00000000000000",
- 754 => "00000000000000",
- 755 => "00000000000000",
- 756 => "00000000000000",
- 757 => "00000000000000",
- 758 => "00000000000000",
- 759 => "00000000000000",
- 760 => "00000000000000",
- 761 => "00000000000000",
- 762 => "00000000000000",
- 763 => "00000000000000",
- 764 => "00000000000000",
- 765 => "00000000000000",
- 766 => "00000000000000",
- 767 => "00000000000000",
- 768 => "00000000000000",
- 769 => "00000000000000",
- 770 => "00000000000000",
- 771 => "00000000000000",
- 772 => "00000000000000",
- 773 => "00000000000000",
- 774 => "00000000000000",
- 775 => "00000000000000",
- 776 => "00000000000000",
- 777 => "00000000000000",
- 778 => "00000000000000",
- 779 => "00000000000000",
- 780 => "00000000000000",
- 781 => "00000000000000",
- 782 => "00000000000000",
- 783 => "00000000000000",
- 784 => "00000000000000",
- 785 => "00000000000000",
- 786 => "00000000000000",
- 787 => "00000000000000",
- 788 => "00000000000000",
- 789 => "00000000000000",
- 790 => "00000000000000",
- 791 => "00000000000000",
- 792 => "00000000000000",
- 793 => "00000000000000",
- 794 => "00000000000000",
- 795 => "00000000000000",
- 796 => "00000000000000",
- 797 => "00000000000000",
- 798 => "00000000000000",
- 799 => "00000000000000",
- 800 => "00000000000000",
- 801 => "00000000000000",
- 802 => "00000000000000",
- 803 => "00000000000000",
- 804 => "00000000000000",
- 805 => "00000000000000",
- 806 => "00000000000000",
- 807 => "00000000000000",
- 808 => "00000000000000",
- 809 => "00000000000000",
- 810 => "00000000000000",
- 811 => "00000000000000",
- 812 => "00000000000000",
- 813 => "00000000000000",
- 814 => "00000000000000",
- 815 => "00000000000000",
- 816 => "00000000000000",
- 817 => "00000000000000",
- 818 => "00000000000000",
- 819 => "00000000000000",
- 820 => "00000000000000",
- 821 => "00000000000000",
- 822 => "00000000000000",
- 823 => "00000000000000",
- 824 => "00000000000000",
- 825 => "00000000000000",
- 826 => "00000000000000",
- 827 => "00000000000000",
- 828 => "00000000000000",
- 829 => "00000000000000",
- 830 => "00000000000000",
- 831 => "00000000000000",
- 832 => "00000000000000",
- 833 => "00000000000000",
- 834 => "00000000000000",
- 835 => "00000000000000",
- 836 => "00000000000000",
- 837 => "00000000000000",
- 838 => "00000000000000",
- 839 => "00000000000000",
- 840 => "00000000000000",
- 841 => "00000000000000",
- 842 => "00000000000000",
- 843 => "00000000000000",
- 844 => "00000000000000",
- 845 => "00000000000000",
- 846 => "00000000000000",
- 847 => "00000000000000",
- 848 => "00000000000000",
- 849 => "00000000000000",
- 850 => "00000000000000",
- 851 => "00000000000000",
- 852 => "00000000000000",
- 853 => "00000000000000",
- 854 => "00000000000000",
- 855 => "00000000000000",
- 856 => "00000000000000",
- 857 => "00000000000000",
- 858 => "00000000000000",
- 859 => "00000000000000",
- 860 => "00000000000000",
- 861 => "00000000000000",
- 862 => "00000000000000",
- 863 => "00000000000000",
- 864 => "00000000000000",
- 865 => "00000000000000",
- 866 => "00000000000000",
- 867 => "00000000000000",
- 868 => "00000000000000",
- 869 => "00000000000000",
- 870 => "00000000000000",
- 871 => "00000000000000",
- 872 => "00000000000000",
- 873 => "00000000000000",
- 874 => "00000000000000",
- 875 => "00000000000000",
- 876 => "00000000000000",
- 877 => "00000000000000",
- 878 => "00000000000000",
- 879 => "00000000000000",
- 880 => "00000000000000",
- 881 => "00000000000000",
- 882 => "00000000000000",
- 883 => "00000000000000",
- 884 => "00000000000000",
- 885 => "00000000000000",
- 886 => "00000000000000",
- 887 => "00000000000000",
- 888 => "00000000000000",
- 889 => "00000000000000",
- 890 => "00000000000000",
- 891 => "00000000000000",
- 892 => "00000000000000",
- 893 => "00000000000000",
- 894 => "00000000000000",
- 895 => "00000000000000",
- 896 => "00000000000000",
- 897 => "00000000000000",
- 898 => "00000000000000",
- 899 => "00000000000000",
- 900 => "00000000000000",
- 901 => "00000000000000",
- 902 => "00000000000000",
- 903 => "00000000000000",
- 904 => "00000000000000",
- 905 => "00000000000000",
- 906 => "00000000000000",
- 907 => "00000000000000",
- 908 => "00000000000000",
- 909 => "00000000000000",
- 910 => "00000000000000",
- 911 => "00000000000000",
- 912 => "00000000000000",
- 913 => "00000000000000",
- 914 => "00000000000000",
- 915 => "00000000000000",
- 916 => "00000000000000",
- 917 => "00000000000000",
- 918 => "00000000000000",
- 919 => "00000000000000",
- 920 => "00000000000000",
- 921 => "00000000000000",
- 922 => "00000000000000",
- 923 => "00000000000000",
- 924 => "00000000000000",
- 925 => "00000000000000",
- 926 => "00000000000000",
- 927 => "00000000000000",
- 928 => "00000000000000",
- 929 => "00000000000000",
- 930 => "00000000000000",
- 931 => "00000000000000",
- 932 => "00000000000000",
- 933 => "00000000000000",
- 934 => "00000000000000",
- 935 => "00000000000000",
- 936 => "00000000000000",
- 937 => "00000000000000",
- 938 => "00000000000000",
- 939 => "00000000000000",
- 940 => "00000000000000",
- 941 => "00000000000000",
- 942 => "00000000000000",
- 943 => "00000000000000",
- 944 => "00000000000000",
- 945 => "00000000000000",
- 946 => "00000000000000",
- 947 => "00000000000000",
- 948 => "00000000000000",
- 949 => "00000000000000",
- 950 => "00000000000000",
- 951 => "00000000000000",
- 952 => "00000000000000",
- 953 => "00000000000000",
- 954 => "00000000000000",
- 955 => "00000000000000",
- 956 => "00000000000000",
- 957 => "00000000000000",
- 958 => "00000000000000",
- 959 => "00000000000000",
- 960 => "00000000000000",
- 961 => "00000000000000",
- 962 => "00000000000000",
- 963 => "00000000000000",
- 964 => "00000000000000",
- 965 => "00000000000000",
- 966 => "00000000000000",
- 967 => "00000000000000",
- 968 => "00000000000000",
- 969 => "00000000000000",
- 970 => "00000000000000",
- 971 => "00000000000000",
- 972 => "00000000000000",
- 973 => "00000000000000",
- 974 => "00000000000000",
- 975 => "00000000000000",
- 976 => "00000000000000",
- 977 => "00000000000000",
- 978 => "00000000000000",
- 979 => "00000000000000",
- 980 => "00000000000000",
- 981 => "00000000000000",
- 982 => "00000000000000",
- 983 => "00000000000000",
- 984 => "00000000000000",
- 985 => "00000000000000",
- 986 => "00000000000000",
- 987 => "00000000000000",
- 988 => "00000000000000",
- 989 => "00000000000000",
- 990 => "00000000000000",
- 991 => "00000000000000",
- 992 => "00000000000000",
- 993 => "00000000000000",
- 994 => "00000000000000",
- 995 => "00000000000000",
- 996 => "00000000000000",
- 997 => "00000000000000",
- 998 => "00000000000000",
- 999 => "00000000000000",
- 1000 => "00000000000000",
- 1001 => "00000000000000",
- 1002 => "00000000000000",
- 1003 => "00000000000000",
- 1004 => "00000000000000",
- 1005 => "00000000000000",
- 1006 => "00000000000000",
- 1007 => "00000000000000",
- 1008 => "00000000000000",
- 1009 => "00000000000000",
- 1010 => "00000000000000",
- 1011 => "00000000000000",
- 1012 => "00000000000000",
- 1013 => "00000000000000",
- 1014 => "00000000000000",
- 1015 => "00000000000000",
- 1016 => "00000000000000",
- 1017 => "00000000000000",
- 1018 => "00000000000000",
- 1019 => "00000000000000",
- 1020 => "00000000000000",
- 1021 => "00000000000000",
- 1022 => "00000000000000",
- 1023 => "00000000000000"
- );
-begin
- data <= rom(to_integer(unsigned(addr(9 downto 0))));
-end architecture rtl;
diff --git a/PIC/stack.vhd b/PIC/stack.vhd
deleted file mode 100644
index fd376c0..0000000
--- a/PIC/stack.vhd
+++ /dev/null
@@ -1,51 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
-entity stack is
- generic (
- DEPTH : positive := 8;
- WIDTH : positive := 13
- );
- port (
- clk : in std_logic;
- reset : in std_logic;
- push : in std_logic;
- pop : in std_logic;
- din : in std_logic_vector(WIDTH - 1 downto 0);
- dout : out std_logic_vector(WIDTH - 1 downto 0)
- );
-end entity stack;
-
-architecture rtl of stack is
-
- type stack_t is
- array (0 to DEPTH - 1)
- of std_logic_vector(WIDTH - 1 downto 0);
-
- signal mem : stack_t
- := (others => (others => '0'));
-
- -- write pointer
- signal top : unsigned(2 downto 0)
- := (others => '0');
-begin
-
- dout <=
- mem(to_integer(top - 1)) when top /= 0 else (others => '0');
-
- stck : process(clk, reset)
- begin
- if reset = '1' then
- top <= (others => '0');
- elsif rising_edge(clk) then
- if push = '1' then
- mem(to_integer(top)) <= din;
- top <= top + 1;
- elsif pop = '1' then
- top <= top - 1;
- end if;
- end if;
- end process;
-
-end architecture rtl;
diff --git a/PIC/state_machine.vhd b/PIC/state_machine.vhd
deleted file mode 100644
index 24da581..0000000
--- a/PIC/state_machine.vhd
+++ /dev/null
@@ -1,222 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-use work.alu_types.all;
-
-use work.decoder.all;
-
-entity state_machine is
- port(
- clk : in std_logic;
- opcode : in std_logic_vector(13 downto 0);
-
- reset : in std_logic;
-
- op : out alu_op;
- we_mem : out std_logic := '0';
- re_mem : out std_logic := '0';
- we_w : out std_logic := '0';
- instr_ret : out std_logic := '0';
- bit_select : out std_logic_vector(2 downto 0) := (others => '0');
- data : out std_logic_vector(7 downto 0) := (others => '0');
- pc : out std_logic_vector(12 downto 0);
- addr : out std_logic_vector(6 downto 0) := (others => '0');
-
- use_literal : out std_logic;
- we_status : out std_logic := '0';
-
- stack_push : out std_logic := '0';
- stack_pop : out std_logic := '0';
- stack_din : out std_logic_vector(12 downto 0) := (others => '0');
- stack_dout : in std_logic_vector(12 downto 0);
-
- alu_skip : in std_logic;
- alu_result : in std_logic_vector(7 downto 0)
- );
-
-
-end entity state_machine;
-
-architecture rtl of state_machine is
- type state_t is (IFetch, MRead, Execute, MWrite);
-
- signal pc_internal : std_logic_vector(12 downto 0) := (others => '0');
- signal state : state_t := IFetch;
- signal pclath : std_logic_vector(4 downto 0) := (others => '0');
-
-begin
- pc <= pc_internal;
-
- fsm : process(clk)
- variable instr : instruction_t;
-
- -- do we do a phantom nop after this instruction?
- variable do_phantom_nop : boolean := false;
- variable is_phantom : boolean := false;
- -- true when phantom came from DECFSZ/INCFSZ skip (must still increment PC)
- -- false when phantom came from GOTO/CALL/RETURN (PC already at target)
- variable is_skip_phantom : boolean := false;
- begin
-
- if rising_edge(clk) then
-
- re_mem <= '0';
- we_mem <= '0';
- we_w <= '0';
- we_status <= '0';
- instr_ret <= '0';
- stack_push <= '0';
- stack_pop <= '0';
-
- if reset = '1' then
- pc_internal <= (others => '0');
- pclath <= (others => '0');
- state <= IFetch;
- do_phantom_nop := false;
- else
-
- case state is
- when IFetch =>
-
- -- if we had a branch before, this cycle is a NOP.
- if do_phantom_nop then
- instr := instruction_decode((others => '0'));
- do_phantom_nop := false;
- is_phantom := true;
- -- is_skip_phantom carries over from whoever set do_phantom_nop
- else
- instr := instruction_decode(opcode);
- is_phantom := false;
- is_skip_phantom := false;
- end if;
-
- -- set use_literal based on decoded instruction, holds through MWrite
- if instr.class = LITERAL_OP then
- use_literal <= '1';
- else
- use_literal <= '0';
- end if;
-
- -- for literal operations
- data <= instr.k(7 downto 0);
-
- -- for memory-read/write operations
- addr <= instr.f;
-
- -- for bit-select operations
- bit_select <= instr.b;
-
- state <= Mread;
-
- when MRead =>
-
- -- read memory addressed by the opcode
- -- MOVWF, CLRF, CLRW, NOP are write-only.
- if instr.class = BIT_OP or
- (instr.class = BYTE_OP and
- instr.op /= MOVWF and instr.op /= CLRF and
- instr.op /= CLRW and instr.op /= NOP) then
- re_mem <= '1';
- end if;
-
- state <= Execute;
-
- when Execute =>
-
- op <= instr.op; -- move the decoded instruction to the ALU
-
- if not is_phantom then
-
- -- increment PC or change address, different for different instructions.
- if instr.op = GOTO then
-
- pc_internal <= "00" & instr.k;
- do_phantom_nop := true;
- is_skip_phantom := false;
-
- elsif instr.op = CALL then
-
- -- push PC+1 to the stack
- stack_din <= std_logic_vector(unsigned(pc_internal) + 1);
- stack_push <= '1';
-
- -- go to the function we called
- pc_internal <= "00" & instr.k;
- do_phantom_nop := true;
- is_skip_phantom := false;
-
- elsif instr.op = RETUR or instr.op = RETLW then
-
- -- pop the PC from stack.
- pc_internal <= stack_dout;
- stack_pop <= '1'; -- pop deferred to next cycle.
- do_phantom_nop := true;
- is_skip_phantom := false;
-
- else
- pc_internal <= std_logic_vector(unsigned(pc_internal) + 1);
- end if;
-
- elsif is_skip_phantom then
- -- skip phantom: PC was at the skipped instruction, step past it
- pc_internal <= std_logic_vector(unsigned(pc_internal) + 1);
- end if;
- -- branch phantom: PC already at target, no change needed
-
- state <= MWrite;
-
- when MWrite =>
-
- -- write to correct memory based on class (skip for phantom NOP)
- if not is_phantom then
- case instr.class is
- when BYTE_OP =>
- if instr.op /= NOP then
- if instr.d = '1' then
- we_mem <= '1';
- -- Write to PCLATH (addr 0x0A): latch upper PC bits
- if instr.f = "0001010" then
- pclath <= alu_result(4 downto 0);
- end if;
- -- Write to PCL (addr 0x02): redirect PC, like a GOTO
- if instr.f = "0000010" then
- pc_internal <= pclath & alu_result;
- do_phantom_nop := true;
- is_skip_phantom := false;
- end if;
- else
- we_w <= '1';
- end if;
- end if;
- when BIT_OP =>
- -- NOT for the BTFSS or BTFSC instructions.
- if instr.op = BCF or instr.op = BSF then
- we_mem <= '1';
- end if;
- when LITERAL_OP =>
- if instr.op /= NOP and instr.op /= RETUR then
- we_w <= '1';
- end if;
- when others => null;
- end case;
- end if;
-
- -- DECFSZ/INCFSZ/BTFSS/BTFSC: skip next instruction if ALU signals skip
- if not is_phantom and
- (instr.op = DECFSZ or instr.op = INCFSZ or instr.op = BTFSS or instr.op = BTFSC) and alu_skip = '1' then
- do_phantom_nop := true;
- is_skip_phantom := true;
- end if;
-
- if not is_phantom then
- we_status <= '1';
- instr_ret <= '1';
- end if;
- state <= IFetch;
-
- end case;
- end if; -- reset
- end if;
- end process fsm;
-
-end architecture rtl;
diff --git a/PIC/tb_pic.vhd b/PIC/tb_pic.vhd
deleted file mode 100644
index 067e154..0000000
--- a/PIC/tb_pic.vhd
+++ /dev/null
@@ -1,83 +0,0 @@
-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;
diff --git a/PIC/tb_stack.vhd b/PIC/tb_stack.vhd
deleted file mode 100644
index 5b386e9..0000000
--- a/PIC/tb_stack.vhd
+++ /dev/null
@@ -1,121 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
-entity tb_stack is
-end entity tb_stack;
-
-architecture behavioural of tb_stack is
- constant T_clk : time := 10 ns;
- constant W : positive := 13;
-
- signal clk : std_logic := '0';
- signal reset : std_logic := '0';
- signal push : std_logic := '0';
- signal pop : std_logic := '0';
- signal din : std_logic_vector(W - 1 downto 0) := (others => '0');
- signal dout : std_logic_vector(W - 1 downto 0);
-
- signal done : boolean := false;
-
- procedure tick(signal clk_in : in std_logic) is
- begin
- wait until rising_edge(clk_in);
- wait for 1 ns;
- end procedure;
-
-begin
-
- clk <= not clk after T_clk / 2 when not done else unaffected;
-
- dut : entity work.stack(rtl)
- generic map (DEPTH => 8, WIDTH => W)
- port map (
- clk => clk,
- reset => reset,
- push => push,
- pop => pop,
- din => din,
- dout => dout
- );
-
- stimulus : process is
- begin
-
- -- test 1: reset clears stack
- report "test 1: reset";
- reset <= '1';
- wait for T_clk;
- reset <= '0';
- wait for 1 ns;
- assert dout = std_logic_vector(to_unsigned(0, W))
- report "reset: dout should be 0" severity error;
-
- -- test 2: push one value and read it back
- report "test 2: push/pop single value";
- din <= std_logic_vector(to_unsigned(16#42#, W));
- push <= '1';
- tick(clk);
- push <= '0';
- assert dout = std_logic_vector(to_unsigned(16#42#, W))
- report "push: dout should be 0x42" severity error;
- pop <= '1';
- tick(clk);
- pop <= '0';
- assert dout = std_logic_vector(to_unsigned(0, W))
- report "pop: dout should be 0 (empty)" severity error;
-
- -- test 3: push multiple values, pop in LIFO order
- report "test 3: LIFO order";
- din <= std_logic_vector(to_unsigned(16#100#, W));
- push <= '1';
- tick(clk);
- din <= std_logic_vector(to_unsigned(16#200#, W));
- tick(clk);
- din <= std_logic_vector(to_unsigned(16#300#, W));
- tick(clk);
- push <= '0';
- assert dout = std_logic_vector(to_unsigned(16#300#, W))
- report "LIFO: top should be 0x300" severity error;
- pop <= '1';
- tick(clk);
- assert dout = std_logic_vector(to_unsigned(16#200#, W))
- report "LIFO: after 1 pop should be 0x200" severity error;
- tick(clk);
- assert dout = std_logic_vector(to_unsigned(16#100#, W))
- report "LIFO: after 2 pops should be 0x100" severity error;
- tick(clk);
- pop <= '0';
- assert dout = std_logic_vector(to_unsigned(0, W))
- report "LIFO: stack empty, dout should be 0" severity error;
-
- report "test 4: overflow wraparound";
- push <= '1';
- for i in 1 to 8 loop
- din <= std_logic_vector(to_unsigned(i, W));
- tick(clk);
- end loop;
- push <= '0';
- -- after 8 pushes top wraps to 0, so stack looks empty
- assert dout = std_logic_vector(to_unsigned(0, W))
- report "overflow: top wrapped to 0, dout should be 0" severity error;
-
- -- test 5: reset mid-operation clears pointer
- report "test 5: reset mid-operation";
- din <= std_logic_vector(to_unsigned(16#1FF#, W));
- push <= '1';
- tick(clk);
- push <= '0';
- reset <= '1';
- wait for T_clk;
- reset <= '0';
- wait for 1 ns;
- assert dout = std_logic_vector(to_unsigned(0, W))
- report "reset mid-op: dout should be 0" severity error;
-
- report "All stack tests done" severity note;
- done <= true;
- wait;
- end process stimulus;
-
-end architecture behavioural;
diff --git a/PIC/test_uart.c b/PIC/test_uart.c
deleted file mode 100644
index 2656371..0000000
--- a/PIC/test_uart.c
+++ /dev/null
@@ -1,67 +0,0 @@
-#include <pic16f84a.h>
-
-typedef unsigned char uint8_t;
-
-__sfr __at(0x70) UART_TX;
-__sfr __at(0x71) UART_RX;
-__sfr __at(0x72) UART_STATUS;
-
-static volatile uint8_t _d0, _d1, _d2;
-static uint8_t counter;
-
-static void delay(void) {
- _d0 = 0;
- do {
- _d1 = 0;
- do {
- _d2 = 0;
- do { _d2++; } while (_d2 != 0);
- } while (++_d1 != 30);
- _d0++;
- } while (_d0 != 116);
-}
-
-static void uart_send(uint8_t byte) {
- while (UART_STATUS & 0x01);
- UART_TX = byte;
-}
-
-// Keep this ONLY for literal strings (ROM)
-static void uart_puts_rom(const char *s) {
- while (*s) {
- uart_send((uint8_t)*s);
- s++;
- }
-}
-
-void main(void) {
- counter = 0;
- uart_puts_rom("Hello\r\n");
-
- while (1) {
- uint8_t v = counter;
- uint8_t started = 0;
-
- uart_send('C');
- uart_send(':');
-
- // Hundreds
- if (v >= 200) { uart_send('2'); v -= 200; started = 1; }
- else if (v >= 100) { uart_send('1'); v -= 100; started = 1; }
-
- // Tens
- {
- uint8_t tens = '0';
- while (v >= 10) { v -= 10; tens++; }
- if (started || tens != '0') { uart_send(tens); }
- }
-
- // Units (always)
- uart_send(v + '0');
-
- uart_puts_rom("\r\n");
-
- counter++;
- delay();
- }
-}
diff --git a/PIC/uart.vhd b/PIC/uart.vhd
deleted file mode 100644
index a0fad93..0000000
--- a/PIC/uart.vhd
+++ /dev/null
@@ -1,195 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- TX: fire and forget (8E1)
--- RX: FIFO-backed (8E1), consumer reads via rd_en/rx_data/rx_empty
-
-entity uart is
- generic (
- CLK_FREQ : positive := 50_000_000;
- BAUD_RATE : positive := 115_200;
- CLKS_PER_BIT : positive := CLK_FREQ / BAUD_RATE
- );
- port (
- clk : in std_logic;
- -- TX
- tx_should_send : in std_logic;
- byte_in : in std_logic_vector(7 downto 0);
- tx_done : out std_logic;
- baud_tick : out std_logic;
- uart_tx : out std_logic;
- -- RX
- uart_rx : in std_logic;
- rd_en : in std_logic;
- rx_data : out std_logic_vector(7 downto 0);
- rx_empty : out std_logic;
- rx_full : out std_logic
- );
-end entity uart;
-
-architecture rtl of uart is
-
- signal baud_counter : std_logic_vector(15 downto 0)
- := (others => '0');
- signal baud_tick_i : std_logic := '0';
-
- signal tx_out : std_logic := '1';
- signal current_byte : std_logic_vector(7 downto 0) := (others => '0');
- signal tx_byte_latch : std_logic_vector(7 downto 0) := (others => '0');
-
- -- RX input synchronizer (2FF, idle state is '1')
- signal uart_rx_meta : std_logic := '1';
- signal uart_rx_sync : std_logic := '1';
-
- -- RX FIFO wiring
- signal fifo_wr_en : std_logic := '0';
- signal fifo_din : std_logic_vector(7 downto 0)
- := (others => '0');
- signal fifo_full : std_logic := '0';
-
-begin
-
- uart_tx <= tx_out;
- baud_tick <= baud_tick_i;
-
- rx_fifo : entity work.fifo
- generic map (DEPTH => 64, ADDR_BITS => 6, WIDTH => 8)
- port map (
- clk => clk,
- wr_en => fifo_wr_en,
- rd_en => rd_en,
- din => fifo_din,
- dout => rx_data,
- full => fifo_full,
- empty => rx_empty
- );
-
- rx_full <= fifo_full;
-
- uart_rx_synchronizer : process(clk)
- begin
- if rising_edge(clk) then
- uart_rx_meta <= uart_rx;
- uart_rx_sync <= uart_rx_meta;
- end if;
- end process uart_rx_synchronizer;
-
- uart_baud_timer : process(clk)
- begin
- if rising_edge(clk) then
- if unsigned(baud_counter) = CLKS_PER_BIT - 1 then
- baud_counter <= (others => '0');
- baud_tick_i <= '1';
- else
- baud_counter <= std_logic_vector(unsigned(baud_counter) + 1);
- baud_tick_i <= '0';
- end if;
- end if;
- end process uart_baud_timer;
-
- uart_transmit_byte : process(clk)
- type t_state is (idle, start, data, parity, stop);
- variable state : t_state := idle;
- variable bit_index : unsigned(2 downto 0);
- variable parity_value : std_logic;
- begin
- if rising_edge(clk) then
- tx_done <= '0';
- if baud_tick_i = '1' then
- case state is
- when idle =>
- if tx_should_send = '1' then
- tx_out <= '0'; -- start bit immediately
- tx_byte_latch <= byte_in; -- latch byte now
- parity_value := '0';
- bit_index := (others => '0');
- state := data;
- end if;
- when start =>
- null; -- unused, kept for completeness
- when data =>
- tx_out <= tx_byte_latch(to_integer(bit_index));
- parity_value := parity_value xor tx_byte_latch(to_integer(bit_index));
- if bit_index = 7 then
- state := parity;
- else
- state := data;
- end if;
- bit_index := bit_index + 1;
- when parity =>
- tx_out <= parity_value;
- state := stop;
- when stop =>
- tx_out <= '1';
- tx_done <= '1';
- state := idle;
- end case;
- end if;
- end if;
- end process uart_transmit_byte;
-
- uart_receive_byte : process(clk)
- type rx_state_t is (idle, start, data, parity, stop);
- variable state : rx_state_t := idle;
- variable bit_index : unsigned(2 downto 0);
- variable rx_byte : std_logic_vector(7 downto 0);
- variable parity_val : std_logic;
- variable rx_counter : unsigned(15 downto 0);
- begin
- if rising_edge(clk) then
- fifo_wr_en <= '0';
- case state is
- when idle =>
- if uart_rx_sync = '0' then
- rx_counter := to_unsigned(CLKS_PER_BIT / 2, 16);
- state := start;
- end if;
- when start =>
- if rx_counter = 0 then
- if uart_rx_sync = '0' then
- rx_counter := to_unsigned(CLKS_PER_BIT - 1, 16);
- bit_index := (others => '0');
- parity_val := '0';
- state := data;
- else
- state := idle;
- end if;
- else
- rx_counter := rx_counter - 1;
- end if;
- when data =>
- if rx_counter = 0 then
- rx_byte(to_integer(bit_index)) := uart_rx_sync;
- parity_val := parity_val xor uart_rx_sync;
- rx_counter := to_unsigned(CLKS_PER_BIT - 1, 16);
- if bit_index = 7 then
- state := parity;
- else
- bit_index := bit_index + 1;
- end if;
- else
- rx_counter := rx_counter - 1;
- end if;
- when parity =>
- if rx_counter = 0 then
- rx_counter := to_unsigned(CLKS_PER_BIT - 1, 16);
- state := stop;
- else
- rx_counter := rx_counter - 1;
- end if;
- when stop =>
- if rx_counter = 0 then
- if uart_rx_sync = '1' and fifo_full = '0' then
- fifo_din <= rx_byte;
- fifo_wr_en <= '1';
- end if;
- state := idle;
- else
- rx_counter := rx_counter - 1;
- end if;
- end case;
- end if;
- end process uart_receive_byte;
-
-end architecture rtl;