学习日志之VHDL(8)

implementation of pentium4 adder

structure

The adder of pentium4 can be divided into two part. The first part is the carry generator another is sum generator.The carry generator is only responsible for the generation of carry bit. And these carry bit can be used to select the result generated by the sum generator.

This structure is used to solve the problem that the carry in ripple carry adder genrated asynchronously. In this scenario, the carry bit on high bit is much slower than low bits. with the implementation of this algorithm, carry bits and sum bits can be generated at the same time. In this way, we could avoid the delay produced by transmiting the result of carry generated by previous 1 bit full adder.

implementation step

To describe the detail of its logic we choose implement it in structure level.

ripple carry adder

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_unsigned.all;

entity RCA is 
	generic (DRCAS : 	Time := 0 ns;
	         DRCAC : 	Time := 0 ns);
	Port (	A:	In	std_logic_vector(3 downto 0);
		B:	In	std_logic_vector(3 downto 0);
		Ci:	In	std_logic;
		S:	Out	std_logic_vector(3 downto 0);
		Co:	Out	std_logic);
end RCA; 

architecture STRUCTURAL of RCA is

  signal STMP : std_logic_vector(3 downto 0);
  signal CTMP : std_logic_vector(4 downto 0);

  component FA 
  generic (DFAS : 	Time := 0 ns;
           DFAC : 	Time := 0 ns);
  Port ( A:	In	std_logic;
	 B:	In	std_logic;
	 Ci:	In	std_logic;
	 S:	Out	std_logic;
	 Co:	Out	std_logic);
  end component; 

begin

  CTMP(0) <= Ci;
  S <= STMP;
  Co <= CTMP(4);
  
  ADDER1: for I in 1 to 4 generate
    FAI : FA 
	  generic map (DFAS => DRCAS, DFAC => DRCAC) 
	  Port Map (A(I-1), B(I-1), CTMP(I-1), STMP(I-1), CTMP(I)); 
  end generate;
end STRUCTURAL;

configuration CFG_RCA_STRUCTURAL of RCA is
  for STRUCTURAL 
    for ADDER1
      for all : FA
        use configuration WORK.CFG_FA_BEHAVIORAL;
      end for;
    end for;
  end for;
end CFG_RCA_STRUCTURAL;

sum generator


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


entity sum_gen is
  Port (
  c_sel: in std_logic_vector(7 downto 0);
  a_o,b_o: in std_logic_vector(31 downto 0);
  s_o: out std_logic_vector(31 downto 0)
  );
end sum_gen;

architecture str of sum_gen is
component carry_select_block is
port (
    a : in STD_LOGIC_VECTOR (3 downto 0);
    b : in STD_LOGIC_VECTOR (3 downto 0);
    cin : in STD_LOGIC;
    s : out STD_LOGIC_VECTOR (3 downto 0)
);
end component;

signal a_s0,a_s1,a_s2,a_s3,a_s4,a_s5,a_s6,a_s7: STD_LOGIC_VECTOR (3 downto 0);
signal b_s0,b_s1,b_s2,b_s3,b_s4,b_s5,b_s6,b_s7: STD_LOGIC_VECTOR (3 downto 0);
signal s_s0,s_s1,s_s2,s_s3,s_s4,s_s5,s_s6,s_s7: STD_LOGIC_VECTOR (3 downto 0);
begin
    a_s0<=a_o(3 downto 0);
    b_s0<=b_o(3 downto 0);
    a_s1<=a_o(7 downto 4);
    b_s1<=b_o(7 downto 4);
    a_s2<=a_o(11 downto 8);
    b_s2<=b_o(11 downto 8);
    a_s3<=a_o(15 downto 12);
    b_s3<=b_o(15 downto 12);
    a_s4<=a_o(19 downto 16);
    b_s4<=b_o(19 downto 16);
    a_s5<=a_o(23 downto 20);
    b_s5<=b_o(23 downto 20);
    a_s6<=a_o(27 downto 24);
    b_s6<=b_o(27 downto 24);
    a_s7<=a_o(31 downto 28);
    b_s7<=b_o(31 downto 28);
    
    block0: carry_select_block port map(a_s0,b_s0,c_sel(0),s_s0);
    block1: carry_select_block port map(a_s1,b_s1,c_sel(1),s_s1);
    block2: carry_select_block port map(a_s2,b_s2,c_sel(2),s_s2);
    block3: carry_select_block port map(a_s3,b_s3,c_sel(3),s_s3);
    block4: carry_select_block port map(a_s4,b_s4,c_sel(4),s_s4);
    block5: carry_select_block port map(a_s5,b_s5,c_sel(5),s_s5);
    block6: carry_select_block port map(a_s6,b_s6,c_sel(6),s_s6);
    block7: carry_select_block port map(a_s7,b_s7,c_sel(7),s_s7);
    
    s_o<=s_s0 & s_s1 & s_s2 & s_s3 & s_s4 & s_s5 & s_s6 & s_s7;
end str;

carry generator


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity carry_gen is
    Port (
    a: in std_logic_vector(31 downto 0);
    b: in std_logic_vector(31 downto 0);
    c: out std_logic_vector(7 downto 0)
    );
end carry_gen;

architecture str of carry_gen is
component PG_unit is
port(
    a,b: in std_logic;
    p,g: out std_logic 
);
end component;

type level1 is array (15 downto 0) of std_logic;
signal g1: level1;
signal p1: level1;
type level2 is array (7 downto 0) of std_logic;
signal g2: level2;
signal p2: level2;
type level3 is array (4 downto 0) of std_logic;
signal g3: level3;
signal p3: level3;
type level4 is array (4 downto 0) of std_logic;
signal g4: level4;
signal p4: level4;
type level5 is array (4 downto 0) of std_logic;
signal g5: level5;
signal p5: level5;

begin
level_1: for i in 0 to 15 generate
    p1(i)<=a(i) xor b(i);
    g1(i)<=a(i) and b(i);
    end generate;

level_2: for i in 0 to 7 generate
    p2(i)<=p1(2*i) and p1(2*i+1);
    g2(i)<=(g1(2*i) and p1(2*i+1)) or g1(2*i+1); 
    end generate;
  
level_3: for i in 0 to 3 generate
    p3(i)<=p2(2*i) and p2(2*i+1);
    g3(i)<=(g2(2*i) and p2(2*i+1)) or g2(2*i+1);
    end generate;
    
level_4_odd: for i in 0 to 1 generate
    p4(i*2+1)<=p3(2*i) and p3(2*i+1);
    g4(i*2+1)<=g3(2*i+1) and (g3(2*i) or p3(2*i+1));
    end generate;
level_4_even: for i in 0 to 1 generate 
    p3(i*2)<=p2(2*i) and p1(2*(2*i+1));
    g3(i*2)<=g1(2*(2*i+1)) and (g2(2*i) or p1(2*(2*i+1)));
    end generate; 
    
level_5: 
    g5(0)<=(g4(1) and p2(4)) or g2(4);
    g5(1)<=(g4(1) and p3(2)) or g3(2);
    g5(2)<=(g4(1) and p4(2)) or g4(2);
    g5(3)<=(g4(1) and p4(3)) or g4(3);    
    
c<=g5(3)&g5(2)&g5(1)&g5(0)&g4(1)&g4(0)&g3(0)&g2(0);
end str;

the complete P4 adder


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity p4_adder is
Port ( a : in STD_LOGIC_VECTOR (31 downto 0);
       b : in STD_LOGIC_VECTOR (31 downto 0);
       s : out STD_LOGIC_VECTOR (31 downto 0));
end p4_adder;

architecture str of p4_adder is
component sum_gen is
Port (
  c_sel: in std_logic_vector(7 downto 0);
  a_o,b_o: in std_logic_vector(31 downto 0);
  s_o: out std_logic_vector(31 downto 0)
  );
end component;

component carry_gen is
Port (
a: in std_logic_vector(31 downto 0);
b: in std_logic_vector(31 downto 0);
c: out std_logic_vector(7 downto 0)
);
end component;
 
signal c_s: std_logic_vector(7 downto 0);

begin
carry: carry_gen port map(a,b,c_s);
sum: sum_gen port map(c_s,a,b,s);
end str;

some notes about VHDL

about configuration

This kind of sentence is usually used in huge and complex design with many different architecture to specify which architecture is in need. It usually appears in the process of simulation, which means you have to define a configuration at the end of your testbench.

the format of configuration is as below:

configuration 配置名 of 实体名 is 
	配置说明
	end 配置名;

the point of its usage are as following :

  • every entity with multiple architectures should declare all of the architecture at the end in configuration sentence.
  • if there are some other entities which decide to use this entity to describe its function in structure level, you should make a choice in the 配置说明 of configuration block.

e.g.

--file NO.1
entity one is 
port(...);
end one;

architecture method1 of one is 
begin 
...
end architecture;

architecture method2 of one is 
begin 
...
end architecture;

...

configuration one_config of one is 
	for method1 
	end for;
end one_config;
	
configuration two_config of one is 
	for method2 
	end for;
end one_config;
--file NO.2
entity two is 
port(...);
end one;

architecture str of two is
begin
...
end architecture

configuration config of two is 
	for str
		use configuration WORK.two_config;
	end for;
	end config;

generate statement

Generate statement is used to generate structure with similar form. And this statement can reduce the length of our VHDL code.
The format of this statement is as below:

标签: for 循环控制变量 in 循环变量取值范围 generate
...--需要进行的操作和生成的结构
end generate

循环控制变量 is a parameter which also can be used in the body of loop. It doesn’t need to be defined in advance. And it can be used simultainously in other loops.
循环变量取值范围 is usually defined with the form like (低位 to 高位)or (高位 downto 低位)

e.g.

label: for i in (0 to 15) generate
mux: mux port map (a,b,s,o);
end generate;

about port assignment of parameters in port map

During the process of coding we meet a problem about parameter assignment. My idea is that assign a part of a long vector to a parameter in the port map with identical bits. But it seems VHDL doesn’t allow us to do it directly. The correct way to do this is as below.

signal a_s: std_logic_vector(7 downto 0);
...
carry: carry_gen port map(a=>a_s(3 downto 0),b,c_s);

Generate an array type and array

In VHDL, there isn’t like the language like C or Python. if you wanna define an array, you have to define an array type in advance. But the synthizer only support the vector with 1 dimensional. but actually you can define an array with 2 dimensional. There are 2 different scenarios when we define an array type:

  • with constrain on the range of suffix
  • without constrain on the range of suffix

in the first scenario, we can use format as is shown below

TYPE 数组名IS ARRAY (数组范围)OF 数据类型;

and for the second scenario, there is a symbol <> which means you don’t want to confirm the range of this array now, but you have to confirm it when you wanna define an array in this type.

TYPE 数组名IS ARRAY (数组下标名 RANGE <>)OF 数据类型

e.g.

TYPE Bit_Vector IS Array (Natural Range <>)OF BIT;
...
VARIABLE va:Bit_Vector (1 to 6);

and the first scenario is the same.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值