UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Newbie mcgoveci
Newbie
413 Views
Registered: ‎02-08-2019

VHDL register implementation

I am trying to implement a circuit in vhdl like in this image except my one has to have 8 16 registers and thus a 3 to 8 decoder instead of a 2 to 4 decoder and 16 bit multiplexers with the top right multiplexer being 8 to 1 16-bit and the bottom left one being a 2 to 1 16-bit multiplexer.

This is the code I have which I think is completed but I have never used vhdl before so I am not sure. Is there anything clearly wrong with it?

vhdlProject.PNG

-- 3 to 8 16 bit multiplexer

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity decoder_3to8 is
	Port ( 
	A0 : in std_logic;
	A1 : in std_logic;
	A2 : in std_logic;
	Q0 : out std_logic;
	Q1 : out std_logic;
	Q2 : out std_logic;
	Q3 : out std_logic);
	Q4 : out std_logic;
	Q5 : out std_logic;
	Q6 : out std_logic;
	Q7 : out std_logic);
end decoder_3to8;
architecture Behavioral of decoder_3to8 is
begin
	Q0<= ((not A0) and (not A1) and (not A2)) after 5 ns;
	Q1<= (A0 and (not A1) and (not A2)) after 5 ns;
	Q2<= ((not A0) and A1 and (not A2)) after 5 ns;
	Q3<= (A0 and A1 and (not A2)) after 5 ns;
	Q4<= ((not A0) and (not A1) and A2) after 5 ns;
	Q5<= (A0 and (not A1) and A2)) after 5 ns;
	Q6<= ((not A0) and A1 and A2) after 5 ns;
	Q7<= (A0 and A1 and A2) after 5 ns;
end Behavioral;

-- 8 to 1 16bit multiplexer

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity mux8_16bit is
	port ( 
	In0 : in std_logic_vector(15 downto 0);
	In1 : in std_logic_vector(15 downto 0);
	In2 : in std_logic_vector(15 downto 0);
	In3 : in std_logic_vector(15 downto 0);
	In4 : in std_logic_vector(15 downto 0);
	In5 : in std_logic_vector(15 downto 0);
	In6 : in std_logic_vector(15 downto 0);
	In7 : in std_logic_vector(15 downto 0);
	s0 : in std_logic;
	s1 : in std_logic;
	s2 : in std_logic;
	Z : out std_logic_vector(15 downto 0));
end mux2_4bit;
architecture Behavioral of mux2_4bit is
begin
	Z <= In0 after 5 ns when so='0' and s1='0' and s2='0' else
		 In1 after 5 ns when so='1' and s1='0' and s2='0' else
		 In2 after 5 ns when so='0' and s1='1' and s2='0' else
		 In3 after 5 ns when so='1' and s1='1' and s2='0' else
		 In4 after 5 ns when so='0' and s1='0' and s2='1' else
		 In5 after 5 ns when so='1' and s1='0' and s2='1' else
		 In6 after 5 ns when so='0' and s1='1' and s2='1' else
		 In7 after 5 ns when so='1' and s1='1' and s2='1' else
		 "0000000000000000" after 5 ns;
end Behavioral;

--  2 to 1 multiplexer
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity mux2_16bit is
port ( 
	In0 : in std_logic_vector(15 downto 0);
	In1 : in std_logic_vector(15 downto 0);
	s : in std_logic;
	Z : out std_logic_vector(15 downto 0));
end mux2_4bit;
architecture Behavioral of mux2_4bit is
begin
	Z <= In0 after 5 ns when s='0' else
	In1 after 5 ns when s='1' else
	"0000000000000000" after 5 ns;
end Behavioral;

-- 16 bit register
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity reg16 is
port ( 
	D : IN std_logic_vector(15 downto 0);
	load : IN std_logic;
	Clk : IN std_logic;
	Q : OUT std_logic_vector(15 downto 0)
	 );
end reg16;
architecture Behavioral of reg16 is
begin
	process(clk,load)
	begin
		if(load='1' and clk='1')then
			Q <= D;
		else
			Q <= Q;
		end if;
	end process;
end;
end Behavioral;

-- Register

entity register_file is
Port ( 
    src_s0 : in std_logic;
	src_s1 : in std_logic;
	src_s2 : in std_logic;
	des_A0 : in std_logic;
	des_A1 : in std_logic;
	des_A2 : in std_logic;
	Clk : in std_logic;
	data_src : in std_logic;
	data : in std_logic_vector(15 downto 0);
	reg0 : out std_logic_vector(15 downto 0);
	reg1 : out std_logic_vector(15 downto 0);
	reg2 : out std_logic_vector(15 downto 0);
	reg3 : out std_logic_vector(15 downto 0));
	reg4 : out std_logic_vector(15 downto 0);
	reg5 : out std_logic_vector(15 downto 0);
	reg6 : out std_logic_vector(15 downto 0);
	reg7 : out std_logic_vector(15 downto 0));
end register_file;
architecture Behavioral of register_file is
	-- components
	-- 16 bit Register for register file
	COMPONENT reg16
	PORT(
		D : IN std_logic_vector(15 downto 0);
		load : IN std_logic;
		Clk : IN std_logic;
		Q : OUT std_logic_vector(15 downto 0)
		);
	END COMPONENT;

	-- 3 to 8 Decoder
	COMPONENT decoder_3to8
	PORT(
		A0 : IN std_logic;
		A1 : IN std_logic;
		A2 : IN std_logic;
		Q0 : OUT std_logic;
		Q1 : OUT std_logic;
		Q2 : OUT std_logic;
		Q3 : OUT std_logic;
		Q4 : OUT std_logic;
		Q5 : OUT std_logic;
		Q6 : OUT std_logic;
		Q7 : OUT std_logic
	);
	END COMPONENT;
	
	-- 2 to 1 16 bit multiplexer
	COMPONENT mux2_16bit
	PORT(
		In0 : IN std_logic_vector(15 downto 0);
		In1 : IN std_logic_vector(15 downto 0);
		s : IN std_logic;
		Z : OUT std_logic_vector(15 downto 0)
	);
	END COMPONENT;
	
	-- 4 to 1 line multiplexer
	COMPONENT mux8_16bit
	PORT(
		In0 : IN std_logic_vector(15 downto 0);
		In1 : IN std_logic_vector(15 downto 0);
		In2 : IN std_logic_vector(15 downto 0);
		In3 : IN std_logic_vector(15 downto 0);
		In4 : IN std_logic_vector(15 downto 0);
		In5 : IN std_logic_vector(15 downto 0);
		In6 : IN std_logic_vector(15 downto 0);
		In7 : IN std_logic_vector(15 downto 0);
		S0 : IN std_logic;
		S1 : IN std_logic;
		S2 : IN std_logic;
		Z : OUT std_logic_vector(15 downto 0)
		);
	END COMPONENT;
	
	signal load_reg0, load_reg1, load_reg2, load_reg3, load_reg4, load_reg5, load_reg6, load_reg7 : std_logic;
	signal reg0_q, reg1_q, reg2_q, reg3_q, reg4_q, reg5_q, reg6_q, reg7_q, data_src_mux_out, src_reg : std_logic_vector(15 downto 0);	
	
	begin
	-- port maps 
	-- register 0
	reg00: reg16 PORT MAP(
		D => data_src_mux_out,
		load => load_reg0,
		Clk => Clk,
		Q => reg0_q
	);
	-- register 1
	reg01: reg16 PORT MAP(
		D => data_src_mux_out,
		load => load_reg1,
		Clk => Clk,
		Q => reg1_q
	);
	--register 2
	reg02: reg16 PORT MAP(
		D => data_src_mux_out,
		load => load_reg2,
		Clk => Clk,
		Q => reg2_q
	);
	-- register 3
	reg03: reg16 PORT MAP(
		D => data_src_mux_out,
		load => load_reg3,
		Clk => Clk,
		Q => reg3_q
	);
	-- register 4
	reg04: reg16 PORT MAP(
		D => data_src_mux_out,
		load => load_reg4,
		Clk => Clk,
		Q => reg4_q
	);
	-- register 5
	reg05: reg16 PORT MAP(
		D => data_src_mux_out,
		load => load_reg5,
		Clk => Clk,
		Q => reg5_q
	);
	-- register 6
	reg06: reg16 PORT MAP(
		D => data_src_mux_out,
		load => load_reg6,
		Clk => Clk,
		Q => reg6_q
	);
	-- register 7
	reg07: reg16 PORT MAP(
		D => data_src_mux_out,
		load => load_reg7,
		Clk => Clk,
		Q => reg7_q
	);
	
	-- Destination register decoder
	des_decoder_3to8: decoder_3to8 PORT MAP(
		A0 => des_A0,
		A1 => des_A1,
		A2 => des_A2
		Q0 => load_reg0,
		Q1 => load_reg1,
		Q2 => load_reg2,
		Q3 => load_reg3,
		Q4 => load_reg4,
		Q5 => load_reg5,
		Q6 => load_reg6,
		Q7 => load_reg7
	);
	
	-- 2 to 1 Data source multiplexer
	data_src_mux2_16bit: mux2_16bit PORT MAP(
		In0 => data,
		In1 => src_reg,
		s => data_src,
		Z => data_src_mux_out
	);
	
	-- 4 to 1 source register multiplexer
	Inst_mux8_16bit: mux8_16bit PORT MAP(
		In0 => reg0_q,
		In1 => reg1_q,
		In2 => reg2_q,
		In3 => reg3_q,
		In4 => reg4_q,
		In5 => reg5_q,
		In6 => reg6_q,
		In7 => reg7_q,
		S0 => src_s0,
		S1 => src_s1,
		s2 => src_s1,
		Z => src_reg
	);
	reg0 <= reg0_q;
	reg1 <= reg1_q;
	reg2 <= reg2_q;
	reg3 <= reg3_q;
	reg4 <= reg4_q;
	reg5 <= reg5_q;
	reg6 <= reg6_q;
	reg7 <= reg7_q;
end Behavioral;
	
	
0 Kudos
2 Replies
Scholar richardhead
Scholar
362 Views
Registered: ‎08-01-2012

Re: VHDL register implementation

Plenty of issues:

1. In decoder_3to8 , why is each bit coming in individually? why not make a bus?

 

a : in std_logic_vector(2 downto 0);
q : out std_logic_vector(7 downto 0);

2. You are using "after" on all assignments. Why? they are not used for synthesis and only useful in simulation. Why did you chose 5 ns? why are you even bothering at all?

 

3. reg16 is a latch, not a register. Latches are not recommended in FPGAs (and generally frowned on in most places now). the template for a register is:

 

process(clk)
begin
  if rising_edge(clk) then
    if en = '1' then  -- synchronous enable
      q <= d;
    end if;
  end if;
end process;

4. Usage of std_logic_arith and std_logic_unsigned libraries are now discouraged (and have been for about 20 + years). They are not part of the VHDL standard. You should use ieee.numeric_std instead (which was part of the 1993 revision of VHDL). 

 

5. Component declarations are not needed. If the target entity is written in VHDL, you can use direct instantiation, meaning the syntax checker can find errors in your port maps in seconds, rather than waiting for mapping to occur where entities are mapped to components (this can be several minutes in larger designs). direct instantiation is done like this:

some_inst : entity <library>.your_entity

so, to instantiate your decoder_3to8 

des_decoder_3to8: entity work.decoder_3to8 
PORT MAP(

6. I know you are just a beginner, but creating such small components can become very cumbersome when the design gets larger. Having such small functional blocks means you will need hundreds of entity instantiations later. You would normally do your design in a single file, meaning your 300 lines can be condensed into 25-50 lines.

7. Comments. Your code has no meaningful comments. Comments should explain the "Why", not the "how" or what, as these should be clear from the code. Always write code like you have to hand it over to someone you've never met before tomorrow. They should be able to see how you've done something from your code, but may not understand why you did it in a specific way.

8. Testbench - you need to write a testbench to make sure it works.

350 Views
Registered: ‎06-21-2017

Re: VHDL register implementation

Just to add to item 1 mentioned by @richardhead, if your a and s bits (address and select ?) are busses, it makes it easier to write your mux and decoder sections as case statements rather than a chain of if-else statements.  This helps to verify that you covered all cases and makes the code more clear. 

0 Kudos