S
shaygol5
Hello,
In cpu architecture course, we were tasked with building a single cycle
MIPS cpu.
after writing the entire architecture and performing multiple test
benches we wrote the architecture to an fpga board and... it didn't
work.
Examining things closely, we found out there's something wrong with our
instruction fetch. mainly, the PC can't advance to the next instruction
address. I wrote down a simple entity with 2 components - a 32 bits
register and an adder. the register outputs data (program address) to
the adder. the adder performs a "+4" on the address and sends it back to
the PC.
Simple, isn't it?
But it's not working, for some reason - when i simulate this unit it
only has junk on it's bus (XXXXXXXX on modelsim). I can't find the
problem and i'm desperate. i have attached all the relevant files. can
someone find what the problem is?
thank you,
Shay
fetch.vhd
---------------------------------------------------
-- Fetch segment
---------------------------------------------------
--
library ieee ;
use ieee.std_logic_1164.all;
-- Include globals
use work.global.all;
---------------------------------------------------
entity fetch is
port(
clock: in std_logic;
clear: in std_logic;
datOutut std_logic_vector(N-1 downto 0)
);
end fetch;
----------------------------------------------------
architecture struct of fetch is
component regN is
port(
dataIn: in std_logic_vector(N-1 downto 0):=zeroes; -- "zeroes" is a 32 bit vector of '0's
clock: in std_logic;
clear: in std_logic;
dataOutut std_logic_vector(N-1 downto 0):=zeroes
);
end component;
component Adder is
port(
x: in std_logic_vector(N-1 downto 0);
y: in std_logic_vector(N-1 downto 0);
Sum: out std_logic_vector(N-1 downto 0)
);
end component;
signal currPC :std_logic_vector(N-1 downto 0):=zeroes;
signal NextPC :std_logic_vector(N-1 downto 0):=zeroes;
begin
Program_counter:
port map regN(NextPC, clock, clear, currPC);
Next_IR:
port map adder(currPC, four, NextPC); -- "four" is a 32 bits vector with the decimal value of 4
datOut <= NextPC;
end struct;
---------------------------------------------------
fetch_TB.vhd
----------------------------------------------------------------------
-- Test Bench for fetch unit
----------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
-- Include globals
use work.global.all;
entity fetch_TB is -- entity declaration
end fetch_TB;
architecture TB of fetch_TB is
component fetch is
port(
clock: in std_logic;
clear: in std_logic;
datOutut std_logic_vector(N-1 downto 0)
);
end component;
-- Signals for wiring
signal clock, clear : std_logic:='0';
signal Dataout : std_logic_vector(N-1 downto 0);
begin
DUT: fetch port map (clock, clear, Dataout);
process begin
clock <= '0';
wait for 10 ns;
clock <= '1';
wait for 10 ns;
end process;
process -- Start of test bench run:
begin
clear <= '0';
wait for 300 ns;
end TB;
adder.vhd
--------------------------------------------------------
-- Adder Entity Implementataton
--------------------------------------------------------
-- Libraries used:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
-- Include globals
use work.global.all;
--------------------------------------------------------
entity Adder is
port( x: in std_logic_vector(N-1 downto 0);
y: in std_logic_vector(N-1 downto 0);
Sum: out std_logic_vector(N-1 downto 0)
);
end Adder;
--------------------------------------------------------
architecture behv of Adder is
-- Define a temparary signal to store the result,
-- including 1 more MSB for carry cases (for future use / validality).
begin
process(x,y)
variable result: std_logic_vector(N downto 0);
begin
result := ('0' & x)+('0' & y);
Sum <= result(N-1 downto 0); -- Sum is the result on the + operator, only with no carry.
end process;
end behv;
--------------------------------------------------------
regN.vhd
---------------------------------------------------
-- N-bits Register
---------------------------------------------------
-- no enable register
library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
-- Include globals
use work.global.all;
---------------------------------------------------
entity regN is
port(
dataIn: in std_logic_vector(N-1 downto 0);
clock: in std_logic;
clear: in std_logic;
dataOutut std_logic_vector(N-1 downto 0)
);
end regN;
----------------------------------------------------
architecture behv of regN is
signal Q_tmp: std_logic_vector(N-1 downto 0);
begin
process(dataIn, clock, clear)
begin
if clear = '1' then
-- use 'range in signal assigment
Q_tmp <= (Q_tmp'range => '0');
elsif (clock='1' and clock'event) then
Q_tmp <= dataIn;
end if;
end process;
-- concurrent statement
dataOut <= Q_tmp;
end behv;
---------------------------------------------------
In cpu architecture course, we were tasked with building a single cycle
MIPS cpu.
after writing the entire architecture and performing multiple test
benches we wrote the architecture to an fpga board and... it didn't
work.
Examining things closely, we found out there's something wrong with our
instruction fetch. mainly, the PC can't advance to the next instruction
address. I wrote down a simple entity with 2 components - a 32 bits
register and an adder. the register outputs data (program address) to
the adder. the adder performs a "+4" on the address and sends it back to
the PC.
Simple, isn't it?
But it's not working, for some reason - when i simulate this unit it
only has junk on it's bus (XXXXXXXX on modelsim). I can't find the
problem and i'm desperate. i have attached all the relevant files. can
someone find what the problem is?
thank you,
Shay
fetch.vhd
---------------------------------------------------
-- Fetch segment
---------------------------------------------------
--
library ieee ;
use ieee.std_logic_1164.all;
-- Include globals
use work.global.all;
---------------------------------------------------
entity fetch is
port(
clock: in std_logic;
clear: in std_logic;
datOutut std_logic_vector(N-1 downto 0)
);
end fetch;
----------------------------------------------------
architecture struct of fetch is
component regN is
port(
dataIn: in std_logic_vector(N-1 downto 0):=zeroes; -- "zeroes" is a 32 bit vector of '0's
clock: in std_logic;
clear: in std_logic;
dataOutut std_logic_vector(N-1 downto 0):=zeroes
);
end component;
component Adder is
port(
x: in std_logic_vector(N-1 downto 0);
y: in std_logic_vector(N-1 downto 0);
Sum: out std_logic_vector(N-1 downto 0)
);
end component;
signal currPC :std_logic_vector(N-1 downto 0):=zeroes;
signal NextPC :std_logic_vector(N-1 downto 0):=zeroes;
begin
Program_counter:
port map regN(NextPC, clock, clear, currPC);
Next_IR:
port map adder(currPC, four, NextPC); -- "four" is a 32 bits vector with the decimal value of 4
datOut <= NextPC;
end struct;
---------------------------------------------------
fetch_TB.vhd
----------------------------------------------------------------------
-- Test Bench for fetch unit
----------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
-- Include globals
use work.global.all;
entity fetch_TB is -- entity declaration
end fetch_TB;
architecture TB of fetch_TB is
component fetch is
port(
clock: in std_logic;
clear: in std_logic;
datOutut std_logic_vector(N-1 downto 0)
);
end component;
-- Signals for wiring
signal clock, clear : std_logic:='0';
signal Dataout : std_logic_vector(N-1 downto 0);
begin
DUT: fetch port map (clock, clear, Dataout);
process begin
clock <= '0';
wait for 10 ns;
clock <= '1';
wait for 10 ns;
end process;
process -- Start of test bench run:
begin
clear <= '0';
wait for 300 ns;
end TB;
adder.vhd
--------------------------------------------------------
-- Adder Entity Implementataton
--------------------------------------------------------
-- Libraries used:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
-- Include globals
use work.global.all;
--------------------------------------------------------
entity Adder is
port( x: in std_logic_vector(N-1 downto 0);
y: in std_logic_vector(N-1 downto 0);
Sum: out std_logic_vector(N-1 downto 0)
);
end Adder;
--------------------------------------------------------
architecture behv of Adder is
-- Define a temparary signal to store the result,
-- including 1 more MSB for carry cases (for future use / validality).
begin
process(x,y)
variable result: std_logic_vector(N downto 0);
begin
result := ('0' & x)+('0' & y);
Sum <= result(N-1 downto 0); -- Sum is the result on the + operator, only with no carry.
end process;
end behv;
--------------------------------------------------------
regN.vhd
---------------------------------------------------
-- N-bits Register
---------------------------------------------------
-- no enable register
library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
-- Include globals
use work.global.all;
---------------------------------------------------
entity regN is
port(
dataIn: in std_logic_vector(N-1 downto 0);
clock: in std_logic;
clear: in std_logic;
dataOutut std_logic_vector(N-1 downto 0)
);
end regN;
----------------------------------------------------
architecture behv of regN is
signal Q_tmp: std_logic_vector(N-1 downto 0);
begin
process(dataIn, clock, clear)
begin
if clear = '1' then
-- use 'range in signal assigment
Q_tmp <= (Q_tmp'range => '0');
elsif (clock='1' and clock'event) then
Q_tmp <= dataIn;
end if;
end process;
-- concurrent statement
dataOut <= Q_tmp;
end behv;
---------------------------------------------------