summaryrefslogtreecommitdiffstats
path: root/PIC/ALU.vhd
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/ALU.vhd
parent129a1c975dbd0c042576010b1f6eb40d19fc5733 (diff)
downloadvhdl_pic-eb8643ddbef43547eb7bfe58789a3908926c7258.tar.gz
vhdl_pic-eb8643ddbef43547eb7bfe58789a3908926c7258.zip
refactor dir structure, add fib.c
Diffstat (limited to 'PIC/ALU.vhd')
-rw-r--r--PIC/ALU.vhd216
1 files changed, 0 insertions, 216 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;