# VHDL: Register File with Eight 8-bit Registers

Status
Not open for further replies.

#### irontitan76

##### Newbie level 4
Hi, I am desperately trying to figure out an assignment using VHDL. As of right now, I don't have much of an idea of how to start. I know other programming languages, but VHDL is, of course, more coding instead of programming. To me, VHDL seems somewhat illogical. Nonetheless, I am trying to learn it. I've attempted to do a structure, but that seems extremely long and tedious. Thanks in advance. The assignment is as follows:

Use VHDL to design a model of a three port register file. The register file is composed of eight 8-bit registers. The register file has two 8-bit outputs (ports A and B) and a single 8-bit input (port C). Each port has an associated 3-bit address input for selecting one of 8 registers for output (A and B ports) or input (C port). Port C has an associated Clk signal for transferring the input on port C to the addressed register on the falling edge of the Clk signal. Your model should be parameterized to allow the number and bit-width of the register file to be scaled using generic parameters.

Use the following entity definition for the register file:

Code:
entity regfile is
generic ( dw    : natural := 8;
size  : natural := 8;
port ( A     : out std_logic_vector(dw-1 downto 0);
B     : out std_logic_vector(dw-1 downto 0);
C     : in  std_logic_vector(dw-1 downto 0);
W_Clk : in  std_logic);
end entity regfile;

#### FvM

##### Super Moderator
Staff member
I've attempted to do a structure, but that seems extremely long and tedious.
Behavioral level seems to be a better way to manage this straightforward homework problem.

irontitan76

### irontitan76

Points: 2

#### irontitan76

##### Newbie level 4
Thanks for the reply. And yes, that's what I thought as well, but I really am a beginner in VHDL and have no idea how to start.

#### FvM

##### Super Moderator
Staff member
I would start with defining the register file as an array of std_logic_vector, using the given generic constants to set depth and word width. There has to be a type definition.

Then writing the architecture body, essentially the write and read processes.

irontitan76

### irontitan76

Points: 2

#### irontitan76

##### Newbie level 4
Would it be something like this? Or am I totally going about this all wrong? I'm sorry for the trouble. I just need to get this done. I learn by examples and I haven't gotten many in class. I've tried to look up information on VHDL online, but it hasn't helped out entirely.

Code:
library ieee;
use ieee.std_logic_1164.all;

entity regfile is
generic ( dw    : natural := 8;
size  : natural := 8;
port ( A     : out std_logic_vector(dw-1 downto 0);
B     : out std_logic_vector(dw-1 downto 0);
C     : in  std_logic_vector(dw-1 downto 0);
W_Clk : in  std_logic);
end entity regfile;

type regArray is array(0 to size) of std_logic_vector(dw-1 downto 0);
signal regfile : regArray;

architecture behavioral of regfile is

begin
process
if clk'event and clk='0' then
when "000" =>
when "001" =>
when "010" =>
when "011" =>
when "100" =>
when "101" =>
when "110" =>
when "111" =>
when others =>
end case;
else
when "000" =>
when "001" =>
when "010" =>
when "011" =>
when "100" =>
when "101" =>
when "110" =>
when "111" =>
when others =>
end case;
when "000" =>
when "001" =>
when "010" =>
when "011" =>
when "100" =>
when "101" =>
when "110" =>
when "111" =>
when others =>
end case;
end if;
end process;
end behavioral;

#### TrickyDicky

Thats roughly the way, but perhaps a little long winded, and it wont scale. The easiest way would be to convert the address to an integer.

regArray( to_integer(unsigned(A_adr) ) ) <= something;

This will scale to any size of adrw without having to write hiddeously long case statements (with wont compile anyway).

Notes
1. You need to size the reg array 0 to size-1, otherwise you wil get an extra register that isnt accessible.
2. Never ever do an "else" with a clock if branch.

I dont quite get why you have 3 case statements for the 3 addresses. You need some sort of logic to determine which address to use.

irontitan76

### irontitan76

Points: 2

#### irontitan76

##### Newbie level 4
Okay, hmm. I used the case statements to eventually determine which address to use. How would the "regArray( to_interger(unsigned(A_adr))) <= something;" help do that? Furthermore, how would I use logic to determine the address to use? That's what I thought the 3 bit address input was for. I got a long way to go on this..

If it's possible, could you post your version of the changes thus far? If not, no worries.

Thank you very much

#### FvM

##### Super Moderator
Staff member
Referring to the previous suggestion,

Code:
regArray(to_integer(unsigned(C_adr))) <= C;
in the clocked process

Code:
A <= regArray( to_integer(unsigned(A_adr)));
B <= regArray( to_integer(unsigned(B_adr)));
in the concurrent code

is all you need.

irontitan76

### irontitan76

Points: 2

#### irontitan76

##### Newbie level 4
Code:
library ieee;
use ieee.std_logic_1164.all;

entity regfile is
generic ( dw    : natural := 8;
size  : natural := 8;
port ( A     : out std_logic_vector(dw-1 downto 0);
B     : out std_logic_vector(dw-1 downto 0);
C     : in  std_logic_vector(dw-1 downto 0);
W_Clk : in  std_logic);
end entity regfile;

type regArray is array(0 to size-1) of std_logic_vector(dw-1 downto 0);
signal regfile : regArray;

architecture behavioral of regfile is

begin
process
if clk'event and clk='0' then
end if;
end process;
end behavioral;

#### FvM

##### Super Moderator
Staff member
Right except for missing process sensitivity list and some typos. The name of your clock signal is w_clk, not clk. Taking the asynchronous assignments out of the process leaves w_clk as the only signal in the sensitivity list,

irontitan76

Points: 2