一个8位简易ALU的设计

一、设计任务

一个8位简易ALU的功能如下:

(1)能实现两个8位数的加、减操作,得到8位结果;

(2)能实现对一个8位输入数据的算术移位(符号扩展),移位范围为左移0-8位、右移0-8位。

用硬件描述语言设计该ALU并进行功能仿真,并自选一款FPGA进行逻辑综合与布局布线,得到消耗的硬件资源情况及时序结果。

  • 电路原理及代码

1)verilog版

通过实验任务我们可以看到ALU的操作在Verilog中都有对应的表达,不需要自己再专门去写门电路,而且这些都是常用的操作,vivado因该有固定的优化后的设计模板。所以只需要一个case选择语句来选择ALU具体进行的操作即可。我们的设计有三个输入信号分别为a,b,sel和一个输出out。sel选择执行的操作。00:a+b   01:a-b   10: a向左移b位   11:为a向右移b位   

(2)VHDL版

这个版本的加减法的实现采用了自己设计的加法器和算数移位运算。加法减法的实现没有考虑外界的进位的情况。a,b为输入数据,c保存进位。a,b每一位相加的结果相当于进位c,a,b三者相异或。进位相当于c(i-1),a,b任意两个相与再或。算数移位通过将输入的指定位到输出的指定位位,再根据移位法则补0或1。(算数移位:左移空缺位补0,右移空缺位根据最高的符号位确定是补0还是补1)。

具体代码如下

(1)verilog

`timescale 1ns / 1ps

module alu(               input [7:0] a,

input [7:0] b,

input [1:0] sel,

output reg [7:0] out

);

always@(a or b or sel) begin

case(sel)

3'b00 : out = a + b;

3'b01 : out = a - b;

3'b10 : out = a <<< b;

3'b11 : out = a >>> b;

default: out = 5'bx;

endcase

end

endmodule

  1. VHDL

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;

USE ieee.std_logic_UNSIGNED.ALL;

entity ALU_B is

Port ( A : in STD_LOGIC_VECTOR (7 downto 0);

B : in STD_LOGIC_VECTOR (7 downto 0);

m : in integer;

sel : in STD_LOGIC_VECTOR (0 to 1);

F : out STD_LOGIC_VECTOR (7 downto 0)

);

end ALU_B;

architecture Behavioral of ALU_B is

begin

process (A,B,m,sel)

variable c : std_logic_vector(7 downto 0);

variable d : std_logic_vector(7 downto 0);

variable i: integer ;

begin

c:="00000000";

d:="11111111";

if sel = "00" then --计算A+B

f(0)<= a(0)xor b(0);

c(0):= a(0)and b(0);

for i in 1 to 7 loop

f(i)<= a(i) xor b(i) xor c(i-1);

c(i):= (a(i)and b(i))or(a(i)and c(i-1))or(b(i)and c(i-1));

end loop;

elsif sel = "01" then --计算A-B 如果是A小于B,计算的是A-B的绝对值

f(0)<=a(0) xor b(0);

c(0):=not a(0) and b(0);

for i in 1 to 7 loop

f(i)<=a(i) xor b(i) xor c(i-1);

c(i):=(b(i) and c(i-1)) or ((b(i) xor c(i-1)) and (not a(i)));

end loop;

elsif sel="10" then--A算数左移m位

--f<=to_stdlogicvector( to_bitvector(A) SLA conv_integer(B)) ;--A算数左移B位

--直接调用的话用上面的

f(7 downto m)<=A(7-m downto 0);

f(m-1 downto 0)<=c(m-1 downto 0);

elsif sel="11" then--A算数右移m位

--f<=to_stdlogicvector( to_bitvector(A) SRA conv_integer(B)) ;--A算数右移B位

--直接调用的话用上面的

f(7-m downto 0)<=A(7 downto m);

if A(7)='0' then

f(7 downto 7-m+1)<=c(7 downto 7-m+1);

else

f(7 downto 7-m+1)<=d(7 downto 7-m+1);

end if;

end if;

end process;

end Behavioral;  

 

  • 电路仿真和结果

testbench如下:

1)verilog

`timescale 1ns / 1ps

module alu_testbench;

reg [7:0]a;

reg [7:0]b;

reg [1:0]sel;

wire [7:0]out;

 

alu UUT (

.a(a),

.b(b),

.sel(sel),

.out(out));

  

initial

begin

a=8'd0;

b=8'd0;

sel=2'd0;

end

always  

fork

#10 sel= 2'b00 ;

#20 sel= 2'b01 ;

#30 sel= 2'b10 ;

#40 sel= 2'b11 ;

#50 sel= 2'b00 ;

#60 sel= 2'b01 ;

#70 sel= 2'b10 ;

#80 sel= 2'b11 ;

#10 a=8'd8;

#50 a=8'd16;

#90 $finish;

#10 b=8'd1;

#50 b=8'd3;

#90 $finish;

join

endmodule

仿真加减法都比较明显,重点是观察算数移位。当进行算数左移时,和逻辑左移相同,右侧补零。当进行算数右移时,右侧要补和符号位相同的数。

实验的结果和预期吻合良好

VHDL版

library ieee;

use ieee.STD_LOGIC_UNSIGNED.all;

use ieee.std_logic_1164.all;

 

-- Add your library and packages declaration here ...

 

entity alu_b_tb is

end alu_b_tb;

 

architecture TB_ARCHITECTURE of alu_b_tb is

-- Component declaration of the tested unit

component alu_b

port(

A : in STD_LOGIC_VECTOR(7 downto 0);

B : in STD_LOGIC_VECTOR(7 downto 0);

signal m :  integer;

sel : in STD_LOGIC_VECTOR(0 to 1);

F : out STD_LOGIC_VECTOR(7 downto 0) );

end component;

 

-- Stimulus signals - signals mapped to the input and inout ports of tested entity

signal A : STD_LOGIC_VECTOR(7 downto 0);

signal B : STD_LOGIC_VECTOR(7 downto 0);

signal m :  integer;

signal sel : STD_LOGIC_VECTOR(0 to 1);

-- Observed signals - signals mapped to the output ports of tested entity

signal F : STD_LOGIC_VECTOR(7 downto 0);

 

-- Add your code here ...

 

begin

 

-- Unit Under Test port map

UUT : alu_b

port map (

A => A,

B => B,

sel => sel,

F => F,

m=>m

);

 

-- Add your stimulus here ...

 

A<="00001001", "00000011" after 50 ns, "00000110" after 100 ns, "00000001" after 150 ns, "10000000" after 200 ns;

B<="00000001", "00000010" after 50 ns, "00000010" after 100 ns, "00000001" after 150 ns, "10100000" after 200 ns;

m<=0,2 after 150ns,1 after 200ns;

sel <="00" ,"00" after 50 ns, "01" after 100 ns,"10" after 150 ns, "11" after 200 ns;

 

end TB_ARCHITECTURE;

 

configuration TESTBENCH_FOR_alu_b of alu_b_tb is

for TB_ARCHITECTURE

for UUT : alu_b

use entity work.alu_b(behavioral);

end for;

end for;

end TESTBENCH_FOR_alu_b;

 

  • 7
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值