From eb8643ddbef43547eb7bfe58789a3908926c7258 Mon Sep 17 00:00:00 2001 From: Vaino Kauppila Date: Sun, 19 Apr 2026 12:32:58 +0300 Subject: refactor dir structure, add fib.c --- PIC/ALU.vhd | 216 ---------- PIC/PIC.vhd | 181 --------- PIC/blink.c | 35 -- PIC/common.vhd | 10 - PIC/decoder.vhd | 155 ------- PIC/dpram.vhd | 110 ----- PIC/fifo.vhd | 75 ---- PIC/hdl-prj.json | 24 -- PIC/hexfile_reader.vhd | 342 ---------------- PIC/pic_top.vhd | 81 ---- PIC/prog_rom.vhd | 1045 ------------------------------------------------ PIC/stack.vhd | 51 --- PIC/state_machine.vhd | 222 ---------- PIC/tb_pic.vhd | 83 ---- PIC/tb_stack.vhd | 121 ------ PIC/test_uart.c | 67 ---- PIC/uart.vhd | 195 --------- 17 files changed, 3013 deletions(-) delete mode 100644 PIC/ALU.vhd delete mode 100644 PIC/PIC.vhd delete mode 100644 PIC/blink.c delete mode 100644 PIC/common.vhd delete mode 100644 PIC/decoder.vhd delete mode 100644 PIC/dpram.vhd delete mode 100644 PIC/fifo.vhd delete mode 100644 PIC/hdl-prj.json delete mode 100644 PIC/hexfile_reader.vhd delete mode 100644 PIC/pic_top.vhd delete mode 100644 PIC/prog_rom.vhd delete mode 100644 PIC/stack.vhd delete mode 100644 PIC/state_machine.vhd delete mode 100644 PIC/tb_pic.vhd delete mode 100644 PIC/tb_stack.vhd delete mode 100644 PIC/test_uart.c delete mode 100644 PIC/uart.vhd (limited to 'PIC') 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 - -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 - -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; -- cgit v1.3