8 bit pipelined calculator in VHDL
Objective: The objective of this laboratory is to implement a 8-bit pipelined calculator on VHDL simulator.Specification of the calculator: The pipelined calculator is based on the calculator you build for the previous lab. The main difference is the handling of the structural hazard on the two registersand the data hazard. All the instructions should be divided into 3 stages, ID, EXE and WB. Each stage uses one cycle. Table 1 describes what each instruction does at every stage. Your implementation must show that the three instructions are completed in three steps.
All numbers are displayed in decimal format as in the previous lab, even though instructionsand data are read as binary numbers. You should adapt your implementation of the adder/subtractor from the previous lab in thiswork. You can make necessary and reasonable changes to your code, but the base line is that youcannot directly use the “+” and “-“ operators in VHDL to do the adding or the subtracting. Thesubtracted might produce negative results, which should be shown on the Seven Segment Displayas such. Your main design task is to handle the data hazards between instructions, for example if the instruction “load 4 r0” is immediately followed by “add r0 r1 r2”, since r0 is only available after the WB stage of the load instruction, you should insert NOP(s) before the add instruction to make sure the “add” reads the right r0 value.
Task 1: Multiplex the registers in one cycle In the previous lab, both the reading and writing of registers happen on the rising edge of cycle. Your first task is to change that into writing on rising edges and reading on dropping edges.
Task 2: Insertion of bubbles into pipeline A calculator instruction might be data dependent on its preceding instruction. For example, if “load 4 r0” is immediately followed by “add r0 r1 r2”, the second instruction should wait one cycle because r0 is not ready yet, i.e., the correct values being written in the next cycle. One way to handle it is to insert a bubble. At the beginning of the ID stage, decide whether to proceed with the current instruction, or to hold off the firing of the current instruction and replace it with a NOP. Your implementation should be based on the product from Task 1, so that at most one bubble needs to be inserted. (Think if we don’t have Task 1, how many bubbles we might need to insert?) The main implementation challenge here is to figure out the logic for when to insert bubble. Task 3: Data forwarding Another way to handle the data dependency is to introducing a controlled data forwarding path from the ALU output to the ALU input, i.e., the end of the EXE stage to the beginning of the EXE stage. In our 3-stage calculator, we just need either bubble insertion or the data forwarding to handle data dependency (Why?), not both. So your implementation will be based the product of Task 1. The main implementation challenges are how many data forwarding paths we need (I sit one or two?), how they merge with existing wires, and when to activate the data forwarding paths. Expected output: The expected result is that at the end every cycle, except the first two, we expect a new result appearing on the display. You should design testing sequences that cover different scenarios, for example, needing bubble insertion/forwarding or not.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity fulladder is
Port (
a : in std_logic;
b : in std_logic;
ci : in std_logic;
s : out std_logic;
co : out std_logic
);
end fulladder;
architecture bh of fulladder is
begin
s <= a XOR b XOR ci;
co <= (a AND b) or (ci and a) or (ci and b);
end bh;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use STD.TEXTIO.ALL;
use work.all;
entity alu is
Port (
a : in STD_LOGIC_VECTOR (7 downto 0);
b : in STD_LOGIC_VECTOR (7 downto 0);
op : in STD_LOGIC_VECTOR (1 downto 0);
s : out STD_LOGIC_VECTOR (7 downto 0)
);
end alu;
architecture structural of alu is
component fulladder
Port (
a : in std_logic;
b : in std_logic;
ci : in std_logic;
s : out std_logic;
co : out std_logic
);
end component;
signal cin : std_logic;
signal ax : std_logic_vector(3 downto 0):=”0000″;
signal bx : std_logic_vector(7 downto 0):=”00000000″;
signal cc : std_logic_vector(7 downto 0):=”00000000″;
begin
process(op)
variable trace_line : line;
begin
if op=”11″ then
–report “Value: ” & integer’image(to_integer(signed(b)));
write(trace_line,string'(“Value:”));
write(trace_line,to_integer(signed(b)),field=>4, justified => right);
writeline(output, trace_line);
end if;
end process;
cin<= op(0) and (not op(1));
bx(0)<= (b(0) xor op(0)) and (not op(1));
U1: entity work.fulladder port map (a=>a(0),b=>bx(0),ci=>cin,s=>s(0),co=>cc(0));
bx(1)<= (b(1) xor op(0)) and (not op(1));
U2: entity work.fulladder port map (a=>a(1),b=>bx(1),ci=>cc(0),s=>s(1),co=>cc(1));
bx(2)<= (b(2) xor op(0)) and (not op(1));
U3: entity work.fulladder port map (a=>a(2),b=>bx(2),ci=>cc(1),s=>s(2),co=>cc(2));
bx(3)<= (b(3) xor op(0)) and (not op(1));
U4: entity work.fulladder port map (a=>a(3),b=>bx(3),ci=>cc(2),s=>s(3),co=>cc(3));
ax(0)<= (a(4) and (not op(1))) or (a(3) and op(1));
bx(4)<= (b(4) xor op(0)) and (not op(1));
U5: entity work.fulladder port map (a=>ax(0),b=>bx(4),ci=>cc(3),s=>s(4),co=>cc(4));
ax(1)<= (a(5) and (not op(1))) or (a(3) and op(1));
bx(5)<= (b(5) xor op(0)) and (not op(1));
U6: entity work.fulladder port map (a=>ax(1),b=>bx(5),ci=>cc(4),s=>s(5),co=>cc(5));
ax(2)<= (a(6) and (not op(1))) or (a(3) and op(1));
bx(6)<= (b(6) xor op(0)) and (not op(1));
U7: entity work.fulladder port map (a=>ax(2),b=>bx(6),ci=>cc(5),s=>s(6),co=>cc(6));
ax(3)<= (a(7) and (not op(1))) or (a(3) and op(1));
bx(7)<= (b(7) xor op(0)) and (not op(1));
U8: entity work.fulladder port map (a=>ax(3),b=>bx(7),ci=>cc(6),s=>s(7),co=>cc(7));
end structural;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity comp1 is
Port (
a : in std_logic;
b : in std_logic;
iEQ : in std_logic;
iGT : in std_logic;
iLT : in std_logic;
oEQ : out std_logic;
oGT : out std_logic;
oLT : out std_logic
);
end comp1;
architecture Behavioral of comp1 is
begin
oEQ<= (not (a xor b)) and iEQ;
oGT<= (a and (not b) and iEQ) or iGT;
oLT<= ((not a) and b and iEQ) or iLT;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity comparator is
Port (
a : in STD_LOGIC_VECTOR (7 downto 0);
b : in STD_LOGIC_VECTOR (7 downto 0);
EQ : out std_logic;
GT : out std_logic;
LT : out std_logic
);
end comparator;
architecture structural of comparator is
component comp1
Port (
a : in std_logic;
b : in std_logic;
iEQ : in std_logic;
iGT : in std_logic;
iLT : in std_logic;
oEQ : out std_logic;
oGT : out std_logic;
oLT : out std_logic
);
end component;
signal eqx, gtx, ltx : STD_LOGIC_VECTOR (6 downto 0):=”0000000″;
begin
C1 : entity work.comp1 port map(a=>a(7),b=>b(7),iEQ=>’1′,iGT=>’0′,iLT=>’0′,oEQ=>eqx(6),oGT=>gtx(6),oLT=>ltx(6));
C2 : entity work.comp1 port map(a=>a(6),b=>b(6),iEQ=>eqx(6),iGT=>gtx(6),iLT=>ltx(6),oEQ=>eqx(5),oGT=>gtx(5),oLT=>ltx(5));
C3 : entity work.comp1 port map(a=>a(5),b=>b(5),iEQ=>eqx(5),iGT=>gtx(5),iLT=>ltx(5),oEQ=>eqx(4),oGT=>gtx(4),oLT=>ltx(4));
C4 : entity work.comp1 port map(a=>a(4),b=>b(4),iEQ=>eqx(4),iGT=>gtx(4),iLT=>ltx(4),oEQ=>eqx(3),oGT=>gtx(3),oLT=>ltx(3));
C5 : entity work.comp1 port map(a=>a(3),b=>b(3),iEQ=>eqx(3),iGT=>gtx(3),iLT=>ltx(3),oEQ=>eqx(2),oGT=>gtx(2),oLT=>ltx(2));
C6 : entity work.comp1 port map(a=>a(2),b=>b(2),iEQ=>eqx(2),iGT=>gtx(2),iLT=>ltx(2),oEQ=>eqx(1),oGT=>gtx(1),oLT=>ltx(1));
C7 : entity work.comp1 port map(a=>a(1),b=>b(1),iEQ=>eqx(1),iGT=>gtx(1),iLT=>ltx(1),oEQ=>eqx(0),oGT=>gtx(0),oLT=>ltx(0));
C8 : entity work.comp1 port map(a=>a(0),b=>b(0),iEQ=>eqx(0),iGT=>gtx(0),iLT=>ltx(0),oEQ=>EQ,oGT=>GT,oLT=>LT);
end structural;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity regfile is
Port (
rreg1 :in STD_LOGIC_VECTOR (1 downto 0);
rreg2 :in STD_LOGIC_VECTOR (1 downto 0);
wrreg :in STD_LOGIC_VECTOR (1 downto 0);
wdata :in STD_LOGIC_VECTOR (7 downto 0);
clk :in std_logic;
wr :in std_logic;
data1 :out STD_LOGIC_VECTOR (7 downto 0);
data2 :out STD_LOGIC_VECTOR (7 downto 0)
);
end regfile;
architecture Behavioral of regfile is
type regarray is array (0 to 3) of std_logic_vector(7 downto 0);
signal regs: regarray:=(others=>”00000000″);
begin
data1<=regs(to_integer(unsigned(rreg1)));
data2<=regs(to_integer(unsigned(rreg2)));
process(clk)
begin
if falling_edge(clk) then
if wr=’1′ then
regs(to_integer(unsigned(wrreg)))<= wdata;
end if;
end if;
end process;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity mux2x1_8 is
Port(
a : in STD_LOGIC_VECTOR (7 downto 0);
b : in STD_LOGIC_VECTOR (7 downto 0);
s : in std_logic;
c : out STD_LOGIC_VECTOR (7 downto 0)
);
end mux2x1_8;
architecture Behavior of mux2x1_8 is
begin
c(0) <= (not(s) and a(0)) or (s and b(0));
c(1) <= (not(s) and a(1)) or (s and b(1));
c(2) <= (not(s) and a(2)) or (s and b(2));
c(3) <= (not(s) and a(3)) or (s and b(3));
c(4) <= (not(s) and a(4)) or (s and b(4));
c(5) <= (not(s) and a(5)) or (s and b(5));
c(6) <= (not(s) and a(6)) or (s and b(6));
c(7) <= (not(s) and a(7)) or (s and b(7));
end Behavior;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity mux2x1_2 is
Port(
a : in STD_LOGIC_VECTOR (1 downto 0);
b : in STD_LOGIC_VECTOR (1 downto 0);
s : in std_logic;
c : out STD_LOGIC_VECTOR (1 downto 0)
);
end mux2x1_2;
architecture Behavior of mux2x1_2 is
begin
c(0) <= (not(s) and a(0)) or (s and b(0));
c(1) <= (not(s) and a(1)) or (s and b(1));
end Behavior;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity control is
Port (
opcode : in STD_LOGIC_VECTOR (1 downto 0);
clk : in std_logic;
eq : in std_logic;
inc : in STD_LOGIC_VECTOR (1 downto 0);
wr : out std_logic;
dsel : out std_logic;
aluop : out STD_LOGIC_VECTOR (1 downto 0);
pcinc : out STD_LOGIC_VECTOR (1 downto 0)
);
end control;
architecture Behavioral of control is
begin
wr <= not (opcode(0) and opcode(1));
dsel <= ‘1’ when opcode =”10″ else ‘0’;
aluop <= “00” when (inc/=”00″ and opcode=”11″) else opcode;
pcinc <= inc when (inc/=”00″ and opcode=”11″ and eq =’1′) else “01”;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity rom is
Port (
address : in STD_LOGIC_VECTOR (7 downto 0);
data : out STD_LOGIC_VECTOR (7 downto 0)
);
end rom;
architecture Behavioral of rom is
begin
with address select data <=
“10010011” when “00000000”, — LOAD BX 0010 (BX =2)
“10100000” when “00000001”, — LOAD CX 0000 (CX = 0)
“00011011” when “00000010”, — ADD BX CX DX (DX = 2)
“00011100” when “00000011”, — ADD BX DX AX (AX = 2*2 = 4)
“00011100” when “00000100”, — ADD BX DX AX (AX = 2*3 = 6)
“10110110” when “00000101”, — LOAD DX 0110 (DX = 6)
“11001110” when “00000110”, — CMP AX DX 1 (skip next instruction if AX=DX)
“10000001” when “00000111”, — LOAD AX 0001 (A=1, should be skipped)
“01001101” when “00001000”, — SUB AX DX BX (BX = AX-DX = 0)
“11011011” when “00001001”, — CMP BX CX 2 (skip next 2 instructions if BX=CX)
“10000000” when “00001010”, — LOAD AX 0000 (A=0, should be skipped)
“10000001” when “00001011”, — LOAD AX 0001 (A=1, should be skipped)
“00001000” when “00001100”, — ADD AX,CX,AX (A=6+0 = 6)
“11000000” when “00001101”, — PRINT AX
“10001111” when “00001110”, — LOAD AX 1111 (A=-1)
“11000000” when “00001111”, — PRINT AX
“00000000” when others; — ADD AX AX AX
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity incrementer is
Port (
a : in STD_LOGIC_VECTOR (7 downto 0);
inc : in STD_LOGIC_VECTOR (1 downto 0);
s : out STD_LOGIC_VECTOR (7 downto 0)
);
end incrementer;
architecture structural of incrementer is
component fulladder
Port (
a : in std_logic;
b : in std_logic;
ci : in std_logic;
s : out std_logic;
co : out std_logic
);
end component;
signal cc : std_logic_vector(7 downto 0):=”00000000″;
begin
U1: entity work.fulladder port map (a=>a(0),b=>inc(0),ci=>’0′,s=>s(0),co=>cc(0));
U2: entity work.fulladder port map (a=>a(1),b=>inc(1),ci=>cc(0),s=>s(1),co=>cc(1));
U3: entity work.fulladder port map (a=>a(2),b=>’0′,ci=>cc(1),s=>s(2),co=>cc(2));
U4: entity work.fulladder port map (a=>a(3),b=>’0′,ci=>cc(2),s=>s(3),co=>cc(3));
U5: entity work.fulladder port map (a=>a(4),b=>’0′,ci=>cc(3),s=>s(4),co=>cc(4));
U6: entity work.fulladder port map (a=>a(5),b=>’0′,ci=>cc(4),s=>s(5),co=>cc(5));
U7: entity work.fulladder port map (a=>a(6),b=>’0′,ci=>cc(5),s=>s(6),co=>cc(6));
U8: entity work.fulladder port map (a=>a(7),b=>’0′,ci=>cc(6),s=>s(7),co=>cc(7));
end structural;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity PC is
Port (
rst : in std_logic;
nxt : in STD_LOGIC_VECTOR (1 downto 0);
clk : in std_logic;
q : out STD_LOGIC_VECTOR (7 downto 0)
);
end PC;
architecture Behavioral of PC is
component incrementer
Port (
a : in STD_LOGIC_VECTOR (7 downto 0);
inc : in STD_LOGIC_VECTOR (1 downto 0);
s : out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
signal qq : STD_LOGIC_VECTOR (7 downto 0):=”00000000″;
signal inc : STD_LOGIC_VECTOR (7 downto 0):=”00000000″;
begin
I1: entity work.incrementer port map(a=>qq, inc=>nxt, s=>inc);
process(clk,rst)
begin
if rst=’1′ then
qq<=”00000000″;
elsif rising_edge(clk) then
qq<=inc;
end if;
end process;
q<=qq;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity datapath is
Port (
rst : in std_logic;
clk : in std_logic
);
end datapath;
architecture Behavioral of datapath is
component alu
Port (
a : in STD_LOGIC_VECTOR (7 downto 0);
b : in STD_LOGIC_VECTOR (7 downto 0);
op : in std_logic;
s : out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
component comparator
Port (
a : in STD_LOGIC_VECTOR (7 downto 0);
b : in STD_LOGIC_VECTOR (7 downto 0);
EQ : out std_logic;
GT : out std_logic;
LT : out std_logic
);
end component;
component regfile
Port (
rreg1 :in STD_LOGIC_VECTOR (1 downto 0);
rreg2 :in STD_LOGIC_VECTOR (1 downto 0);
wrreg :in STD_LOGIC_VECTOR (1 downto 0);
wdata :in STD_LOGIC_VECTOR (7 downto 0);
clk :in std_logic;
wr :in std_logic;
data1 :out STD_LOGIC_VECTOR (7 downto 0);
data2 :out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
component mux2x1_8
Port(
a : in STD_LOGIC_VECTOR (7 downto 0);
b : in STD_LOGIC_VECTOR (7 downto 0);
s : in std_logic;
c : out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
component mux2x1_2
Port(
a : in STD_LOGIC_VECTOR (1 downto 0);
b : in STD_LOGIC_VECTOR (1 downto 0);
s : in std_logic;
c : out STD_LOGIC_VECTOR (1 downto 0)
);
end component;
component control
Port (
opcode : in STD_LOGIC_VECTOR (1 downto 0);
clk : in std_logic;
eq : in std_logic;
inc : in STD_LOGIC_VECTOR (1 downto 0);
wr : out std_logic;
dsel : out std_logic;
aluop : out STD_LOGIC_VECTOR (1 downto 0)
);
end component;
component PC
Port (
rst : in std_logic;
nxt : in STD_LOGIC_VECTOR (1 downto 0);
clk : in std_logic;
q : out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
component rom
Port (
address : in STD_LOGIC_VECTOR (7 downto 0);
data : out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
signal nxt : STD_LOGIC_VECTOR (1 downto 0):=”01″; — default pc increment
signal address: STD_LOGIC_VECTOR (7 downto 0):=”00000000″;
signal inst : STD_LOGIC_VECTOR (7 downto 0):=”00000000″;
signal eq,lt,gt : std_logic:=’0′;
signal op : STD_LOGIC_VECTOR (1 downto 0):=”00″;
signal opcode : STD_LOGIC_VECTOR (1 downto 0):=”00″;
signal r1 : STD_LOGIC_VECTOR (1 downto 0):=”00″;
signal r2 : STD_LOGIC_VECTOR (1 downto 0):=”00″;
signal r3 : STD_LOGIC_VECTOR (1 downto 0):=”00″;
signal rdest : STD_LOGIC_VECTOR (1 downto 0):=”00″;
signal imm : STD_LOGIC_VECTOR (7 downto 0):=”00000000″;
signal d1, d2, d3, aluout: STD_LOGIC_VECTOR (7 downto 0):=”00000000″;
signal wr, dsel : std_logic:=’0′;
begin
pc1: entity work.PC port map(rst=>rst, nxt=>nxt, clk=>clk, q=>address);
rom1: entity work.rom port map(address=>address, data=>inst);
opcode <= inst(7) & inst (6);
r1 <= inst(5) & inst (4);
r2 <= inst(3) & inst (2);
r3 <= inst(1) & inst (0);
imm <= “0000” & inst(3) & inst (2) & inst(1) & inst (0);
ctl: entity work.control port map(opcode=>opcode, clk=>clk, eq=>eq, inc=>r3, wr=>wr, dsel=>dsel, aluop=>op, pcinc=>nxt);
mux1: entity work.mux2x1_2 port map(a=>r3,b=>r1,s=>dsel,c=>rdest);
regs: entity work.regfile port map(rreg1=>r1, rreg2=>r2, wrreg=>rdest, wdata=>aluout, clk=>clk, wr=>wr, data1=>d1, data2=>d2);
mux2: entity work.mux2x1_8 port map(a=>d1,b=>imm,s=>dsel,c=>d3);
alu1: entity work.alu port map(a=>d3, b=>d2, op=>op, s=>aluout);
comp : entity work.comparator port map(a=>d1, b=>d2, EQ=>eq, GT=>gt, LT=>lt);
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity testbench is
end entity testbench;
architecture dataflow of testbench is
component datapath
Port (
rst : in std_logic;
clk : in std_logic
);
end component;
signal clk : std_logic := ‘0’;
signal rst : std_logic := ‘0’;
begin
clk <= not clk after 10 ns;
calc : entity work.datapath port map(rst=>rst, clk=>clk);
testprocess: process is
begin
rst <= ‘1’;
wait for 10 ns;
rst <= ‘0’;
wait for 400 ns;
end process testprocess;
end architecture dataflow;
Solution
Calculator
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity fulladder is
Port (
a : in std_logic;
b : in std_logic;
ci : in std_logic;
s : out std_logic;
co : out std_logic
);
end fulladder;
architecture bh of fulladder is
begin
s <= a XOR b XOR ci;
co <= (a AND b) or (ci and a) or (ci and b);
end bh;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity alu is
Port (
a : in STD_LOGIC_VECTOR (7 downto 0);
b : in STD_LOGIC_VECTOR (7 downto 0);
op : in STD_LOGIC_VECTOR (1 downto 0);
s : out STD_LOGIC_VECTOR (7 downto 0)
);
end alu;
architecture structural of alu is
component fulladder
Port (
a : in std_logic;
b : in std_logic;
ci : in std_logic;
s : out std_logic;
co : out std_logic
);
end component;
signal cin : std_logic;
signal ax : std_logic_vector(3 downto 0):=”0000″;
signal bx : std_logic_vector(7 downto 0):=”00000000″;
signal cc : std_logic_vector(7 downto 0):=”00000000″;
begin
cin<= op(0) and (not op(1));
bx(0)<= (b(0) xor op(0)) and (not op(1));
U1: entity work.fulladder port map (a=>a(0),b=>bx(0),ci=>cin,s=>s(0),co=>cc(0));
bx(1)<= (b(1) xor op(0)) and (not op(1));
U2: entity work.fulladder port map (a=>a(1),b=>bx(1),ci=>cc(0),s=>s(1),co=>cc(1));
bx(2)<= (b(2) xor op(0)) and (not op(1));
U3: entity work.fulladder port map (a=>a(2),b=>bx(2),ci=>cc(1),s=>s(2),co=>cc(2));
bx(3)<= (b(3) xor op(0)) and (not op(1));
U4: entity work.fulladder port map (a=>a(3),b=>bx(3),ci=>cc(2),s=>s(3),co=>cc(3));
ax(0)<= (a(4) and (not op(1) or op(0))) or (a(3) and op(1) and not op(0));
bx(4)<= (b(4) xor op(0)) and (not op(1));
U5: entity work.fulladder port map (a=>ax(0),b=>bx(4),ci=>cc(3),s=>s(4),co=>cc(4));
ax(1)<= (a(5) and (not op(1) or op(0))) or (a(3) and op(1) and not op(0));
bx(5)<= (b(5) xor op(0)) and (not op(1));
U6: entity work.fulladder port map (a=>ax(1),b=>bx(5),ci=>cc(4),s=>s(5),co=>cc(5));
ax(2)<= (a(6) and (not op(1) or op(0))) or (a(3) and op(1) and not op(0));
bx(6)<= (b(6) xor op(0)) and (not op(1));
U7: entity work.fulladder port map (a=>ax(2),b=>bx(6),ci=>cc(5),s=>s(6),co=>cc(6));
ax(3)<= (a(7) and (not op(1) or op(0))) or (a(3) and op(1) and not op(0));
bx(7)<= (b(7) xor op(0)) and (not op(1));
U8: entity work.fulladder port map (a=>ax(3),b=>bx(7),ci=>cc(6),s=>s(7),co=>cc(7));
end structural;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity comp1 is
Port (
a : in std_logic;
b : in std_logic;
iEQ : in std_logic;
iGT : in std_logic;
iLT : in std_logic;
oEQ : out std_logic;
oGT : out std_logic;
oLT : out std_logic
);
end comp1;
architecture Behavioral of comp1 is
begin
oEQ<= (not (a xor b)) and iEQ;
oGT<= (a and (not b) and iEQ) or iGT;
oLT<= ((not a) and b and iEQ) or iLT;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.all;
entity comparator is
Port (
a : in STD_LOGIC_VECTOR (7 downto 0);
b : in STD_LOGIC_VECTOR (7 downto 0);
EQ : out std_logic;
GT : out std_logic;
LT : out std_logic
);
end comparator;
architecture structural of comparator is
component comp1
Port (
a : in std_logic;
b : in std_logic;
iEQ : in std_logic;
iGT : in std_logic;
iLT : in std_logic;
oEQ : out std_logic;
oGT : out std_logic;
oLT : out std_logic
);
end component;
signal eqx, gtx, ltx : STD_LOGIC_VECTOR (6 downto 0):=”0000000″;
begin
C1 : entity work.comp1 port map(a=>a(7),b=>b(7),iEQ=>’1′,iGT=>’0′,iLT=>’0′,oEQ=>eqx(6),oGT=>gtx(6),oLT=>ltx(6));
C2 : entity work.comp1 port map(a=>a(6),b=>b(6),iEQ=>eqx(6),iGT=>gtx(6),iLT=>ltx(6),oEQ=>eqx(5),oGT=>gtx(5),oLT=>ltx(5));
C3 : entity work.comp1 port map(a=>a(5),b=>b(5),iEQ=>eqx(5),iGT=>gtx(5),iLT=>ltx(5),oEQ=>eqx(4),oGT=>gtx(4),oLT=>ltx(4));
C4 : entity work.comp1 port map(a=>a(4),b=>b(4),iEQ=>eqx(4),iGT=>gtx(4),iLT=>ltx(4),oEQ=>eqx(3),oGT=>gtx(3),oLT=>ltx(3));
C5 : entity work.comp1 port map(a=>a(3),b=>b(3),iEQ=>eqx(3),iGT=>gtx(3),iLT=>ltx(3),oEQ=>eqx(2),oGT=>gtx(2),oLT=>ltx(2));
C6 : entity work.comp1 port map(a=>a(2),b=>b(2),iEQ=>eqx(2),iGT=>gtx(2),iLT=>ltx(2),oEQ=>eqx(1),oGT=>gtx(1),oLT=>ltx(1));
C7 : entity work.comp1 port map(a=>a(1),b=>b(1),iEQ=>eqx(1),iGT=>gtx(1),iLT=>ltx(1),oEQ=>eqx(0),oGT=>gtx(0),oLT=>ltx(0));
C8 : entity work.comp1 port map(a=>a(0),b=>b(0),iEQ=>eqx(0),iGT=>gtx(0),iLT=>ltx(0),oEQ=>EQ,oGT=>GT,oLT=>LT);
end structural;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity regfile is
Port (
rreg1 :in STD_LOGIC_VECTOR (1 downto 0);
rreg2 :in STD_LOGIC_VECTOR (1 downto 0);
wrreg :in STD_LOGIC_VECTOR (1 downto 0);
wdata :in STD_LOGIC_VECTOR (7 downto 0);
clk :in std_logic;
wr :in std_logic;
data1 :out STD_LOGIC_VECTOR (7 downto 0);
data2 :out STD_LOGIC_VECTOR (7 downto 0)
);
end regfile;
architecture Behavioral of regfile is
type regarray is array (0 to 3) of std_logic_vector(7 downto 0);
signal regs: regarray:=(others=>”00000000″);
begin
data1<=regs(to_integer(unsigned(rreg1)));
data2<=regs(to_integer(unsigned(rreg2)));
process(clk)
begin
if falling_edge(clk) then
if wr=’1′ then
regs(to_integer(unsigned(wrreg)))<= wdata;
end if;
end if;
end process;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity mux2x1_8 is
Port(
a : in STD_LOGIC_VECTOR (7 downto 0);
b : in STD_LOGIC_VECTOR (7 downto 0);
s : in std_logic;
c : out STD_LOGIC_VECTOR (7 downto 0)
);
end mux2x1_8;
architecture Behavior of mux2x1_8 is
begin
c(0) <= (not(s) and a(0)) or (s and b(0));
c(1) <= (not(s) and a(1)) or (s and b(1));
c(2) <= (not(s) and a(2)) or (s and b(2));
c(3) <= (not(s) and a(3)) or (s and b(3));
c(4) <= (not(s) and a(4)) or (s and b(4));
c(5) <= (not(s) and a(5)) or (s and b(5));
c(6) <= (not(s) and a(6)) or (s and b(6));
c(7) <= (not(s) and a(7)) or (s and b(7));
end Behavior;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity mux2x1_2 is
Port(
a : in STD_LOGIC_VECTOR (1 downto 0);
b : in STD_LOGIC_VECTOR (1 downto 0);
s : in std_logic;
c : out STD_LOGIC_VECTOR (1 downto 0)
);
end mux2x1_2;
architecture Behavior of mux2x1_2 is
begin
c(0) <= (not(s) and a(0)) or (s and b(0));
c(1) <= (not(s) and a(1)) or (s and b(1));
end Behavior;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity control is
Port (
opcode: in STD_LOGIC_VECTOR (1 downto 0);
inc : in STD_LOGIC_VECTOR (1 downto 0);
clk : in std_logic;
wr : out std_logic;
dsel : out std_logic;
aluop : out STD_LOGIC_VECTOR (1 downto 0);
jmp : out std_logic
);
end control;
architecture Behavioral of control is
begin
wr <= not (opcode(0) and opcode(1));
dsel <= ‘1’ when opcode =”10″ else ‘0’;
aluop <= opcode; –“10″ when (inc/=”00″ and opcode=”11”) else opcode;
jmp <= (inc(1) and opcode(0) and opcode(1));
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity rom is
Port (
address : in STD_LOGIC_VECTOR (7 downto 0);
data : out STD_LOGIC_VECTOR (7 downto 0)
);
end rom;
architecture Behavioral of rom is
begin
with address select data <=
“10000101” when “00000000”, — LOAD AX 0101 (AX = 5)
“00000000” when “00000001”, — ADD AX AX AX (AX = 5*2 = 10)
“00000000” when “00000010”, — ADD AX AX AX (AX = 5*4 = 20)
“10010100” when “00000011”, — LOAD BX 0100 (BX = 4)
“01000101” when “00000100”, — SUB AX BX BX (BX = AX-BX = 20-4=16)
“00010101” when “00000101”, — ADD BX BX BX (BX = 16*2 = 32)
“10101000” when “00000110”, — LOAD CX 1000 (CX = -8)
“11000000” when “00000111”, — PRINT AX
“11010000” when “00001000”, — PRINT BX
“11100000” when “00001001”, — PRINT CX
“11000001” when others; — NOP
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity incrementer is
Port (
a : in STD_LOGIC_VECTOR (7 downto 0);
inc : in STD_LOGIC_VECTOR (1 downto 0);
s : out STD_LOGIC_VECTOR (7 downto 0)
);
end incrementer;
architecture structural of incrementer is
component fulladder
Port (
a : in std_logic;
b : in std_logic;
ci : in std_logic;
s : out std_logic;
co : out std_logic
);
end component;
signal cc : std_logic_vector(7 downto 0):=”00000000″;
begin
U1: entity work.fulladder port map (a=>a(0),b=>inc(0),ci=>’0′,s=>s(0),co=>cc(0));
U2: entity work.fulladder port map (a=>a(1),b=>inc(1),ci=>cc(0),s=>s(1),co=>cc(1));
U3: entity work.fulladder port map (a=>a(2),b=>’0′,ci=>cc(1),s=>s(2),co=>cc(2));
U4: entity work.fulladder port map (a=>a(3),b=>’0′,ci=>cc(2),s=>s(3),co=>cc(3));
U5: entity work.fulladder port map (a=>a(4),b=>’0′,ci=>cc(3),s=>s(4),co=>cc(4));
U6: entity work.fulladder port map (a=>a(5),b=>’0′,ci=>cc(4),s=>s(5),co=>cc(5));
U7: entity work.fulladder port map (a=>a(6),b=>’0′,ci=>cc(5),s=>s(6),co=>cc(6));
U8: entity work.fulladder port map (a=>a(7),b=>’0′,ci=>cc(6),s=>s(7),co=>cc(7));
end structural;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity PC is
Port (
rst : in std_logic;
a : in STD_LOGIC_VECTOR (7 downto 0);
clk : in std_logic;
q : out STD_LOGIC_VECTOR (7 downto 0)
);
end PC;
architecture Behavioral of PC is
begin
process(clk,rst)
begin
if rst=’1′ then
q<=”00000000″;
elsif falling_edge(clk) then
q<=a;
end if;
end process;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity PipeStageID is
Port (
a : in STD_LOGIC_VECTOR (7 downto 0);
rst : in std_logic;
clk : in std_logic;
q : out STD_LOGIC_VECTOR (7 downto 0)
);
end PipeStageID;
architecture Behavioral of PipeStageID is
begin
process(clk,rst)
begin
if rst=’1′ then
q<=”11000001″; –(NOP)
elsif rising_edge(clk) then
q<=a;
end if;
end process;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity PipeStageEXE is
Port (
d1 : in STD_LOGIC_VECTOR (7 downto 0);
d2 : in STD_LOGIC_VECTOR (7 downto 0);
d3 : in STD_LOGIC_VECTOR (7 downto 0);
r1 : in STD_LOGIC_VECTOR (1 downto 0);
r2 : in STD_LOGIC_VECTOR (1 downto 0);
r3 : in STD_LOGIC_VECTOR (1 downto 0);
ALUsrc : in std_logic;
ALUop : in STD_LOGIC_VECTOR (1 downto 0);
RegWrite: in std_logic;
jmp : in std_logic;
rst : in std_logic;
clk : in std_logic;
qd1 : out STD_LOGIC_VECTOR (7 downto 0);
qd2 : out STD_LOGIC_VECTOR (7 downto 0);
qd3 : out STD_LOGIC_VECTOR (7 downto 0);
qr1 : out STD_LOGIC_VECTOR (1 downto 0);
qr2 : out STD_LOGIC_VECTOR (1 downto 0);
qr3 : out STD_LOGIC_VECTOR (1 downto 0);
qsrc : out std_logic;
qop : out STD_LOGIC_VECTOR (1 downto 0);
qwr : out std_logic;
qjmp : out std_logic
);
end PipeStageEXE;
architecture Behavioral of PipeStageEXE is
begin
process(clk,rst)
begin
if rst=’1′ then
qd1<=”00000000″;
qd2<=”00000000″;
qd3<=”00000000″;
qr1<=”00″;
qr2<=”00″;
qr3<=”01″;
qsrc<=’0′;
qop<=”11″;
qwr<=’0′;
qjmp<=’0′;
elsif rising_edge(clk) then
qd1<=d1;
qd2<=d2;
qd3<=d3;
qr1<=r1;
qr2<=r2;
qr3<=r3;
qsrc<=ALUsrc;
qop<=ALUop;
qwr<=RegWrite;
qjmp<=jmp;
end if;
end process;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity PipeStageWB is
Port (
inc : in STD_LOGIC_VECTOR (1 downto 0);
ALUout : in STD_LOGIC_VECTOR (7 downto 0);
RegDest : in STD_LOGIC_VECTOR (1 downto 0);
RegWrite: in std_logic;
eq : in std_logic;
jmp : in std_logic;
dtype : in STD_LOGIC_VECTOR (1 downto 0);
rst : in std_logic;
clk : in std_logic;
qinc : out STD_LOGIC_VECTOR (1 downto 0);
qout : out STD_LOGIC_VECTOR (7 downto 0);
qrdest : out STD_LOGIC_VECTOR (1 downto 0);
qwr : out std_logic;
qeq : out std_logic;
qjmp : out std_logic;
qdtype : out STD_LOGIC_VECTOR (1 downto 0)
);
end PipeStageWB;
architecture Behavioral of PipeStageWB is
begin
process(clk,rst)
begin
if rst=’1′ then
qinc<=”01″;
qout<=”00000000″;
qrdest<=”00″;
qwr<=’0′;
qeq<=’0′;
qjmp<=’0′;
qdtype<=”01″;
elsif rising_edge(clk) then
qinc<=inc;
qout<=ALUout;
qrdest<=RegDest;
qwr<=RegWrite;
qeq<=eq;
qjmp<=jmp;
qdtype<=dtype;
end if;
end process;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity ForwardingUnit is
Port (
wbwr: in std_logic;
wbrd: in STD_LOGIC_VECTOR (1 downto 0);
exrs: in STD_LOGIC_VECTOR (1 downto 0);
exrt: in STD_LOGIC_VECTOR (1 downto 0);
fwdA : out std_logic;
fwdB : out std_logic
);
end ForwardingUnit;
architecture Behavioral of ForwardingUnit is
begin
fwdA <= ‘1’ when wbwr=’1′ and wbrd=exrs else ‘0’;
fwdB <= ‘1’ when wbwr=’1′ and wbrd=exrt else ‘0’;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use STD.TEXTIO.ALL;
use work.all;
entity Display is
Port (
input : in STD_LOGIC_VECTOR (7 downto 0);
typ : in STD_LOGIC_VECTOR (1 downto 0); — 00=value, 1X=branch, 01=nop
clk : in std_logic
);
end Display;
architecture Behavioral of Display is
begin
process(clk)
variable trace_line : line;
begin
if falling_edge(clk) then
if typ=”00″ then
write(trace_line,to_integer(signed(input)),field=>4, justified => right);
elsif typ=”01″ then
write(trace_line,string'(” NOP”));
else
write(trace_line,string'(” B”));
write(trace_line,to_bit(typ(0)));
end if;
writeline(output, trace_line);
end if;
end process;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.all;
entity DisplayControl is
Port (
opcode : in STD_LOGIC_VECTOR (1 downto 0);
r3 : in STD_LOGIC_VECTOR (1 downto 0);
jmp : in std_logic;
eq : in std_logic;
load : in std_logic;
typ : out STD_LOGIC_VECTOR (1 downto 0)
);
end DisplayControl;
architecture Behavioral of DisplayControl is
begin
typ<= (jmp & eq) when jmp=’1′ else
“01” when (r3=”01″ and opcode=”11″) else
“00”;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity datapath is
Port (
rst : in std_logic;
clk : in std_logic
);
end datapath;
architecture Behavioral of datapath is
component alu
Port (
a : in STD_LOGIC_VECTOR (7 downto 0);
b : in STD_LOGIC_VECTOR (7 downto 0);
op : in std_logic;
s : out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
component comparator
Port (
a : in STD_LOGIC_VECTOR (7 downto 0);
b : in STD_LOGIC_VECTOR (7 downto 0);
EQ : out std_logic;
GT : out std_logic;
LT : out std_logic
);
end component;
component regfile
Port (
rreg1 :in STD_LOGIC_VECTOR (1 downto 0);
rreg2 :in STD_LOGIC_VECTOR (1 downto 0);
wrreg :in STD_LOGIC_VECTOR (1 downto 0);
wdata :in STD_LOGIC_VECTOR (7 downto 0);
clk :in std_logic;
wr :in std_logic;
data1 :out STD_LOGIC_VECTOR (7 downto 0);
data2 :out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
component mux2x1_8
Port(
a : in STD_LOGIC_VECTOR (7 downto 0);
b : in STD_LOGIC_VECTOR (7 downto 0);
s : in std_logic;
c : out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
component mux2x1_2
Port(
a : in STD_LOGIC_VECTOR (1 downto 0);
b : in STD_LOGIC_VECTOR (1 downto 0);
s : in std_logic;
c : out STD_LOGIC_VECTOR (1 downto 0)
);
end component;
component control
Port (
opcode: in STD_LOGIC_VECTOR (1 downto 0);
inc : in STD_LOGIC_VECTOR (1 downto 0);
clk : in std_logic;
wr : out std_logic;
dsel : out std_logic;
aluop : out STD_LOGIC_VECTOR (1 downto 0);
jmp : out std_logic
);
end component;
component incrementer
Port (
a : in STD_LOGIC_VECTOR (7 downto 0);
inc : in STD_LOGIC_VECTOR (1 downto 0);
s : out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
component PC
Port (
rst : in std_logic;
a : in STD_LOGIC_VECTOR (7 downto 0);
clk : in std_logic;
q : out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
component rom
Port (
address : in STD_LOGIC_VECTOR (7 downto 0);
data : out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
component PipeStageID
Port (
a : in STD_LOGIC_VECTOR (7 downto 0);
rst : in std_logic;
clk : in std_logic;
q : out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
component PipeStageEXE
Port (
d1 : in STD_LOGIC_VECTOR (7 downto 0);
d2 : in STD_LOGIC_VECTOR (7 downto 0);
d3 : in STD_LOGIC_VECTOR (7 downto 0);
r1 : in STD_LOGIC_VECTOR (1 downto 0);
r2 : in STD_LOGIC_VECTOR (1 downto 0);
r3 : in STD_LOGIC_VECTOR (1 downto 0);
ALUsrc : in std_logic;
ALUop : in STD_LOGIC_VECTOR (1 downto 0);
RegWrite: in std_logic;
jmp : in std_logic;
rst : in std_logic;
clk : in std_logic;
qd1 : out STD_LOGIC_VECTOR (7 downto 0);
qd2 : out STD_LOGIC_VECTOR (7 downto 0);
qd3 : out STD_LOGIC_VECTOR (7 downto 0);
qr1 : out STD_LOGIC_VECTOR (1 downto 0);
qr2 : out STD_LOGIC_VECTOR (1 downto 0);
qr3 : out STD_LOGIC_VECTOR (1 downto 0);
qsrc : out std_logic;
qop : out STD_LOGIC_VECTOR (1 downto 0);
qwr : out std_logic;
qjmp : out std_logic
);
end component;
component PipeStageWB
Port (
inc : in STD_LOGIC_VECTOR (1 downto 0);
ALUout : in STD_LOGIC_VECTOR (7 downto 0);
RegDest : in STD_LOGIC_VECTOR (1 downto 0);
RegWrite: in std_logic;
eq : in std_logic;
jmp : in std_logic;
dtype : in STD_LOGIC_VECTOR (1 downto 0);
rst : in std_logic;
clk : in std_logic;
qinc : out STD_LOGIC_VECTOR (1 downto 0);
qout : out STD_LOGIC_VECTOR (7 downto 0);
qrdest : out STD_LOGIC_VECTOR (1 downto 0);
qwr : out std_logic;
qeq : out std_logic;
qjmp : out std_logic;
qdtype : out STD_LOGIC_VECTOR (1 downto 0)
);
end component;
component ForwardingUnit
Port (
wbwr: in std_logic;
wbrd: in STD_LOGIC_VECTOR (1 downto 0);
exrs: in STD_LOGIC_VECTOR (1 downto 0);
exrt: in STD_LOGIC_VECTOR (1 downto 0);
fwdA : out std_logic;
fwdB : out std_logic
);
end component;
component Display
Port (
input : in STD_LOGIC_VECTOR (7 downto 0);
typ : in STD_LOGIC_VECTOR (1 downto 0);
clk : in std_logic
);
end component;
component DisplayControl
Port (
opcode : in STD_LOGIC_VECTOR (1 downto 0);
r3 : in STD_LOGIC_VECTOR (1 downto 0);
jmp : in std_logic;
eq : in std_logic;
load : in std_logic;
typ : out STD_LOGIC_VECTOR (1 downto 0)
);
end component;
signal inc : STD_LOGIC_VECTOR (1 downto 0):=”00″; — pc increment
signal pcinc,address: STD_LOGIC_VECTOR (7 downto 0):=”00000000″;
signal inst : STD_LOGIC_VECTOR (7 downto 0):=”00000000″;
signal opcode : STD_LOGIC_VECTOR (1 downto 0):=”00″;
signal data: STD_LOGIC_VECTOR (7 downto 0):=”00000000″;
signal p1d1,p1d2,p1d3: STD_LOGIC_VECTOR (7 downto 0):=”00000000″;
signal p1r1,p1r2,p1r3: STD_LOGIC_VECTOR (1 downto 0):=”00″;
signal p1src: std_logic:=’0′;
signal p1op,p1inc: STD_LOGIC_VECTOR (1 downto 0):=”00″;
signal p1wr: std_logic:=’0′;
signal p1jmp: std_logic:=’0′;
signal p2d1,p2d2,p2d3,p2imm,p2out: STD_LOGIC_VECTOR (7 downto 0):=”00000000″;
signal p2eq,p2lt,p2gt : std_logic:=’0′;
signal p2r1,p2r2,p2r3,p2rdest: STD_LOGIC_VECTOR (1 downto 0):=”00″;
signal p2src: std_logic:=’0′;
signal p2op,p2nxt: STD_LOGIC_VECTOR (1 downto 0):=”00″;
signal p2wr: std_logic:=’0′;
signal p2jmp: std_logic:=’0′;
signal p2selA,p2selB: std_logic:=’0′;
signal p2data1,p2data2: STD_LOGIC_VECTOR (7 downto 0):=”00000000″;
signal p2dtype: STD_LOGIC_VECTOR (1 downto 0):=”00″;
signal p3out: STD_LOGIC_VECTOR (7 downto 0):=”00000000″;
signal p3rdest: STD_LOGIC_VECTOR (1 downto 0):=”00″;
signal p3wr: std_logic:=’0′;
signal p3eq : std_logic:=’0′;
signal p3jmp: std_logic:=’0′;
signal p3inc: STD_LOGIC_VECTOR (1 downto 0):=”00″;
signal p3dtype: STD_LOGIC_VECTOR (1 downto 0):=”00″;
begin
mux0: entity work.mux2x1_2 port map(a=>”01″,b=>p3inc,s=>p3jmp,c=>inc);
inc1: entity work.incrementer port map(a=>address, inc=>inc, s=>pcinc);
pc1: entity work.PC port map(rst=>rst, a=>pcinc, clk=>clk, q=>address);
rom1: entity work.rom port map(address=>address, data=>data);
pipeline1: entity work.PipeStageID port map(a=>data,rst=>rst,clk=>clk,q=>inst);
opcode <= inst(7) & inst (6);
p1r1 <= inst(5) & inst (4);
p1r2 <= inst(3) & inst (2);
p1r3 <= inst(1) & inst (0);
p1d3 <= “0000” & inst(3) & inst (2) & inst(1) & inst (0);
ctl: entity work.control port map(opcode=>opcode, inc=>p1r3, clk=>clk, wr=>p1wr, dsel=>p1src, aluop=>p1op, jmp=>p1jmp);
regs: entity work.regfile port map(rreg1=>p1r1, rreg2=>p1r2, wrreg=>p3rdest, wdata=>p3out, clk=>clk, wr=>p3wr, data1=>p1d1, data2=>p1d2);
pipeline2: entity work.PipeStageEXE port map(d1=>p1d1,d2=>p1d2,d3=>p1d3,r1=>p1r1,r2=>p1r2,r3=>p1r3,ALUsrc=>p1src,ALUop=>p1op,RegWrite=>p1wr,jmp=>p1jmp,rst=>rst,clk=>clk,qd1=>p2d1,qd2=>p2d2,qd3=>p2imm,qr1=>p2r1,qr2=>p2r2,qr3=>p2r3,qsrc=>p2src,qop=>p2op,qwr=>p2wr,qjmp=>p2jmp);
fwdunit: entity work.ForwardingUnit port map(wbwr=>p3wr,wbrd=>p3rdest,exrs=>p2r1,exrt=>p2r2,fwdA=>p2selA,fwdB=>p2selB);
muxfwdA: entity work.mux2x1_8 port map(a=>p2d1,b=>p3out,s=>p2selA,c=>p2data1);
muxfwdB: entity work.mux2x1_8 port map(a=>p2d2,b=>p3out,s=>p2selB,c=>p2data2);
mux1: entity work.mux2x1_8 port map(a=>p2data1,b=>p2imm,s=>p2src,c=>p2d3);
alu1: entity work.alu port map(a=>p2d3, b=>p2data2, op=>p2op, s=>p2out);
comp : entity work.comparator port map(a=>p2data1, b=>p2data2, EQ=>p2eq, GT=>p2gt, LT=>p2lt);
mux2: entity work.mux2x1_2 port map(a=>p2r3,b=>p2r1,s=>p2src,c=>p2rdest);
dispctl: entity work.DisplayControl port map(opcode=>p2op,r3=>p2r3,jmp=>p2jmp,eq=>p2eq,load=>p2src,typ=>p2dtype);
pipeline3: entity work.PipeStageWB port map(inc=>p2r3,ALUout=>p2out,RegDest=>p2rdest,RegWrite=>p2wr,eq=>p2eq,jmp=>p2jmp,dtype=>p2dtype,rst=>rst,clk=>clk,qinc=>p3inc,qout=>p3out,qrdest=>p3rdest,qwr=>p3wr,qeq=>p3eq,qjmp=>p3jmp,qdtype=>p3dtype);
disp1: entity work.Display port map(input=>p3out,typ=>p3dtype,clk=>clk);
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.all;
entity testbench is
end entity testbench;
architecture dataflow of testbench is
component datapath
Port (
rst : in std_logic;
clk : in std_logic
);
end component;
signal clk : std_logic := ‘0’;
signal rst : std_logic := ‘0’;
begin
clk <= not clk after 10 ns;
calc : entity work.datapath port map(rst=>rst, clk=>clk);
testprocess: process is
begin
rst <= ‘1’;
wait for 5 ns;
rst <= ‘0’;
wait for 250 ns;
end process testprocess;
end architecture dataflow;