You are on page 1of 21

library IEEE;

use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity path is
port (
clk: in STD_LOGIC;
reset: in STD_LOGIC;
data: in STD_LOGIC_VECTOR (7 downto 0);
pathOut: out STD_LOGIC_VECTOR (7 downto 0);
addr: out STD_LOGIC_VECTOR (15 downto 0);
ALUFlag: out STD_LOGIC_VECTOR (8 downto 0)
);
end path;
architecture path_arch of path is
--multiplier
COMPONENT mult
PORT(
clk : IN std_logic;
start : IN

std_logic;

pass : IN std_logic;
finish: IN

std_logic;

result: OUT std_logic_vector(9 DOWNTO 0);


mstate: BUFFER std_logic_vector(1 DOWNTO 0);
in0 : IN std_logic_vector(3 DOWNTO 0);
in1 : IN std_logic_vector(3 DOWNTO 0)
);
END COMPONENT;
-- ALU
COMPONENT alu

port (
inA: in STD_LOGIC_VECTOR (9 downto 0);
inB: in STD_LOGIC_VECTOR (9 downto 0);
fn: in STD_LOGIC_VECTOR (3 downto 0);
aluout: out STD_LOGIC_VECTOR (9 downto 0);
flags: out STD_LOGIC_VECTOR (3 downto 0)
);
END COMPONENT;
COMPONENT shifter
port (
shtIn: in STD_LOGIC_VECTOR (9 downto 0);
sfn: in STD_LOGIC_VECTOR (3 downto 0);
shtOut: out STD_LOGIC_VECTOR (9 downto 0);
shtFlag: out STD_LOGIC;
shEn: in std_logic
);
END COMPONENT;
-- register signals
SIGNAL r0,r1,r2,r3: std_logic_vector(3 downto 0);
SIGNAL rgEn: std_logic;
-- multiplier interconnects
SIGNAL pass_logic: std_logic;
SIGNAL mul1,mul2,rin: std_logic_vector(3 downto 0);
SIGNAL multout: std_logic_vector(9 DOWNTO 0);
--mux and tristate signals
SIGNAL d1out, d2out: STD_LOGIC_VECTOR (9 downto 0);
SIGNAL outEn: STD_LOGIC;
--alu connection signals
SIGNAL aluout, aluI1, aluI2 : STD_LOGIC_VECTOR (9 downto 0);
--alu state signals

SIGNAL astate, anextstate: STD_LOGIC_VECTOR (1 downto 0);


--flag signals
SIGNAL tmpflag, mulflag, spflag, lmFlag: std_logic_vector(3 downto 0);
SIGNAL sflag: std_logic;
-- signals for accumulator file
SIGNAL a0, a1,a2,a3: STD_LOGIC_VECTOR (9 downto 0);
SIGNAL acon: STD_LOGIC_VECTOR (1 downto 0);
SIGNAL regEn: STD_LOGIC;
--limiter signals
SIGNAL lmOut: STD_LOGIC_VECTOR (7 downto 0);
SIGNAL lmIn: STD_LOGIC_VECTOR (9 downto 0);
SIGNAL lmfn: STD_LOGIC_VECTOR (3 downto 0);
SIGNAL zz: std_logic_vector(11 downto 0);
-- Instruction Register Signals
SIGNAL op: std_logic_vector(2 downto 0);
SIGNAL func: std_logic_vector(4 downto 0);
SIGNAL shOp: std_logic_vector(3 downto 0);
SIGNAL aca, acb: std_logic_vector(1 downto 0);
SIGNAL imm: std_logic_vector(9 downto 0);
SIGNAL imm2: std_logic_vector(3 downto 0);
SIGNAL ra, rb: std_logic_vector(1 downto 0);
-- Shifter Signals
SIGNAL shtOut: std_logic_vector(9 downto 0);
SIGNAL shift: std_logic;
-- address signal registers
SIGNAL ir1: std_logic_vector(7 DOWNTO 0);
SIGNAL ir2: std_logic_vector(7 DOWNTO 0);
SIGNAL mah: std_logic_vector(7 downto 0);
SIGNAL mal: std_logic_vector(7 downto 0);
SIGNAL pc: std_logic_vector(15 downto 0);

SIGNAL disp: std_logic;


-- state signal definitions
SIGNAL state: std_logic_vector(2 downto 0);
SIGNAL nextstate: std_logic_vector(2 downto 0);
-- execute start and finish signals
SIGNAL start: std_logic;
SIGNAL finish: std_logic;
SIGNAL mstate: std_logic_vector(1 downto 0);
BEGIN
-- multiplier port map
mlt: mult PORT MAP (
clk => clk,
start => start,
finish => finish,
result => multout,
mstate => mstate,
pass => pass_logic,
in0 => mul1,
in1 => mul2
);
--ALU port map
a: alu PORT MAP (
inA => aluI1,
inB => aluI2,
fn => func(3 downto 0),
aluout => aluout,
flags => tmpflag
);
-- shifter port map
s: shifter PORT MAP (

shtIn => d1out,


sfn => shOp,
shtOut => shtOut,
shtFlag => sflag,
shEn => shift
);
-- Map labels from IRs
mp: PROCESS (ir1,ir2)
BEGIN
op <= ir1(7 downto 5);
func <= ir1(4 downto 0);
aca <= ir2(7 downto 6);
acb <= ir2(5 downto 4);
shOp <= ir2(3 downto 0);
imm <= ir2(5) & "0000" & ir2(4 downto 0);
imm2 <= ir2(3 downto 0);
ra <= ir2(5 downto 4);
rb <= ir2(3 downto 2);
END PROCESS mp;
--combinatorial logic
pass_logic <= '1' when ((op = "100") AND (func(2) = '1')) else '0';
rgEn <= '1' when ((op = "100") AND (func(2) = '0') AND (start = '1')) else '0';
-- shifter enable
shift <= '1' when (op = "010") else '0';
--limiter mapping
lmIn <= d1out;
lmfn <= shOp;
--mux and tristate mapping
--outEn <= '0';
outEn <= '1' when (op = "010" AND shOp(2) = '1') else '0';

regEn <= '1' when (start = '1' AND ((op ="000") OR (op = "001") OR (op = "010" A
ND shOp(3) = '0') OR (op = "100" AND func(2) = '1'))) else '0';
--alu inputs
aluI1 <= multout when (op = "001" AND func(2) = '0') else shtOut;
aluI2 <= imm when ((op = "000") AND (func(4) = '1')) else
d1out when (op = "001" AND func(2) = '0') else d2out;
--limiter outputs
pathOut <= lmOut when outEn = '1' else "ZZZZZZZZ";
--disp variable
disp <= '1' WHEN ((op = "011") OR (op = "010" AND shOp(3) = '1') OR (op = "100"
AND func(4) = '1')) ELSE '0';
--calculate address
addr <= (mah & mal) WHEN (disp = '1' AND start = '1') ELSE
--sp
pc;
--finish signal for states
finish <= '1' when (state = "101" AND NOT (op = "001")) else
'0' when (op = "111" AND func = "11111") else
'0' when (state = "101" AND op = "001" AND NOT(mstate = "10")) else
'1' when (mstate = "10") else '0';
-- Set variables for next state
nextstate <=
-- 0->1
"001" WHEN state = "000" ELSE
-- 1->2
"010" WHEN (state = "001" AND NOT (op = "111")) ELSE
-- 1->5
"101" WHEN (state = "001" AND op = "111") ELSE
-- 2->3
"011" WHEN (state = "010" AND (disp = '1')) ELSE
-- 2->5

"101" WHEN (state = "010" AND NOT (disp = '1')) ELSE


-- 3->4
"100" WHEN (state = "011") ELSE
-- 4->5
"101" WHEN (state = "100") ELSE
-- 5->5
"101" WHEN (state = "101" AND finish = '0') ELSE
-- 5->1
"001" WHEN (state = "101" AND finish = '1') ELSE
-- ?
"000";
-- Sequential logic
PROCESS (clk, reset)
BEGIN
IF (reset ='1') THEN
pc <= "1111111111111111";
ir1 <= "11100000";
ir2 <= "00000000";
state <= "000";
mah <= "00000000";
mal <= "00000000";
ELSIF (clk'event AND clk = '1') THEN
-- All transitions
state <= nextstate;
pc <= pc + "0000000000000001";
-- State 0->1 transition
IF (nextstate = "001" AND state = "000") THEN
ir1 <= data;
start <= '0';
--

finish <= '0';

END IF;
-- State 1->2 transition
IF (nextstate = "010" AND state = "001") THEN
ir2 <= data;
END IF;
-- State 1->5 transition
IF (nextstate = "101" AND state = "001") THEN
start <= '1';
END IF;
-- State 2->5 transition
IF (nextstate = "101" AND state = "010") THEN
start <= '1';
END IF;
-- State 2->3 transition
IF (nextstate = "011" AND state = "010") THEN
mah <= data;
END IF;
-- State 3->4 transition
IF (nextstate = "100" AND state = "011") THEN
mal <= data;
END IF;
-- State 4->5 transition
IF (nextstate = "101" AND state = "100") THEN
start <= '1';
END IF;
-- State 5->1 transition
IF (nextstate = "001" AND state = "101") THEN
ir1 <= data;
start <= '0';
--

finish <= '1';

END IF;
END IF;
END PROCESS;
-- mux for accumlators
regSel: PROCESS (clk, reset)
BEGIN
IF (reset ='1') THEN
a0 <= "0000000000";
a1 <= "0000000000";
a2 <= "0000000000";
a3 <= "0000000000";
ELSIF (clk='1' AND clk'event) THEN
IF (regEn = '1' AND NOT (op = "001")) THEN
CASE aca(1 DOWNTO 0) IS
WHEN "00" => a0 <= aluout;
WHEN "01" => a1 <= aluout;
WHEN "10" => a2 <= aluout;
WHEN OTHERS => a3 <= aluout;
END CASE;
END IF;
IF (regEn = '1' AND (op = "001" OR (op = "100" AND func(2) = '1'))) THEN
CASE aca(1 DOWNTO 0) IS
WHEN "00" => a0 <= multout;
WHEN "01" => a1 <= multout;
WHEN "10" => a2 <= multout;
WHEN OTHERS => a3 <= multout;
END CASE;
END IF;
END IF;
END PROCESS regSel;

-- register file input decision


reg_in: process (func)
BEGIN
IF (func(0) = '1') THEN
rin <= data(3 downto 0);
ELSIF (func(1) = '1') THEN
rin <= imm2;
ELSIF (func(3) = '1') THEN
CASE rb(1 downto 0) IS
WHEN "00" => rin <= r0;
WHEN "01" => rin <= r1;
WHEN "10" => rin <= r2;
WHEN OTHERS => rin <= r3;
END CASE;
ELSE rin <= "ZZZZ";
END IF;
END PROCESS reg_in;
-- mux for registers and load enable
reg: PROCESS (clk, reset)
BEGIN
IF (reset ='1') THEN
r0 <= "0000";
r1 <= "0000";
r2 <= "0000";
r3 <= "0000";
ELSIF (clk='1' AND clk'event) THEN
IF rgEn = '1' THEN
CASE ra(1 DOWNTO 0) IS
WHEN "00" => r0 <= rin;
WHEN "01" => r1 <= rin;

WHEN "10" => r2 <= rin;


WHEN OTHERS => r3 <= rin;
END CASE;
END IF;
END IF;
END PROCESS reg;
--demux for mul-1
demux1: PROCESS (ra)
BEGIN
CASE ra(1 DOWNTO 0) IS
WHEN "00" => mul1 <= r0;
WHEN "01" => mul1 <= r1;
WHEN "10" => mul1 <= r2;
WHEN OTHERS => mul1 <= r3;
END CASE;
END PROCESS demux1;
--demux for mul-2
demux2: PROCESS (ra, rb, func)
BEGIN
IF func(4) = '1' THEN
mul2 <= imm2;
ELSIF func(0) = '1' THEN
CASE ra(1 DOWNTO 0) IS
WHEN "00" => mul2 <= r0;
WHEN "01" => mul2 <= r1;
WHEN "10" => mul2 <= r2;
WHEN OTHERS => mul2 <= r3;
END CASE;
ELSIF func = "00100" THEN
CASE rb(1 DOWNTO 0) IS

WHEN "00" => mul2 <= r0;


WHEN "01" => mul2 <= r1;
WHEN "10" => mul2 <= r2;
WHEN OTHERS => mul2 <= r3;
END CASE;
ELSE
mul2 <= "ZZZZ";
END IF;
END PROCESS demux2;
-- demux for accumalators
-- to shifter & limiter
dmux1: PROCESS (aca)
BEGIN
CASE aca(1 DOWNTO 0) IS
WHEN "00" => d1out <= a0;
WHEN "01" => d1out <= a1;
WHEN "10" => d1out <= a2;
WHEN OTHERS => d1out <= a3;
END CASE;
END PROCESS dmux1;
-- to aluB
dmux2: PROCESS (acb)
BEGIN
CASE acb(1 DOWNTO 0) IS
WHEN "00" => d2out <= a0;
WHEN "01" => d2out <= a1;
WHEN "10" => d2out <= a2;
WHEN OTHERS => d2out <= a3;
END CASE;
END PROCESS dmux2;

--limiter
funct:PROCESS(lmIn, lmfn)
BEGIN
CASE lmfn IS
WHEN "1000" => --limit to eight (LIMA)
IF lmIn(8 DOWNTO 7) = "00" THEN
zz <= "0000" & lmIn(9) & lmIn(6 DOWNTO 0);
ELSE
zz <= "00" & lmIn(8 DOWNTO 7) & lmIn(9) & "1111111";
END IF;
WHEN "1001" => --limit to four (LIMF)
IF lmIn(8 DOWNTO 3) = "000000" THEN
zz <= "00000000" & lmIn(9) & lmIn(2 DOWNTO 0);
ELSE
zz <= lmIn(6 DOWNTO 3) & "0000" & lmIn(9) & "111";
END IF;
WHEN "1010" => zz <= "00" & lmIn(1 DOWNTO 0) & lmIn(9 DOWNTO 2);
te to eight (TNKA)

--trunca

WHEN "1011" => zz <= lmIn(3 DOWNTO 0) & lmIn(9) & lmIn(6 DOWNTO 4) & "0000";
--truncate to four (RNDF)
WHEN "1100" => zz <= "00" & lmIn(8 DOWNTO 7) & lmIn(9) & lmIn(6 DOWNTO 0);
--round to eight (RNDA)
WHEN "1101" => zz <= lmIn(6 DOWNTO 3) & lmIn(9) & "0000" & lmIn(2 DOWNTO 0);
--round to four (TNKF)
WHEN OTHERS => zz <= "00" & lmIn(9 DOWNTO 0);
END CASE;
lmFlag <= zz(11 DOWNTO 8);
lmOut <= zz(7 DOWNTO 0);
END PROCESS funct;
--calculate flags for mult
PROCESS (multout)
BEGIN

--pass lmIn

mulflag(0) <= '0';


mulflag(1) <= multout(9);
IF multout(9 DOWNTO 0) = "0000000000" THEN
mulflag(2) <= '1';
ELSE
mulflag(2) <= '0';
END IF;
mulflag(3) <= '0';
END PROCESS;
--calculate flags for special operations
spflag(0) <= (func(0) AND func(4));
spflag(1) <= (func(1) AND func(4));
spflag(2) <= (func(2) AND func(4));
spflag(3) <= tmpflag(3);
-- load flag registers
flg: PROCESS (clk)
BEGIN
IF (clk='1' AND clk'event) THEN
IF (start = '1') THEN
CASE op IS
WHEN "000" => ALUflag <= lmFlag & sflag & tmpflag;
WHEN "010" => ALUflag <= lmFlag & sflag & tmpflag;
WHEN "001" => ALUflag <= lmFlag & sflag & mulflag;
WHEN "111" => ALUflag <= lmFlag & sflag & spflag;
WHEN OTHERS => ALUflag <= lmFlag & sflag & "0000";
END CASE;
END IF;
END IF;
END PROCESS flg;
end path_arch;

--------------------------------------------------------------------------------------------------------- 10-bit ALU for DSP


library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity alu is
port (
inA: in STD_LOGIC_VECTOR (9 downto 0);
inB: in STD_LOGIC_VECTOR (9 downto 0);
fn: in STD_LOGIC_VECTOR (3 downto 0);
aluout: out STD_LOGIC_VECTOR (9 downto 0);
flags: out STD_LOGIC_VECTOR (3 downto 0)
);
end alu;

architecture alu_arch of alu is


signal z: std_logic_vector(10 downto 0);
begin
sort: PROCESS (fn, inA,inB)
BEGIN
CASE fn(3 DOWNTO 0) IS
WHEN "0000" => z <= ('0' & inA) + inB; --inA + inB
WHEN "0001" => z <= ('0' & inA) - inB; --inA -inB
WHEN "0010" => z <= '0' & (inA and inB);

--inA and inB

WHEN "0011" => z <= '0' & (inA or inB); --inA or inB
WHEN "0100" => z <= '0' & (inA xor inB);

--inA xor inB

WHEN "0101" => z <= ('0' & inA) - inB; --cmp inA and inB
WHEN "0110" => z <= ('0' & not inA);

--invert inA

WHEN "0111" => z <= ('0' & inA) + 1;

--increment inA

WHEN "1000" => z <= ('0' & inA) - 1;

--decrement inA

WHEN "1001" => z <= "00000000000";

--pass zero

WHEN "1010" => z <= 0 - ('0' & inA);

--negate inA

WHEN "1011" =>


IF inA(9) = '1' THEN
z <= '0' & ((not inA) + 1);
ELSE
z <= '0' & inA(9 DOWNTO 0);
END IF;
WHEN "1111" => z <= ('0'& inA); --pass inA
WHEN OTHERS => z <= "00000000000";

--pass zero

END CASE;
--flags: |overflow | zero | negative | carry|
flags(0) <= z(10);
flags(1) <= z(9);
IF z(9 DOWNTO 0) = "0000000000" THEN
flags(2) <= '1';
ELSE
flags(2) <= '0';
END IF;
CASE fn(3 DOWNTO 0) IS
WHEN "0000" => flags(3) <= (inA(9)and inB(9) and (not z(9))) or ((not inA(9)) an
d (not inB(9)) and z(9));
WHEN "0001" => flags(3) <= (inA(9)and inB(9) and (not z(9))) or ((not inA(9)) an
d (not inB(9)) and z(9));
WHEN "0101" => flags(3) <= (inA(9)and inB(9) and (not z(9))) or ((not inA(9)) an
d (not inB(9)) and z(9));
WHEN OTHERS => flags(3) <= '0';
END CASE;
CASE fn(3 DOWNTO 0) IS
WHEN "0101" => aluout <= inA(9 downto 0);

WHEN OTHERS => aluout <= z(9 downto 0);


END CASE;
END PROCESS sort;
end alu_arch;
--------------------------------------------------------------------------------------------------------- 10-bit shifter
library IEEE;
use IEEE.std_logic_1164.all;
entity shifter is
port (
shtIn: in STD_LOGIC_VECTOR (9 downto 0);
sfn: in STD_LOGIC_VECTOR (3 downto 0);
shtOut: out STD_LOGIC_VECTOR (9 downto 0);
shtFlag: out STD_LOGIC;
shEn: in std_logic
);
end shifter;
architecture shifter_arch of shifter is
SIGNAL z: std_logic_vector(10 downto 0);
BEGIN
funct:PROCESS(shtIn, sfn,shEn)
BEGIN
IF shEn = '1' THEN
CASE sfn IS
WHEN "0000" => z <= shtIn(9 DOWNTO 0) & '0';

--arithmatic shift left input

WHEN "0001" => z <= shtIn(0) & '0' & shtIn(9 DOWNTO 1); --arithmetic shift right
input
WHEN "0010" => z <= shtIn(0) & shtIn(9) & shtIn(9 DOWNTO 1);
right input
WHEN "0011" => z <= shtIn(9 DOWNTO 0) & shtIn(9);

--logical shift

--rotate left input

WHEN "0100" => z <= shtIn(0) & shtIn(0) & shtIn(9 DOWNTO 1);

--rotate right i

nput
WHEN "0101" =>
IF shtIn(3 DOWNTO 0) = "0000" THEN
z <= '0' & shtIn(9) & shtIn(8 DOWNTO 4) & "0000";

--round input

ELSE
z <= '1' & shtIn(9) & shtIn(8 DOWNTO 4) & "0000";
END IF;
WHEN "0110" => IF shtIn(8 DOWNTO 5) = "0000" THEN
z <= '0' & shtIn(9) & "0000" & shtIn(4 DOWNTO 0);

--truncate input

ELSE
z <= '1' & shtIn(9) & "0000" & shtIn(4 DOWNTO 0);
END IF;
WHEN OTHERS => z <= '0' & shtIn(9 DOWNTO 0);

--pass shtIn

END CASE;
ELSE
z <= '0' & shtIn(9 DOWNTO 0);
END IF;
shtFlag <= z(10);
shtOut <= z(9 DOWNTO 0);
END PROCESS funct;
end shifter_arch;
-------------------------------------------------------------------------------------------------- mult.vhd
-- A 4-bit, fixed-point, integer multiplier module

LIBRARY ieee;
USE ieee.std_logic_1164.all;

-- Standard logic

USE ieee.std_logic_unsigned.all; -- Arithmetic stuff


ENTITY mult IS
PORT(

clk : IN std_logic;
start : IN

std_logic;

pass : IN std_logic;
finish: IN

std_logic;

result: OUT std_logic_vector(9 DOWNTO 0);


mstate: BUFFER std_logic_vector(1 DOWNTO 0);
in0 : IN std_logic_vector(3 DOWNTO 0);
in1 : IN std_logic_vector(3 DOWNTO 0)
);
END mult;
ARCHITECTURE one OF mult IS
-- Signal definitions
SIGNAL product, nextproduct: std_logic_vector(7 DOWNTO 0);
SIGNAL count, nextcount: std_logic_vector(2 DOWNTO 0);
SIGNAL state,nextstate: std_logic_vector(1 DOWNTO 0);
SIGNAL mult,nextmult: std_logic_vector(3 DOWNTO 0);
SIGNAL answer: std_logic_vector(7 DOWNTO 0);
SIGNAL sum,temp: std_logic_vector(3 DOWNTO 0);
BEGIN
-- Combinatorial logic
result <= "00" & answer WHEN pass = '0' ELSE (in0(3) & "000000" & in0(2 downto 0
));
--

finish <= '1' WHEN state = "10" ELSE 'Z';

temp <= in0 WHEN mult(0) = '1' ELSE "0000";


sum <= temp + product(7 DOWNTO 4);
mstate <= state;
nextcount <= count + "001";
nextmult <= '0' & mult(3 DOWNTO 1);
nextproduct <= sum & product(3 DOWNTO 0);
nextstate <= "00" WHEN (state = "00" AND start='0') ELSE

"01" WHEN (state = "00" AND start = '1') ELSE


"01" WHEN (state = "01" AND count < "100") ELSE
"10" WHEN (state = "01" AND count = "100") ELSE
"10" WHEN (state = "10" AND start = '1') ELSE
"00";
-- Sequential logic
PROCESS(clk,in0,in1,start)
BEGIN
-- Initialization
IF (start = '0') THEN
count <= "000";
product <= "00000000";
answer <= "00000000";
state <= "00";
ELSIF (clk'event AND clk ='1') THEN
-- All transitions
state <= nextstate;
-- State 0->1 transition
IF (state = "00" AND nextstate = "01") THEN
mult <= in1;
END IF;
-- State 1->1 transition
IF (state = "01" AND nextstate = "01") THEN
-- Update count, mult each time
count <= nextcount;
mult <= nextmult;
-- Update product
product <= '0' & nextproduct(7 DOWNTO 1);
END IF;
-- State 1->2 transition

IF (nextstate = "10") THEN


answer <= product ;
END IF;
END IF;
END PROCESS;
END one;
-------------------------------------------------------------------------------------------------

You might also like