Help with instruction fetch unit in VHDL

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;
datOut:eek:ut 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;
dataOut:eek:ut 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;
datOut:eek:ut 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;
dataOut:eek:ut 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;
---------------------------------------------------
 
A

Andy Botterill

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?

clear=0 in the testbench. It does not get to 1 in the testbench.

Therefore the register never gets initialised to 0. Incrementing X
doesn't do what you want.

Try setting clear to 1 in the testbench and report back.

Best of luck Andy
 
M

Mike Young

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

I don't see the feedback from nextPC to currPC. It might be that it's
there, but not completely evident on a first and second glance. Diagram
it out and satisfy yourself that currPC can advance with nextPC.

(It would be ever so much clearer to write that as one module.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,527
Members
44,998
Latest member
MarissaEub

Latest Threads

Top