DSP VHDL FILE

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" AND 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); --truncate to eight (TNKA)

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); --pass lmIn

END CASE;

lmFlag <= zz(11 DOWNTO 8);

lmOut <= zz(7 DOWNTO 0);

END PROCESS funct;

--calculate flags for mult

PROCESS (multout)

BEGIN

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)) and (not inB(9)) and z(9));

WHEN "0001" => flags(3) <= (inA(9)and inB(9) and (not z(9))) or ((not inA(9)) and (not inB(9)) and z(9));

WHEN "0101" => flags(3) <= (inA(9)and inB(9) and (not z(9))) or ((not inA(9)) and (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); --logical shift right input

WHEN "0011" => z <= shtIn(9 DOWNTO 0) & shtIn(9); --rotate left input

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

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;

--------------------------------------------------------------------------------------------------