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;