Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

VHDL: Register File with Eight 8-bit Registers

Status
Not open for further replies.

irontitan76

Newbie level 4
Joined
Feb 22, 2013
Messages
5
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,320
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;
		  adrw  : natural := 3);
	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);
		  A_adr : in  std_logic_vector(adrw downto 0);
		  B_adr : in  std_logic_vector(adrw downto 0);
		  C_adr : in  std_logic_vector(adrw downto 0);
		  W_Clk : in  std_logic);
end entity regfile;
 

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.
 
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.
 

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.
 
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;
		      adrw  : natural := 3);
	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);
		    A_adr : in  std_logic_vector(adrw downto 0);
		    B_adr : in  std_logic_vector(adrw downto 0);
		    C_adr : in  std_logic_vector(adrw 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
                    case A_adr is
                         when "000" => 
                         when "001" => 
                         when "010" => 
			 when "011" => 
			 when "100" => 
			 when "101" => 
			 when "110" => 
			 when "111" => 
                         when others =>  
                     end case;
               else
                     case B_adr is
                         when "000" => 
                         when "001" => 
                         when "010" => 
			 when "011" => 
			 when "100" => 
			 when "101" => 
			 when "110" => 
			 when "111" => 
                         when others =>  
                      end case;
                      case C_adr is
                         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;
 

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.
 
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
 

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.
 
Code:
library ieee;
use ieee.std_logic_1164.all;

entity regfile is
  generic ( dw    : natural := 8;
		      size  : natural := 8;
		      adrw  : natural := 3);
	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);
		    A_adr : in  std_logic_vector(adrw downto 0);
		    B_adr : in  std_logic_vector(adrw downto 0);
		    C_adr : in  std_logic_vector(adrw 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
				regArray(to_integer(unsigned(A_adr))) <= C; 
			end if;
				regArray(to_integer(unsigned(B_adr)));
				regArray(to_integer(unsigned(C_adr)));
	end process;
end behavioral;
 

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,
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top