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