作业-基于verilog HDL的八位超前进位加法器

合集下载

应用VHDL语言设计八位二进制加法器

应用VHDL语言设计八位二进制加法器
返回
§4.2 完成工作任务的引导
一、资讯
要完成应用VHDL语言设计出一个八位二进制加法器,请大家 认真阅读4.3节所介绍的基本内容,并复习3.2节的有关介绍。
二、计划
类似3.2节中提出有3种应用原理图设计输入法实现八位二进制
加法器的方案,应用VHDL语言设计八位二进制加法器也有多种
方案。
第一种方案:以8个全加器为底层模块,用VHDL语言层次设计
法设计八位二进制加法器。
第二种方案:运用在程序包ieee.std_logic_signed中定义
的标准逻辑位矢量的加法来设计八位二进制加法器。
下一页
§4.2 完成工作任务的引导
第三种方案:应用VHDL语言设计法中的LPM方法来设计八位 二进制加法器。
三、决策
第一种方案与第3章的第一种方案相似,其实这种方案不是设计 上最简单的方案,也不是性能最好的方案。但它所应用的层次设计 法是VHDL语言设计中重要的一种方法,建议大家应用这种方法做 一次。
第4章 应用VHDL语言方法设计 八位二进制加法器
【要求】
应用VHDL语言设计八位二进制加法器
【知识点】•ຫໍສະໝຸດ 应用VHDL语言设计八位二进制加法器

掌握VHDL语言输入法

掌握VHDL语言层次化设计方法
【重点和难点】
应用VHDL语言设计八位二进制加法器
下一页
第4章 应用VHDL语言方法设计 八位二进制加法器
end add4;
上一页 下一页
§4.3 相关技术基础知识与基本技能
architecture b of add4 is signal ct:std_logic_vector(6 downto 0); component fulladd is

verilog hdl语言100例详解

verilog hdl语言100例详解

verilog hdl语言100例详解Verilog HDL语言是一种硬件描述语言,用于描述数字电路和系统的行为和结构。

它是硬件设计工程师在数字电路设计中的重要工具。

本文将介绍100个例子,详细解释Verilog HDL语言的应用。

1. 基本门电路:Verilog HDL可以用于描述基本门电路,如与门、或门、非门等。

例如,下面是一个描述与门电路的Verilog HDL代码:```verilogmodule and_gate(input a, input b, output y);assign y = a & b;endmodule```2. 多路选择器:Verilog HDL也可以用于描述多路选择器。

例如,下面是一个描述2:1多路选择器的Verilog HDL代码:```verilogmodule mux_2to1(input a, input b, input sel, output y);assign y = sel ? b : a;endmodule```3. 寄存器:Verilog HDL可以用于描述寄存器。

例如,下面是一个描述8位寄存器的Verilog HDL代码:```verilogmodule register_8bit(input [7:0] d, input clk, input reset, output reg [7:0] q);always @(posedge clk or posedge reset)if (reset)q <= 0;elseq <= d;endmodule```4. 计数器:Verilog HDL可以用于描述计数器。

例如,下面是一个描述8位计数器的Verilog HDL代码:```verilogmodule counter_8bit(input clk, input reset, output reg [7:0] count);always @(posedge clk or posedge reset)if (reset)count <= 0;elsecount <= count + 1;endmodule```5. 加法器:Verilog HDL可以用于描述加法器。

verilogHDL(王金明版源码)

verilogHDL(王金明版源码)

王金明:《Verilog HDL 程序设计教程》- 1 -【例3.1】4 位全加器module adder4(cout,sum,ina,inb,cin);output[3:0] sum;output cout;input[3:0] ina,inb;input cin;assign {cout,sum}=ina+inb+cin;endmodule【例3.2】4 位计数器module count4(out,reset,clk);output[3:0] out;input reset,clk;reg[3:0] out;always @(posedge clk)beginif (reset) out<=0; //同步复位else out<=out+1; //计数endendmodule【例3.3】4 位全加器的仿真程序`timescale 1ns/1ns`include "adder4.v"module adder_tp; //测试模块的名字reg[3:0] a,b; //测试输入信号定义为reg 型reg cin;wire[3:0] sum; //测试输出信号定义为wire 型wire cout;integer i,j;adder4 adder(sum,cout,a,b,cin); //调用测试对象always #5 cin=~cin; //设定cin 的取值initialbegina=0;b=0;cin=0;for(i=1;i<16;i=i+1)#10 a=i; //设定a 的取值Endinitialbeginfor(j=1;j<16;j=j+1)#10 b=j; //设定b 的取值Endinitial //定义结果显示格式begin$monitor($time,,,"%d + %d + %b={%b,%d}",a,b,cin,cout,sum);#160 $finish;endendmodule【例3.4】4 位计数器的仿真程序`timescale 1ns/1ns`include "count4.v"module coun4_tp;reg clk,reset; //测试输入信号定义为reg 型wire[3:0] out; //测试输出信号定义为wire 型parameter DELY=100;count4 mycount(out,reset,clk); //调用测试对象always #(DELY/2) clk = ~clk; //产生时钟波形initialbegin //激励信号定义clk =0; reset=0;#DELY reset=1;#DELY reset=0;#(DELY*20) $finish;end//定义结果显示格式initial $monitor($time,,,"clk=%d reset=%d out=%d", clk, reset,out);endmodule【例3.5】“与-或-非”门电路module AOI(A,B,C,D,F); //模块名为AOI(端口列表A,B,C,D,F) input A,B,C,D; //模块的输入端口为A,B,C,Doutput F; //模块的输出端口为Fwire A,B,C,D,F; //定义信号的数据类型assign F= ~((A&B)|(C&D)); //逻辑功能描述endmodule【例5.1】用case 语句描述的4 选1 数据选择器module mux4_1(out,in0,in1,in2,in3,sel);output out;input in0,in1,in2,in3;input[1:0] sel;reg out;always @(in0 or in1 or in2 or in3 or sel) //敏感信号列表case(sel)2'b00: out=in0;2'b01: out=in1;2'b10: out=in2;2'b11: out=in3;default: out=2'bx;endcaseendmodule【例5.2】同步置数、同步清零的计数器module count(out,data,load,reset,clk);output[7:0] out;input[7:0] data;input load,clk,reset;reg[7:0] out;always @(posedge clk) //clk 上升沿触发beginif (!reset) out = 8'h00; //同步清0,低电平有效else if (load) out = data; //同步预置else out = out + 1; //计数endendmodule【例5.3】用always 过程语句描述的简单算术逻辑单元`define add 3'd0`define minus 3'd1`define band 3'd2`define bor 3'd3`define bnot 3'd4module alu(out,opcode,a,b);output[7:0] out;reg[7:0] out;input[2:0] opcode; //操作码input[7:0] a,b; //操作数always@(opcode or a or b) //电平敏感的always 块begincase(opcode)`add: out = a+b; //加操作`minus: out = a-b; //减操作`band: out = a&b; //求与`bor: out = a|b; //求或`bnot: out=~a; //求反default: out=8'hx; //未收到指令时,输出任意态endcaseendendmodule`timescale 1ns/1ns`include "alu.v"module alu_tb;wire [7:0] out;reg [7:0] a,b;reg [2:0] opcode;initialbegina = 8'h12;b = 8'h34;opcode = `add;#10 opcode = `minus;#10 opcode = `band;#10 opcode = `bor;#10 opcode = `bnot;endalu alu(.out(out),.a(a),.b(b),.opcode(opcode)); endmodule【例5.4】用initial 过程语句对测试变量A、B、C 赋值`timescale 1ns/1nsmodule test;reg A,B,C;initialbeginA = 0;B = 1;C = 0;#50 A = 1; B = 0;#50 A = 0; C = 1;#50 B = 1;#50 B = 0; C = 0;#50 $finish ;endendmodule【例5.5】用begin-end 串行块产生信号波形`timescale 10ns/1nsmodule wave1;reg wave;parameter cycle=10;initialbeginwave=0;#(cycle/2) wave=1;#(cycle/2) wave=0;#(cycle/2) wave=1;#(cycle/2) wave=0;#(cycle/2) wave=1;#(cycle/2) $finish ;endinitial $monitor($time,,,"wave=%b",wave); endmodule【例5.6】用fork-join 并行块产生信号波形`timescale 10ns/1nsmodule wave2;reg wave;parameter cycle=5;initialforkwave=0;#(cycle) wave=1;#(2*cycle) wave=0;#(3*cycle) wave=1;#(4*cycle) wave=0;#(5*cycle) wave=1;#(6*cycle) $finish;joininitial $monitor($time,,,"wave=%b",wave); endmodule【例5.7】持续赋值方式定义的2 选1 多路选择器module MUX21_1(out,a,b,sel);input a,b,sel;output out;assign out=(sel==0)?a:b;//持续赋值,如果sel 为0,则out=a ;否则out=b Endmodule【例5.8】阻塞赋值方式定义的2 选1 多路选择器module MUX21_2(out,a,b,sel);input a,b,sel;output out;reg out;always@(a or b or sel)beginif(sel==0) out=a; //阻塞赋值else out=b;endendmodule【例5.9】非阻塞赋值module non_block(c,b,a,clk);output c,b;input clk,a;reg c,b;always @(posedge clk)beginb<=a;c<=b;endendmodule【例5.10】阻塞赋值module block(c,b,a,clk);output c,b;input clk,a;reg c,b;always @(posedge clk)beginb=a;c=b;endendmodule`timescale 1ns/1ns`include "block.v"module block_tb;wire c,b;reg clk,a;initialbeginclk = 0;a = 0;#30 a = 1;#30 a = 0;#30 a = 1;#30 $stop;endalways #10 clk = ~clk;block block(.c(c),.b(b),.clk(clk),.a(a));endmodule【例5.11】模为60 的BCD 码加法计数器module count60(qout,cout,data,load,cin,reset,clk); output[7:0] qout;output cout;input[7:0] data;input load,cin,clk,reset;reg[7:0] qout;always @(posedge clk) //clk 上升沿时刻计数beginif (reset) qout<=0; //同步复位else if(load) qout<=data; //同步置数else if(cin)beginif(qout[3:0]==9) //低位是否为9,是则beginqout[3:0]<=0; //回0,并判断高位是否为5if (qout[7:4]==5) qout[7:4]<=0;elseqout[7:4]<=qout[7:4]+1; //高位不为5,则加1endelse //低位不为9,则加1qout[3:0]<=qout[3:0]+1;endendassign cout=((qout==8'h59)&cin)?1:0; //产生进位输出信号endmodule`timescale 1ns/1ns`include "count60.v"module count60_tb;wire [7:0] qout;wire cout;reg [7:0] data;reg load,cin,clk,reset;always #5 clk = ~clk;count60cnt(.qout(qout),.cout(cout),.data(data),.load(load),.cin(cin),.cl k(clk),.reset(reset));initialbeginclk = 0;reset = 1;load = 1; cin = 0; data = 8'h25;#20 reset = 0;#20 load = 0;#30 cin = 1;#100 load = 1;#30 load = 0;#300 cin = 0;#50 cin = 1;#500 $stop;endendmodule【例5.12】BCD 码—七段数码管显示译码器module decode4_7(decodeout,indec);output[6:0] decodeout;input[3:0] indec;reg[6:0] decodeout;always @(indec)begincase(indec) //用case 语句进行译码4'd0:decodeout=7'b1111110;4'd1:decodeout=7'b0110000;4'd2:decodeout=7'b1101101;4'd3:decodeout=7'b1111001;4'd4:decodeout=7'b0110011;4'd5:decodeout=7'b1011011;4'd6:decodeout=7'b1011111;4'd7:decodeout=7'b1110000;4'd8:decodeout=7'b1111111;4'd9:decodeout=7'b1111011;default: decodeout=7'bx;endcaseendendmodule【例5.13】用casez 描述的数据选择器module mux_casez(out,a,b,c,d,select); output out;input a,b,c,d;input[3:0] select;reg out;always @(select or a or b or c or d) begincasez(select)4'b1: out = a;4'b??1?: out = b;4'b?1??: out = c;4'b1: out = d;endcaseendendmodule【例5.14】隐含锁存器举例module buried_ff(c,b,a);output c;input b,a;reg c;always @(a or b)beginif((b==1)&&(a==1)) c=a&b;endendmodule【例5.15】用for 语句描述的七人投票表决器module voter7(pass,vote);output pass;input[6:0] vote;reg[2:0] sum;integer i;reg pass;always @(vote)beginsum=0;- 9 -for(i=0;i<=6;i=i+1) //for 语句if(vote[i]) sum=sum+1;if(sum[2]) pass=1; //若超过4 人赞成,则pass=1else pass=0;endendmodule【例5.16】用for 语句实现2 个8 位数相乘module mult_for(outcome,a,b);parameter size=8;input[size:1] a,b; //两个操作数output[2*size:1] outcome; //结果reg[2*size:1] outcome;integer i;always @(a or b)beginoutcome=0;for(i=1; i<=size; i=i+1) //for 语句if(b[i]) outcome=outcome +(a << (i-1));endendmodule【例5.17】用repeat 实现8 位二进制数的乘法module mult_repeat(outcome,a,b);parameter size=8;input[size:1] a,b;output[2*size:1] outcome;reg[2*size:1] temp_a,outcome;reg[size:1] temp_b;always @(a or b)beginoutcome=0;temp_a=a;temp_b=b;repeat(size) //repeat 语句,size 为循环次数beginif(temp_b[1]) //如果temp_b 的最低位为1,就执行下面的加法outcome=outcome+temp_a;temp_a=temp_a<<1; //操作数a 左移一位程序文本- 10 -temp_b=temp_b>>1; //操作数b 右移一位endendendmodule`include "mult_repeat.v"module mult_repeat_tb;parameter size = 8;reg [size:1] a,b;wire [2*size:1] outcome;initialbegina = 8'h25;b = 8'h16;#10 a = 8'ha4; b = 8'h20;endmult_repeat mult(.a(a),.b(b),.outcome(outcome)); endmodule【例5.18】同一循环的不同实现方式module loop1; //方式1integer i;initialfor(i=0;i<4;i=i+1) //for 语句begin$display(“i=%h”,i);endendmodulemodule loop2; //方式2integer i;initial begini=0;while(i<4) //while 语句begin$display ("i=%h",i);i=i+1;endendendmodulemodule loop3; //方式3integer i;initial begini=0;repeat(4) //repeat 语句begin$display ("i=%h",i);i=i+1;endendendmodule【例5.19】使用了`include 语句的16 位加法器- 11 -`include "adder.v"module adder16(cout,sum,a,b,cin);output cout;parameter my_size=16;output[my_size-1:0] sum;input[my_size-1:0] a,b;input cin;adder my_adder(cout,sum,a,b,cin); //调用adder 模块endmodule//下面是adder 模块代码module adder(cout,sum,a,b,cin);parameter size=16;output cout;output[size-1:0] sum;input cin;input[size-1:0] a,b;assign {cout,sum}=a+b+cin;endmodule【例5.20】条件编译举例module compile(out,A,B);output out;input A,B;`ifdef add //宏名为addassign out=A+B;`elseassign out=A-B;`endifEndmodule【例6.1】加法计数器中的进程module count(data,clk,reset,load,cout,qout);output cout;output[3:0] qout;reg[3:0] qout;input[3:0] data;input clk,reset,load;程序文本- 12 -always @(posedge clk) //进程1,always 过程块beginif (!reset) qout= 4'h00; //同步清0,低电平有效else if (load) qout= data; //同步预置else qout=qout + 1; //加法计数endassign cout=(qout==4'hf)?1:0; //进程2,用持续赋值产生进位信号endmodule【例6.2】任务举例module alutask(code,a,b,c);input[1:0] code;input[3:0] a,b;output[4:0] c;reg[4:0] c;task my_and; //任务定义,注意无端口列表input[3:0] a,b; //a,b,out 名称的作用域范围为task 任务内部output[4:0] out;integer i;beginfor(i=3;i>=0;i=i-1)out[i]=a[i]&b[i]; //按位与endendtaskalways@(code or a or b)begincase(code)2'b00: my_and(a,b,c);/* 调用任务my_and,需注意端口列表的顺序应与任务定义中的一致,这里的a,b,c 分别对应任务定义中的a,b,out */2'b01: c=a|b; //或2'b10: c=a-b; //相减2'b11: c=a+b; //相加endcaseendendmodule- 13 -【例6.3】测试程序`include "alutask.v"module alu_tp;reg[3:0] a,b;reg[1:0] code;wire[4:0] c;parameter DELY = 100;alutask ADD(code,a,b,c); //调用被测试模块initial begincode=4'd0; a= 4'b0000; b= 4'b1111;#DELY code=4'd0; a= 4'b0111; b= 4'b1101;#DELY code=4'd1; a= 4'b0001; b= 4'b0011;#DELY code=4'd2; a= 4'b1001; b= 4'b0011;#DELY code=4'd3; a= 4'b0011; b= 4'b0001;#DELY code=4'd3; a= 4'b0111; b= 4'b1001;#DELY $finish;endinitial $monitor($time,,,"code=%b a=%b b=%b c=%b", code,a,b,c); endmodule【例6.4】函数function[7:0] get0;input[7:0] x;reg[7:0] count;integer i;begincount=0;for (i=0;i<=7;i=i+1)if (x[i]=1'b0) count=count+1;get0=count;endendfunction【例6.5】用函数和case 语句描述的编码器(不含优先顺序)module code_83(din,dout);input[7:0] din;output[2:0] dout;程序文本- 14 -function[2:0] code; //函数定义input[7:0] din; //函数只有输入,输出为函数名本身casex (din)8'b1xxx_xxxx : code = 3'h7;8'b01xx_xxxx : code = 3'h6;8'b001x_xxxx : code = 3'h5;8'b0001_xxxx : code = 3'h4;8'b0000_1xxx : code = 3'h3;8'b0000_01xx : code = 3'h2;8'b0000_001x : code = 3'h1;8'b0000_000x : code = 3'h0;default: code = 3'hx;endcaseendfunctionassign dout = code(din) ; //函数调用endmodule【例6.6】阶乘运算函数module funct(clk,n,result,reset);output[31:0] result;input[3:0] n;input reset,clk;reg[31:0] result;always @(posedge clk) //在clk 的上升沿时执行运算beginif(!reset) result<=0; //复位else beginresult <= 2 * factorial(n); //调用factorial 函数endendfunction[31:0] factorial; //阶乘运算函数定义(注意无端口列表)input[3:0] opa; //函数只能定义输入端,输出端口为函数名本身reg[3:0] i;beginfactorial = opa ? 1 : 0;for(i= 2; i <= opa; i = i+1) //该句若要综合通过,opa 应赋具体的数值factorial = i* factorial; //阶乘运算end- 15 -endfunctionendmodule【例6.7】测试程序`define clk_cycle 50`include "funct.v"module funct_tp;reg[3:0] n;reg reset,clk;wire[31:0] result;initial //定义激励向量beginn=0; reset=1; clk=0;for(n=0;n<=15;n=n+1)#100 n=n;endinitial $monitor($time,,,"n=%d result=%d",n,result);//定义输出显示格式always #1 `clk_cycle clk=~clk; //产生时钟信号funct funct_try(.clk(clk),.n(n),.result(result),.reset(reset)); //调用被测试模块Endmodule【例6.8】顺序执行模块1module serial1(q,a,clk);output q,a;input clk;reg q,a;always @(posedge clk)beginq=~q;a=~q;endendmodule【例6.9】顺序执行模块2module serial2(q,a,clk);output q,a;程序文本- 16 -input clk;reg q,a;always @(posedge clk)begina=~q;q=~q;endendmodule【例6.10】并行执行模块1module paral1(q,a,clk);output q,a;input clk;reg q,a;always @(posedge clk)beginq=~q;endalways @(posedge clk)begina=~q;endendmodule【例6.11】并行执行模块2module paral2(q,a,clk);output q,a;input clk;reg q,a;always @(posedge clk)begina=~q;endalways @(posedge clk)beginq=~q;endendmodule【例7.1】调用门元件实现的4 选1 MUX- 17 -module mux4_1a(out,in1,in2,in3,in4,cntrl1,cntrl2); output out;input in1,in2,in3,in4,cntrl1,cntrl2;wire notcntrl1,notcntrl2,w,x,y,z;not (notcntrl1,cntrl2),(notcntrl2,cntrl2);and (w,in1,notcntrl1,notcntrl2),(x,in2,notcntrl1,cntrl2),(y,in3,cntrl1,notcntrl2),(z,in4,cntrl1,cntrl2);or (out,w,x,y,z);endmodule【例7.2】用case 语句描述的4 选1 MUXmodule mux4_1b(out,in1,in2,in3,in4,cntrl1,cntrl2);output out;input in1,in2,in3,in4,cntrl1,cntrl2;reg out;always@(in1 or in2 or in3 or in4 or cntrl1 or cntrl2)case({cntrl1,cntrl2})2'b00:out=in1;2'b01:out=in2;2'b10:out=in3;2'b11:out=in4;default:out=2'bx;endcaseendmodule【例7.3】行为描述方式实现的4 位计数器module count4(clk,clr,out);input clk,clr;output[3:0] out;reg[3:0] out;always @(posedge clk or posedge clr)beginif (clr) out<=0;else out<=out+1;endendmodule程序文本- 18 -【例7.4】数据流方式描述的4 选1 MUXmodule mux4_1c(out,in1,in2,in3,in4,cntrl1,cntrl2);output out;input in1,in2,in3,in4,cntrl1,cntrl2;assign out=(in1 & ~cntrl1 & ~cntrl2)|(in2 & ~cntrl1 & cntrl2)| (in3 & cntrl1 & ~cntrl2)|(in4 & cntrl1 & cntrl2);Endmodule【例7.5】用条件运算符描述的4 选1 MUXmodule mux4_1d(out,in1,in2,in3,in4,cntrl1,cntrl2);output out;input in1,in2,in3,in4,cntrl1,cntrl2;assign out=cntrl1 ? (cntrl2 ? in4:in3):(cntrl2 ? in2:in1); endmodule【例7.6】门级结构描述的2 选1MUXmodule mux2_1a(out,a,b,sel);output out;input a,b,sel;not (sel_,sel);and (a1,a,sel_),(a2,b,sel);or (out,a1,a2);endmodule【例7.7】行为描述的2 选1MUXmodule mux2_1b(out,a,b,sel); output out;input a,b,sel;reg out;always @(a or b or sel)beginif(sel) out = b;else out = a;endendmodule【例7.8】数据流描述的2 选1MUX module MUX2_1c(out,a,b,sel); output out;- 19 -input a,b,sel;assign out = sel ? b : a; endmodule【例7.9】调用门元件实现的1 位半加器module half_add1(a,b,sum,cout); input a,b;output sum,cout;and (cout,a,b);xor (sum,a,b);endmodule【例7.10】数据流方式描述的1 位半加器module half_add2(a,b,sum,cout); input a,b;output sum,cout;assign sum=a^b;assign cout=a&b;endmodule【例7.11】采用行为描述的1 位半加器module half_add3(a,b,sum,cout); input a,b;output sum,cout;reg sum,cout;always @(a or b)begincase ({a,b}) //真值表描述2'b00: begin sum=0; cout=0; end2'b01: begin sum=1; cout=0; end2'b10: begin sum=1; cout=0; end2'b11: begin sum=0; cout=1; end endcaseendendmodule【例7.12】采用行为描述的1 位半加器module half_add4(a,b,sum,cout); input a,b;output sum,cout;程序文本- 20 -reg sum,cout;always @(a or b)beginsum= a^b;cout=a&b;endendmodule【例7.13】调用门元件实现的1 位全加器module full_add1(a,b,cin,sum,cout); input a,b,cin;output sum,cout;wire s1,m1,m2,m3;and (m1,a,b),(m2,b,cin),(m3,a,cin);xor (s1,a,b),(sum,s1,cin);or (cout,m1,m2,m3);endmodule【例7.14】数据流描述的1 位全加器module full_add2(a,b,cin,sum,cout);input a,b,cin;output sum,cout;assign sum = a ^ b ^ cin;assign cout = (a & b)|(b & cin)|(cin & a);endmodule【例7.15】1 位全加器module full_add3(a,b,cin,sum,cout);input a,b,cin;output sum,cout;assign {cout,sum}=a+b+cin;endmodule【例7.16】行为描述的1 位全加器module full_add4(a,b,cin,sum,cout);input a,b,cin;output sum,cout;- 21 -reg sum,cout; //在always 块中被赋值的变量应定义为reg 型reg m1,m2,m3;always @(a or b or cin)beginsum = (a ^ b) ^ cin;m1 = a & b;m2 = b & cin;m3 = a & cin;cout = (m1|m2)|m3;endendmodule【例7.17】混合描述的1 位全加器module full_add5(a,b,cin,sum,cout);input a,b,cin;output sum,cout;reg cout,m1,m2,m3; //在always 块中被赋值的变量应定义为reg 型wire s1;xor x1(s1,a,b); //调用门元件always @(a or b or cin) //always 块语句beginm1 = a & b;m2 = b & cin;m3 = a & cin;cout = (m1| m2) | m3;endassign sum = s1 ^ cin; //assign 持续赋值语句endmodule【例7.18】结构描述的4 位级连全加器`include "full_add1.v"module add4_1(sum,cout,a,b,cin);output[3:0] sum;output cout;input[3:0] a,b;input cin;full_add1 f0(a[0],b[0],cin,sum[0],cin1); //级连描述full_add1 f1(a[1],b[1],cin1,sum[1],cin2);full_add1 f2(a[2],b[2],cin2,sum[2],cin3);程序文本- 22 -full_add1 f3(a[3],b[3],cin3,sum[3],cout); endmodule【例7.19】数据流描述的4 位全加器module add4_2(cout,sum,a,b,cin);output[3:0] sum;output cout;input[3:0] a,b;input cin;assign {cout,sum}=a+b+cin;endmodule【例7.20】行为描述的4 位全加器module add4_3(cout,sum,a,b,cin);output[3:0] sum;output cout;input[3:0] a,b;input cin;reg[3:0] sum;reg cout;always @(a or b or cin)begin{cout,sum}=a+b+cin;endendmodule【例8.1】$time 与$realtime 的区别`timescale 10ns/1nsmodule time_dif;reg ts;parameter delay=2.6;initialbegin#delay ts=1;#delay ts=0;#delay ts=1;#delay ts=0;endinitial $monitor($time,,,"ts=%b",ts); //使用函数$time- 23 -Endmodule【例8.2】$random 函数的使用`timescale 10ns/1nsmodule random_tp;integer data;integer i;parameter delay=10;initial $monitor($time,,,"data=%b",data);initial beginfor(i=0; i<=100; i=i+1)#delay data=$random; //每次产生一个随机数endendmodule【例8.3】1 位全加器进位输出UDP 元件primitive carry_udp(cout,cin,a,b);input cin,a,b;output cout;table//cin a b : cout //真值表0 0 0 : 0;0 1 0 : 0;0 0 1 : 0;0 1 1 : 1;1 0 0 : 0;1 0 1 : 1;1 1 0 : 1;1 1 1 : 1;endtableendprimitive【例8.4】包含x 态输入的1 位全加器进位输出UDP 元件primitive carry_udpx1(cout,cin,a,b);input cin,a,b;output cout;table// cin a b : cout //真值表0 0 0 : 0;程序文本- 24 -0 1 0 : 0;0 0 1 : 0;0 1 1 : 1;1 0 0 : 0;1 0 1 : 1;1 1 0 : 1;1 1 1 : 1;0 0 x : 0; //只要有两个输入为0,则进位输出肯定为00 x 0 : 0;x 0 0 : 0;1 1 x : 1; //只要有两个输入为1,则进位输出肯定为11 x 1 : 1;x 1 1 : 1;endtableendprimitive【例8.5】用简缩符“?”表述的1 位全加器进位输出UDP 元件primitive carry_udpx2(cout,cin,a,b);input cin,a,b;output cout;// cin a b : cout //真值表0 0 : 0; //只要有两个输入为0,则进位输出肯定为00 ? 0 : 0;0 0 ? : 0;1 1 : 1; //只要有两个输入为1,则进位输出肯定为11 ? 1 : 1;1 1 ? : 1;endtableendprimitive【例8.6】3 选1 多路选择器UDP 元件primitive mux31(Y,in0,in1,in2,s2,s1);input in0,in1,in2,s2,s1;output Y;table//in0 in1 in2 s2 s1 : Y0 ? ? 0 0 : 0; //当s2s1=00 时,Y=in01 ? ? 0 0 : 1;0 0 1 : 0; //当s2s1=01 时,Y=in1- 25 -1 0 1 : 1;0 1 : 0; //当s2s1=1?时,Y=in21 1 : 1;0 0 ? 0 ? : 0;1 1 ? 0 ? : 1;0 ? 0 ? 0 : 0;1 ? 1 ? 0 : 1;0 0 1 : 0;1 1 1 : 1;endtableendprimitive【例8.7】电平敏感的1 位数据锁存器UDP 元件primitive latch(Q,clk,reset,D);input clk,reset,D;output Q;initial Q = 1'b1; //初始化table// clk reset D : state : Q1 : : 0 ; //reset=1,则不管其他端口为什么值,输出都为0 0 0 0 : ? : 0 ; //clk=0,锁存器把D 端的输入值输出0 0 1 : ? : 1 ;1 0 ? : ? : - ; //clk=1,锁存器的输出保持原值,用符号“-”表示endtableendprimitive【例8.8】上升沿触发的D 触__________发器UDP 元件primitive DFF(Q,D,clk);output Q;input D,clk;reg Q;table//clk D : state : Q(01) 0 : ? : 0; //上升沿到来,输出Q=D(01) 1 : ? : 1;(0x) 1 : 1 : 1;(0x) 0 : 0 : 0;(?0) ? : ? : -; //没有上升沿到来,输出Q 保持原值() : : - ; //时钟不变,输出也不变程序文本- 26 -endtableendprimitive【例8.9】带异步置1 和异步清零的上升沿触发的D 触发器UDP 元件primitive DFF_UDP(Q,D,clk,clr,set);output Q;input D,clk,clr,set;reg Q;table// clk D clr set : state : Q(01) 1 0 0 : ? : 0;(01) 1 0 x : ? : 0;0 x : 0 : 0;(01) 0 0 0 : ? : 1;(01) 0 x 0 : ? : 1;x 0 : 1 : 1;(x1) 1 0 0 : 0 : 0;(x1) 0 0 0 : 1 : 1;(0x) 1 0 0 : 0 : 0;(0x) 0 0 0 : 1 : 1;1 : : 1; //异步复位 0 1 : : 0; //异步置1n ? 0 0 : ? : -;* : : -;(0) : : -;(0): : -;: : x;endtableendprimitive【例8.12】延迟定义块举例module delay(out,a,b,c); output out;input a,b,c;and a1(n1,a,b);or o1(out,c,n1);specify(a=>out)=2;(b=>out)=3;(c=>out)=1;- 27 -endspecifyendmodule【例8.13】激励波形的描述'timescale 1ns/1nsmodule test1;reg A,B,C;initialbegin //激励波形描述A = 0;B = 1;C = 0;#100 C = 1;#100 A = 1; B = 0;#100 A = 0;#100 C = 0;#100 $finish;endinitial $monitor($time,,,"A=%d B=%d C=%d",A,B,C); //显示endmodule【例8.15】用always 过程块产生两个时钟信号module test2;reg clk1,clk2;parameter CYCLE = 100;alwaysbegin{clk1,clk2} = 2'b10;#(CYCLE/4) {clk1,clk2} = 2'b01;#(CYCLE/4) {clk1,clk2} = 2'b11;#(CYCLE/4) {clk1,clk2} = 2'b00;#(CYCLE/4) {clk1,clk2} = 2'b10;endinitial $monitor($time,,,"clk1=%b clk2=%b",clk1,clk2); endmodule【例8.17】存储器在仿真程序中的应用module ROM(addr,data,oe);output[7:0] data; //数据信号input[14:0] addr; //地址信号input oe; //读使能信号,低电平有效程序文本- 28 -reg[7:0] mem[0:255]; //存储器定义parameter DELAY = 100;assign #DELAY data=(oe==0) ? mem[addr] : 8'hzz;initial $readmemh("rom.hex",mem); //从文件中读入数据endmodule【例8.18】8 位乘法器的仿真程序`timescale 10ns/1nsmodule mult8_tp; //测试模块的名字reg[7:0] a,b; //测试输入信号定义为reg 型wire [15:0] out; //测试输出信号定义为wire 型integer i,j;mult8 m1(out,a,b); //调用测试对象//激励波形设定initialbegina=0;b=0;for(i=1;i<255;i=i+1)#10 a=i;endinitialbeginfor(j=1;j<255;j=j+1)#10 b=j;endinitial //定义结果显示格式begin$monitor($time,,,"%d * %d= %d",a,b,out); #2560 $finish;endendmodulemodule mult8(out, a, b); //8 位乘法器源代码parameter size=8;input[size:1] a,b; //两个操作数output[2*size:1] out; //结果assign out=a*b; //乘法运算符- 29 -Endmodule【例8.19】8 位加法器的仿真程序`timescale 1ns/1nsmodule add8_tp; //仿真模块无端口列表reg[7:0] A,B; //输入激励信号定义为reg 型reg cin;wire[7:0] SUM; //输出信号定义为wire 型wire cout;parameter DELY = 100;add8 AD1(SUM,cout,A,B,cin); //调用测试对象initial begin //激励波形设定A= 8'd0; B= 8'd0; cin=1'b0;#DELY A= 8'd100; B= 8'd200; cin=1'b1;#DELY A= 8'd200; B= 8'd88;#DELY A= 8'd210; B= 8'd18; cin=1'b0;#DELY A= 8'd12; B= 8'd12;#DELY A= 8'd100; B= 8'd154;#DELY A= 8'd255; B= 8'd255; cin=1'b1;#DELY $finish;end//输出格式定义initial $monitor($time,,,"%d + %d + %b = {%b, %d}",A,B,cin,cout,SUM); endmodulemodule add8(SUM,cout,A,B,cin); //待测试的8 位加法器模块output[7:0] SUM;output cout;input[7:0] A,B;input cin;assign {cout,SUM}=A+B+cin;endmodule【例8.20】2 选1 多路选择器的仿真`timescale 1ns/1nsmodule mux_tp;reg a,b,sel;wire out;程序文本- 30 -MUX2_1 m1(out,a,b,sel); //调用待测试模块initialbegina=1'b0; b=1'b0; sel=1'b0;#5 sel=1'b1;#5 a=1'b1; sel=1'b0;#5 sel=1'b1;#5 a=1'b0; b=1'b1; sel=1'b0;#5 sel=1'b1;#5 a=1'b1; b=1'b1; sel=1'b0;#5 sel=1'b1;endinitial $monitor($time,,,"a=%b b=%b sel=%b out=%b",a,b,sel,out); endmodulemodule MUX2_1(out,a,b,sel); //待测试的2 选1MUX 模块input a,b,sel;output out;not #(0.4,0.3) (sel_,sel); //#(0.4,0.3)为门延时and #(0.7,0.6) (a1,a,sel_);and #(0.7,0.6) (a2,b,sel);or #(0.7,0.6) (out,a1,a2);endmodule【例8.21】8 位计数器的仿真`timescale 10ns/1nsmodule counter8_tp;reg clk,reset; //输入激励信号定义为reg 型wire[7:0] qout; //输出信号定义为wire 型parameter DELY=100;counter8 C1(qout,reset,clk); //调用测试对象always #(DELY/2) clk = ~clk; //产生时钟波形initialbegin //激励波形定义clk =0; reset=0;- 31 -#DELY reset=1;#DELY reset=0;#(DELY*300) $finish;end//结果显示initial $monitor($time,,,"clk=%d reset=%d qout=%d",clk,reset,qout); endmodulemodule counter8(qout,reset,clk); //待测试的8 位计数器模块output[7:0] qout;input clk,reset;reg[7:0] qout;always @(posedge clk)begin if (reset) qout<=0;else qout<=qout+1;endendmodule【例9.1】基本门电路的几种描述方法(1)门级结构描述module gate1(F,A,B,C,D);input A,B,C,D;output F;nand(F1,A,B); //调用门元件and(F2,B,C,D);or(F,F1,F2);endmodule(2)数据流描述module gate2(F,A,B,C,D);input A,B,C,D;output F;assign F=(A&B)|(B&C&D); //assign 持续赋值endmodule(3)行为描述module gate3(F,A,B,C,D);input A,B,C,D;output F;程序文本- 32 -reg F;always @(A or B or C or D) //过程赋值beginF=(A&B)|(B&C&D);endendmodule【例9.2】用bufif1 关键字描述的三态门module tri_1(in,en,out);input in,en;output out;tri out;bufif1 b1(out,in,en); //注意三态门端口的排列顺序endmodule【例9.3】用assign 语句描述的三态门module tri_2(out,in,en);output out;input in,en;assign out = en ? in : 'bz;//若en=1,则out=in;若en=0,则out 为高阻态Endmodule【例9.4】三态双向驱动器module bidir(tri_inout,out,in,en,b);inout tri_inout;output out;input in,en,b;assign tri_inout = en ? in : 'bz;assign out = tri_inout ^ b;endmodule【例9.5】三态双向驱动器module bidir2(bidir,en,clk);inout[7:0] bidir;input en,clk;reg[7:0] temp;assign bidir= en ? temp : 8'bz;always @(posedge clk)begin- 33 -if(en) temp=bidir;else temp=temp+1;endendmodule【例9.6】3-8 译码器module decoder_38(out,in);output[7:0] out;input[2:0] in;reg[7:0] out;always @(in)begincase(in)3'd0: out=8'b11111110;3'd1: out=8'b11111101;3'd2: out=8'b11111011;3'd3: out=8'b11110111;3'd4: out=8'b11101111;3'd5: out=8'b11011111;3'd6: out=8'b10111111;3'd7: out=8'b01111111;endcaseendendmodule【例9.7】8-3 优先编码器module encoder8_3(none_on,outcode,a,b,c,d,e,f,g,h); output none_on;output[2:0] outcode;input a,b,c,d,e,f,g,h;reg[3:0] outtemp;assign {none_on,outcode}=outtemp;always @(a or b or c or d or e or f or g or h)beginif(h) outtemp=4'b0111;else if(g) outtemp=4'b0110;else if(f) outtemp=4'b0101;else if(e) outtemp=4'b0100;else if(d) outtemp=4'b0011;。

Verilog-HDL中的语句

Verilog-HDL中的语句

第三章 Verilog-HDL中的语句1.基本语句1.1赋值语句赋值语句分为连续赋值语句和过程赋值语句。

1.1.1连续赋值语句1.连续赋值语句用于把值赋给wire型变量(不能为reg型变量赋值)。

语句形式为:assign A = B & C;a.只要在右端表达式的操作数上有事件(事件为值的变化)发生时,表达式即被计算;b.如果计算的结果值有变化,新结果就赋给左边的线网。

2.连续赋值的目标类型♦标量线网 wire a;♦向量线网 wire [7:0] a;♦向量线网的常数型位选择 a[1]♦向量线网的常数型部分选择 a[3:1]♦上述类型的任意的拼接运算结果 {3a[2],a[2:1]}注:多条assign语句可以合并到一起。

3.线网说明赋值连续赋值可作为线网说明本身的一部分。

这样的赋值被称为线网说明赋值。

如: wire Clear = 'b1;等价于 wire clear;assign clear=‘b1;1.1.2 过程赋值语句1.a.过程性赋值是仅仅在initial语句或always语句内的赋值b.它只能对reg型的变量赋值。

表达式的右端可以是任何表达式。

c.过程性赋值分两类:阻塞性过程赋值 =非阻塞性过程赋值<=2.语句内部时延与句间时延a.在赋值语句中表达式右端出现的时延是语句内部时延。

Done = #5 1'b1;b.通过语句内部时延表达式,右端的值在赋给左端目标前被延迟。

即右端表达式在语句内部时延之前计算,随后进入时延等待,再对左端目标赋值。

c.对比以下语句间的时延beginTemp = 1'b1;#5 Done = Temp; //语句间时延控制end3.阻塞性过程赋值a.赋值运算符是“=”的过程赋值是阻塞性过程赋值。

b.阻塞性过程赋值在在下一语句执行前,执行该赋值语句。

例:initialbeginClr = #5 0;Clr = #4 1;Clr = #10 0;end4.非阻塞性过程赋值a .在非阻塞性过程赋值中,使用赋值符号“ <=”。

Verilog实现的4位串行进位加法器精编版

Verilog实现的4位串行进位加法器精编版

Verilog实现的4位串行进位加法器精编版在数字电路中,加法器是最基本的电路之一、串行进位加法器是一种将两个二进制数相加的电路,通过逐位相加的方式实现。

本文将介绍如何使用Verilog语言实现一个4位串行进位加法器的精编版。

首先,我们需要定义输入和输出端口。

对于一个4位的串行进位加法器,我们需要4个输入端口A[3:0]和B[3:0],以及一个输出端口Sum[3:0]。

另外,还需要一个输入端口CarryIn和一个输出端口CarryOut,用于传递进位信号。

```module SerialCarryAdderinput [3:0] A,input [3:0] B,input CarryIn,output [3:0] Sum,output CarryOut```接下来,我们可以定义内部信号。

对于一个4位的串行进位加法器,我们需要4个内部信号,分别代表每一位的进位信号。

```wire C0, C1, C2, C3;```然后,我们可以开始实现每一位的加法逻辑。

首先,我们定义一个内部信号XOROut,用于存储每一位的异或结果。

然后,我们使用XOR门实现异或逻辑。

```wire XOROut;assign XOROut = A[0] ^ B[0];```接下来,我们定义一个内部信号ANDOut,用于存储每一位的与结果。

然后,我们使用AND门实现与逻辑。

```wire ANDOut;assign ANDOut = A[0] & B[0];```然后,我们定义一个内部信号Sum0,用于存储第一位的和结果。

然后,我们使用XOR门实现异或逻辑。

```wire Sum0;assign Sum0 = XOROut ^ CarryIn;```然后,我们定义一个内部信号Carry0,用于存储第一位的进位结果。

然后,我们使用OR门实现或逻辑。

```wire Carry0;assign Carry0 = ANDOut , (XOROut & CarryIn);```接下来,我们可以依次实现剩余3位的加法逻辑。

verilog hdl应用程序设计实例精讲

verilog hdl应用程序设计实例精讲

verilog hdl应用程序设计实例精讲网上现在有很多关于verilog hdl应用程序设计的资料,但是并没有一个很系统和全面的教程来帮助初学者快速入门。

本文就verilog hdl应用程序设计实例进行了精讲,从基本概念到应用实例一步一步地回答了初学者的问题,帮助大家理解verilog hdl的设计和应用。

一、verilog hdl的基本概念Verilog HDL是一种硬件描述语言,用于描述数字系统,包括逻辑电路、集成电路等等。

它既可以进行仿真验证,也可以直接生成硬件电路。

简单来说,verilog hdl就是一种用来描述数字系统的语言。

1.1 模块与实例化在verilog hdl中,模块是最基本的设计单元,每个模块包含一个或多个端口和内部逻辑电路。

模块可以包含其他模块,这被称为实例化。

实例化可以理解为创建一个模块的实例,并根据实例进行连接。

1.2 端口和内部信号模块的端口是与其他模块或外部电路连接的接口,可以是输入、输出或双向。

内部信号是模块内部产生和使用的信号,只在模块内部可见。

1.3 组合逻辑与时序逻辑组合逻辑是指只有输入信号改变时才会改变输出信号的逻辑电路,而时序逻辑是指输出信号的改变还受到时钟信号的控制。

在verilog hdl中,可以使用逻辑门、逻辑运算符和条件语句来实现组合逻辑和时序逻辑。

二、verilog hdl应用程序设计实例接下来,我们通过一些实例来展示verilog hdl的应用程序设计。

2.1 4位全加器我们首先来实现一个4位全加器。

全加器是用来实现两个二进制数的加法的电路,它能够实现两个输入和一个进位的相加操作,输出结果和进位。

在verilog hdl 中,可以使用逻辑运算符和条件语句来实现全加器。

2.2 4位加法器我们可以使用四个全加器来实现一个4位加法器。

加法器是用来实现两个二进制数的加法的电路,它能够实现多位的相加操作,输出结果和进位。

2.3 4位计数器计数器是一种能够实现计数功能的电路,它能够根据时钟信号进行计数,并在达到一定数值时输出特定信号。

Verilog HDL数字设计教程(贺敬凯)第4章


module multiplexer_N( X1,X2,X3,X4, sel,Y);
parameter N=8; //该参数定义了一个8位的4选1多 路选择器 input[N-1: 0] X1,X2,X3,X4;
第4章 Verilog HDL常用电路设计 input[1:0] sel;
output reg [N-1: 0] Y; always @(sel,X1,X2,X3,X4) case(sel) 2'b00: Y = X1;
output reg[N-1:0] out; always @(enable,input3,input2,input1,input0) begin
第4章 Verilog HDL常用电路设计
if(enable==2'b00) out=input3; else out='bz; if(enable==2'b01) out=input2; else out='bz;
endmodule
第4章 Verilog HDL常用电路设计 程序说明:
(1) 程序中定义了一个输入sel,一个输出Y,使用控制 信号sel来确定Y的输出。 (2) 由于本程序涉及求以2为底的对数计算,因此若修改 参数N,sel的位数就要手工做相应调整,这样才可实现任意 位数的译码器。
第4章 Verilog HDL常用电路设计
第4章 Verilog HDL常用电路设计
begin case(sel) 3'b000: result=X+Y; //加法 3'b001: result=X-Y; //减法 3'b010: result=X<<1; //左移1位 3'b011: result=X>>1; //右移1位 3'b100: result=X&Y; //相与 3'b101: result=X^Y; //异或 3'b110: result=~X; //求反 3'b111: result=X; //直通 endcase end endmodule

Verilog HDL入门


线网型:wire,tri
wor,trior,wand,triand,trireg,tri1,tri0 supply0,supply1
寄存器型:
reg integer,time real,realtime
wire和tri
用于连接单元的连线是最常见的线网类型。 默认值为z。 wire与tri语法和语义一致; 三态线可以用于描述多个驱动源驱动同一根线 的线网类型;并且没有其他特殊的意义。 通常都用wire。 其他线网型用于底层设计与仿真,FPGA设计通 常不会涉及。
简单的Verilog程序
该程序例子通过另一种方法描述了一个三态 门。 在这个例子中存在着两个模块:模块trist1 在这个例子中存在着两个模块:模块trist1 tri_inst。 调用模块 mytri 的实例元件 tri_inst。 是上层模块。 模块 trist1 是上层模块。模块 mytri 则被 称为子模块。 称为子模块。 通过这种结构性模块构造可构成特大型模块 。
例:always @(b or c) always a=b&c;
元件(实)例化
例:and and1(a,b,c); BUFG BUFG_inst ( .O(out), // Clock buffer output .I(in) // Clock buffer input );
注意
三种方式可以在同一个模块之内混合使用 ; 同一个模块内可以有多个always块,多个 assign和多个元件例化。 所有这些单元是并行执行的。 这些单元的书写顺序不影响逻辑功能;
128状态值集合:包含强度信息
其他值集合
整数(32bits) 实数 字符串 时间(64bits) 布尔值(0,1) ……
提纲

VHDL流水线加法器

可编程实验报告实验报告要求:1、任务的简单描述2、画出电路图3、写出源代码4、仿真结果5、分析和讨论1、3-8译码器源代码:LIBRARY ieee;USE ieee.std_logic_1164.all;USE ieee.std_logic_arith.all;USE ieee.std_logic_signed.all;ENTITY dc38 ISPORT(sel : in std_logic_vector(2 downto 0);y : out std_logic_vector(7 downto 0)); END dc38;ARCHITECTURE behavior OF dc38 ISBEGINy <= "11111110" WHEN sel = "000" else"11111101" WHEN sel = "001" else"11111011" WHEN sel = "010" else"11110111" WHEN sel = "011" else"11101111" WHEN sel = "100" else"11011111" WHEN sel = "101" else"10111111" WHEN sel = "110" else"01111111" WHEN sel = "111" else"ZZZZZZZZ";END behavior;仿真结果:一位全加器A B CI S CO0 0 0 0 00 0 1 1 00 1 0 1 00 1 1 0 11 0 0 1 01 0 1 0 11 1 0 0 11 1 1 1 1四级流水加法器library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;entity adder isport(clk,rst : in std_logic;a,b : in std_logic_vector(3 downto 0);sum : out std_logic_vector(3 downto 0);c : out std_logic);end entity adder;architecture depict of adder issignal reg1: std_logic_vector(7 downto 0);signal reg2: std_logic_vector(6 downto 0);signal reg3: std_logic_vector(5 downto 0);beginbit0:process(clk,rst)beginif(rst='1') thenreg1<="00000000";elsif(rising_edge(clk)) thenreg1(0)<= a(0) xor b(0);reg1(1)<= a(0) and b(0);reg1(2)<= a(1);reg1(3)<= b(1);reg1(4)<= a(2);reg1(5)<= b(2);reg1(6)<= a(3);reg1(7)<= b(3);end if;end process bit0;bit1:process(clk,rst)beginif(rst='1') thenreg2<="0000000";elsif(rising_edge(clk)) thenreg2(0)<= reg1(0);reg2(1)<= reg1(1) xor reg1(2) xor reg1(3);reg2(2)<= (reg1(1) and reg1(2))or(reg1(1)and reg1(3))or(reg1(2)and reg1(3));reg2(6 downto 3)<=reg1(7 downto 4);end if;end process bit1;bit2:process(clk,rst)beginif(rst='1') thenreg3<="000000";elsif(rising_edge(clk)) thenreg3(1 downto 0)<=reg2(1 downto 0);reg3(2)<=reg2(2)xor reg2(3)xor reg2(4);reg3(3)<=(reg2(2)and reg2(3))or(reg2(2)and reg2(4))or(reg2(3)and reg2(4));reg3(5 downto 4)<=reg2( 6 downto 5);end if;end process bit2;bit3:process(clk,rst)beginif(rst='1') thensum<="0000";c<='0';elsif(rising_edge(clk)) thensum(2 downto 0)<=reg3(2 downto 0);sum(3)<=reg3(3)xor reg3(4)xor reg3(5);c<=(reg3(3)and reg3(4))or(reg3(3)and reg3(5))or(reg3(4)and reg3(5));end if;end process bit3;end depict;library ieee;use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all;entity noadd isport(clk,rst : in std_logic;a,b : in std_logic_vector(3 downto 0);sum : out std_logic_vector(3 downto 0);c : out std_logic);end entity noadd;architecture depict of noadd issignal reg : std_logic_vector(4 downto 0);signal rega: std_logic_vector(4 downto 0);signal regb: std_logic_vector(4 downto 0);beginprocess(clk)beginif(rising_edge(clk))thenrega<='0'& a;regb<='0'& b;end if;end process;process(clk)beginif(rst='1')thenreg<="00000";elsif(rising_edge(clk))thenreg<=rega+regb;end if;end process;sum<=reg(3 downto 0);c<=reg(4);end depict;4位十进制数计数器library ieee;use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; entity dec_disp is port(clk_cnt : in std_logic;sel1 : out std_logic_vector(3 downto 0);sel2 : out std_logic_vector(3 downto 0);sel3 : out std_logic_vector(3 downto 0);sel4 : out std_logic_vector(3 downto 0));end dec_disp;architecture behav of dec_disp issignal data1 : std_logic_vector(3 downto 0); signal data2 : std_logic_vector(3 downto 0); signal data3 : std_logic_vector(3 downto 0); signal data4 : std_logic_vector(3 downto 0);begincount:process(clk_cnt)beginif(rising_edge(clk_cnt))thenif(data1="1001")thendata1<="0000";elseif(data2="1001")thendata2<="0000";data1<=data1+1;elseif(data3="1001")thendata3<="0000";data2<=data2+1;elseif(data4="1001")thendata4<="0000";data3<=data3+1;elsedata4<=data4+1;end if;end if;end if;end if;end if;end process count;sel1<=data1;sel2<=data2;sel3<=data3;sel4<=data4;end behav;正弦波发生器sin.mif文件depth=256;width=8;address_radix=dec; data_radix=dec; contentbegin0: 131;1: 134;2: 137;3: 141;4: 144;5: 147;6: 150;7: 153;8: 156;9: 159;10: 162;11: 165;12: 168; 13: 171;14: 174;15: 177;16: 180;17: 183;18: 186;19: 188;20: 191;21: 194;22: 196;23: 199;24: 202;25: 204;26: 207;27: 209;28: 212;29: 214;30: 216;31!219;32:221;33:223;34:225;35:227;36:229;37:231;38:233;39:234;40:236;41:238;42:239;43:241;44:242;45:244;46:245;47:246;48:247;49:249;50:250;51:250;52:251;53:252; 54:253; 55:254; 56:254; 57:255; 58:255; 59:255; 60:255; 61:255; 62:255; 63:255; 64:255; 65:255; 66:255; 67:255; 68:255; 69:255; 70:254; 71:254; 72:253; 73:252; 74:251; 75:250; 76:250; 77:249; 78:247; 79:246; 80:245; 81:244; 82:242; 83:241; 84:239; 85:238; 86:236; 87:234; 88:233; 89:231; 90:229; 91:227; 92:225; 93:223; 94:221; 95:219; 96:216;97:214;98:212;99:209;100:207;101:204;102:202;103:199;104:196;105:194;106:191;107:188;108:186;109:183;110:180;111:177;112:174;113:171;114:168;115:165;116:162;117:159;118:156;119:153;120:150;121:147;122:144;123:141;124:137;125:134;126:131;127:128;128:125;129:122;130:119;131:115;132:112;133:109;134:106;135:103;136:10;137:97;138:94;139:91;140:88;141:85;142:82;143:79;144:76;145:73;146:70;147:68;148:65;149:62;150:60;151:57;152:54;153:52;154:49;155:47;156:44;157:42;158:40;159:37;160:35;161:33;162:31;163:29;164:27;165:25;166:23;167:22;168:20;169:18;170:17;171:15;172:14;173:12;174:11;175:10;176:9;177:7;178:6;179:6;180:5;181:4;182:3;183:2;184:2;185:1; 186:1; 187:1; 188:0; 189:0; 190:0; 191:0; 192:0; 193:0; 194:0; 195:1; 196:1; 197:1; 198:2; 199:2; 200:3; 201:4; 202:5; 203:6; 204:6; 205:7; 206:9; 207:10; 208:11; 209:12; 210:14; 211:15; 212:17; 213:18; 214:20; 215:22; 216:23; 217:25; 218:27; 219:29; 220:31; 221:33; 222:35; 223:37; 224:40; 225:42; 226:44; 227:47; 228:49; 229:52; 230:54; 231:57; 232:60; 233:62; 234:65; 235:68; 236:70 ; 237:73; 238:76; 239:79; 240:82; 241:85; 242:88; 243:91; 244:94; 245:97; 246:100; 247:103; 248:106; 249:109; 250:112; 251:115; 252:119; 253:122; 254:125; 255:128; end;。

verilog 12位超前进位加法器讲解学习

v e r i l o g12位超前进位加法器12位流水线加法器的设计2016311030103 吴昊1.实验目的用verilog实现12位流水线加法器2.实验原理12位加法器是将3个4位加法器串行连接而形成的。

如果每个4位加法器都有100ns的吞吐延迟,那么该结构的最大延迟时间将是300ns。

在同步电路中,这种结构是为了使所有的操作都在同一时钟周期内进行。

本文采用另一种流水线结构可以通过把该处理过程分配到多个时钟周期上,以更高的吞吐速率进行操作。

速度和物理资源的折中保证了这种方法是可行的。

这种流水线结构包含一个数据输入寄存器IR,输出寄存器OR 和之间的传播寄存器PR1和PR2.这种结构对数据进行序列化,因此在一个给定的时钟周期内,进位只能在1/3个数据路径中传播。

输入数据通路接口以同步方式给运算单元提供完整的输入字,但是此时仅仅形成了低4位数据字节的和。

然后将那个“和”与其左面的数据一起存入20位内部寄存器PR1中。

在下一个时钟周期内,形成中4位数据字节的和,并且将其与低4位字节和,这一周期的进位一起存入PR2中。

在第三个时钟周期内,形成高4位数据字节的和,并将低、中4位数据字节的和输出进位一并存入12位输出寄存器OR。

利用这种内部寄存器,该流水线单元可以近似工作在原价发起频率的三倍平频率上。

在最初的延迟周期后,每隔100ns就会在单元的输出端出现一个新的和。

12位加法器流水线结构:3.Verilog代码源代码:module add12(a,b,c_in,c_out,sum,clock);input [11:0] a,b;input c_in,clock;output [11:0] sum;output c_out;reg [24:0] IR;reg [20:0] PR1;reg [16:0] PR2;reg [12:0] OR;wire [3:0] A,C,E;wire B,D,F;assign{c_out,sum}=OR;add4 wh1(A,B,IR[4:1],IR[8:5],IR[0]);add4 wh2(C,D,PR1[8:5],PR1[12:9],PR1[4]); add4 wh3(E,F,PR2[12:9],PR2[16:13],PR2[8]); always@(posedge clock)beginIR[0]<=c_in;IR[4:1]<=a[3:0];IR[8:5]<=b[3:0];IR[12:9]<=a[7:4];IR[16:13]<=b[7:4];IR[20:17]<=a[11:8];IR[24:21]<=b[11:8];PR1[3:0]<=A;PR1[4]<=B;PR1[8:5]<=IR[12:9];PR1[12:9]<=IR[16:13];PR1[16:13]<=IR[20:17];PR1[20:17]<=IR[24:21];PR2[7:4]<=C;PR2[8]<=D;PR2[3:0]<=PR1[3:0];PR2[12:9]<=PR1[16:13];PR2[16:13]<=PR1[20:17];OR[11:8]<=E;OR[12]<=F;OR[7:0]<=PR2[7:0];endEndmodule4位超前进位加法器模块:module add4(sum,c_out,a,b,c_in);output [3:0] sum;output c_out;input [3:0] a;input [3:0] b;input c_in;wire [3:0] g=a&b;wire [3:0] p=a^b;wire c1,c2,c3,c4;assignc1=(p[0]&c_in)|g[0],c2=(p[1]&p[0]&c_in)|(p[1]&g[0])|g[1],c3=g[2]|(p[2]&g[1])|(p[2]&p[1]&g[0])|(p[3]&p[2]&p[1]&p[0]&c_in),c4=g[3]|(p[3]&g[2])|(p[3]&p[2]&g[1])|(p[3]&p[2]&p[1]&g[0])|(p[3]&p[2]&p[1]&p[ 0]&c_in);assignsum[0]=p[0]^c_in,sum[1]=p[1]^c1,sum[2]=p[2]^c2,sum[3]=p[3]^c3;assignc_out=c4;endmodule测试代码:module add12_test;reg [11:0] a,b;reg c_in,clock;wire c_out;wire [11:0] sum;add12 k(a,b,c_in,c_out,sum,clock);initialbeginclock=0;a=12'h123;b=12'h321;c_in=0;#100 a=12'h111;b=12'h222;#100 a=12'h189;b=12'h739;#100 a=12'h458;b=12'hc52;endalwaysbegin#50 clock=~clock;endendmodule4.实验数据仿真图:由仿真图可知,加法器输出结果正确,并在三个时钟周期后,每一个时钟周期输出一个新的和,成功加快了三倍频率。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基于verilog HDL的八位超前进位加法器
Verilog 综合作业陈孙文
2011-10-25
指导老师:邓婉玲老师目录:
1. 超前进位加法器原理
2. 算法代码
3. modelsim SE软件实现功能仿真
4. synplify pro软件实现综合
正文:
一、原理
(1)、全加器
列出真值表如表所示,若Ai、Bi两个一位二进制数相加,以Ci表示来自低位的的进位,Si表示和,Ci表示向高位的进位,可以看出该电路考虑来低位的进位,是一个一位数的全加器电路,其逻辑符号如图所示。

串并行超前进位加法器的特点是:各级进位信号同时产生,减小或消除因进位信号逐级传递所用的时间。

每一位的进位信号不依赖于从低位逐级传递,而是—开始就能确定。

全加器真值可以得到逻辑表达式:
为表达简单,定义两个中间变量Gi和Pi
得出
得到各位进位信号的逻辑表达式为:
当实际位数较多时,往往将全部数位按4位一组分成若干组,组内采用超前进位,组间采用串行进价,组成所谓的串并行进位加法器。

二、算法代码:有4bits.v、8bits.v、testbench.v三个文件;
4bits.v实现输入为4位数的加法器;8bits.v中调用4bits.v中的函数来实现8位数相加;testbench.v 为测试代码;
实现四位加法4bits.v部分:
module fast_adder4b(ina,inb,carry_in,sum_out,clk,rst_n);
parameter ADDER_WIDTH=4;
parameter SUM_WIDTH=5;
input [ADDER_WIDTH-1:0]ina; //输入数ina,8位
input [ADDER_WIDTH-1:0]inb; //输入数inb,8位
input carry_in;
input rst_n;
input clk;
output [SUM_WIDTH-1:0] sum_out;
reg [SUM_WIDTH-1:0] sum_out;
wire [ADDER_WIDTH-1:0]sg;
wire [ADDER_WIDTH-1:0]sp;
wire [ADDER_WIDTH-1:0]sc;
assign sg[0]=ina[0]&inb[0]; //中间变量G0=ina0&inb0;
assign sg[1]=ina[1]&inb[1];
assign sg[2]=ina[2]&inb[2];
assign sg[3]=ina[3]&inb[3];
assign sp[0]=ina[0]^inb[0]; //中间变量P0=ina0^inb0;
assign sp[1]=ina[1]^inb[1];
assign sp[2]=ina[2]^inb[2];
assign sp[3]=ina[3]^inb[3];
assign sc[0]=sg[0]|(sp[0]&carry_in); //进位位C0
assign sc[1]=sg[1]|(sp[1]&(sg[0]|(sp[0]&carry_in)));
assign sc[2]=sg[2]|(sp[2]&(sg[1]|(sp[1]&(sg[0]|(sp[0]&carry_in)))));
assign sc[3]=sg[3]|(sp[3]&(sg[2]|(sp[2]&(sg[1]|(sp[1]&(sg[0]|(sp[0]&carry_in)))))));
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
sum_out<=5'b00000;
else
begin
sum_out[0]<=sp[0]^carry_in; //输出结果位
sum_out[1]<=sp[1]^sc[0];
sum_out[2]<=sp[2]^sc[1];
sum_out[3]<=sp[3]^sc[2];
sum_out[4]<=sc[3];
end
end
endmodule
实现八位加法8bits.v部分:
module pipe_adder8b(ina,inb,sum_out,clk,rst_n);
parameter ADDER_WIDTH=8;
parameter SUM_WIDTH=9;
parameter HALF_ADDER_WIDTH=4;
input [ADDER_WIDTH-1:0]ina;
input [ADDER_WIDTH-1:0]inb;
input rst_n;
input clk;
output[SUM_WIDTH-1:0] sum_out;
reg [SUM_WIDTH-1:0] sum_out;
reg [HALF_ADDER_WIDTH-1:0] ina_lsb;
reg [HALF_ADDER_WIDTH-1:0] ina_msb;
reg [HALF_ADDER_WIDTH-1:0] inb_lsb;
reg [HALF_ADDER_WIDTH-1:0] inb_msb;
reg [HALF_ADDER_WIDTH-1:0] ina_msb1;
reg [HALF_ADDER_WIDTH-1:0] inb_msb1;
reg [HALF_ADDER_WIDTH:0] sum11;
wire[HALF_ADDER_WIDTH:0] sum1;
wire[HALF_ADDER_WIDTH:0] sum2;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
ina_lsb<=4'b0000;
ina_msb<=4'b0000;
inb_lsb<=4'b0000;
inb_msb<=4'b0000;
end
else
begin
ina_lsb<=ina[3:0];
ina_msb<=ina[7:4];
inb_lsb<=inb[3:0];
inb_msb<=inb[7:4];
end
end
fast_adder4b u1(ina_lsb,inb_lsb,1'b0,sum1,clk,rst_n); //低四位调用4位加法器模块
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
ina_msb1<=4'b0000;
inb_msb1<=4'b0000;
end
else
begin
ina_msb1<=ina_msb;
inb_msb1<=inb_msb;
end
end
fast_adder4b u2(ina_msb1,inb_msb1,sum1[4],sum2,clk,rst_n); //高四位调用4位加法器模块always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
sum11<=4'b0000;
else
sum11<=sum1;
end
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
sum_out<=9'b0000_00000;
else
sum_out<={sum2,sum11[3:0]};
end
endmodule
testbengch.v部分:
`timescale 1ns/1ns
module test_8a;
reg clk,rst_n;
reg [7:0]ina,inb;
wire [8:0]sum_out;
always #20 clk=~clk; //时钟信号40ns一个周期
initial
begin
rst_n=1;
clk=0;
#30
ina=43; //给a赋值43
inb=61;
#200 rst_n=0;
#40 rst_n=1;
#2000 $stop;
end
//fast_adder4b bbb(.ina(ina),.inb(inb),.carry_in(1'b0),.sum_out(sum_out),.clk(clk),.rst_n(rst_n));
pipe_adder8b te(.ina(ina),.inb(inb),.sum_out(sum_out),.clk(clk),.rst_n(rst_n));
endmodule
三、modelsim软件实现功能仿真
三个代码文件compile通过之后,执行simulation;添加待观察端口到波形图wave中,执行simulation->run all命令,在wave波形图中得到以下的仿真波形:
四、synplify pro软件综合。

相关文档
最新文档