VHDL编码题

目录

半加器和全加器

半加器

全加器

八位加法器设计

BCD码加法器设计

乘法器

for语句

repeat语句

while语句

 移位寄存器

同步预制功能

使用移位操作符 

计时器

同步加载计数器

异步加载计数器

异步清0加载计数器

同步清0加载计数器

分频器

偶数分频

奇数分频 

任务和函数

任务(task)

函数(function)


半加器和全加器

半加器

module h_adder (A,B,so,co);
input A,B;
output so,co;
assign so = A ^ B;//与逻辑
assign co = A & B;//异逻辑 同0异1
endmodule

全加器

顶层设计(根据图像来进行例化)
module f_adder (ain,bin,cin,cout,sum);
output cout,sun; input ain,bin,cin
wire netl,net2,net3;
h_adder U1 (ain, bin, net1, net2);  //位置关联法
h_adder U2( .A (net1)),.so(sum),.B(cin),.co(net3)); //端口名关联法
     or U3 (cout,net2, net3) ;   //位置关联法,建议使用端口名关联法,有的元件不能直观看出来位置
endnodule

半加器模块
module h_adder (A,B,so,co);
input A,B;
output so,co;
assign so = A ^ B;//与逻辑
assign co = A & B;//异逻辑 同0异1
endmodule

八位加法器设计

1
module
ADDER8B(A,B,CIN,COUT,DOUT);
output [7:0] DOUT;output COUT;
input [7:0] A,B; input CIN;
wire [8:0]DATA;//加操作的进位自动进入DATA[8]
assign DATA = A + B + CIN;
assign COUT = DATA[8] ;
assign DOUT = DATR [7:0] ;
endmodule


2
module
ADDERBB (A,B,CIN,COUT,DOUT);
output [7:0] DOUT; output COUT;
input [7:0] A,B;input CIN;
//加操作的进位进入并位COUT
assign {COUT,DOUT} = A + B +CIN;
endmodule

BCD码加法器设计

module BCD_ADDER(A,B,D);
 input [7:0] A,B; output [8:0]D;
 wire [4:0] DT0,DT1; reg [8:0] D; reg s;
always@(DTO)
 begin if (DT0[4:0] >= 5'b01010)
//如果低位ECD码的和大于等于10,则使和加上6,且有进位,使进位标志s等于1。
   begin D[3:0]=(DT0[3∶0]+4'b0110); s=1'bl; end
   else begin D[3:0] =DTO0[3:0] ; s=1'b0; end
end //否则,将低位值赋予低位BCD码D[3;0]输出,无进位,使进位标志S等于0。
always@(DT1) begin
 if (DT1[4;0]>=5'b01010)
 begin D[7;4] =(DT1[3;0]+4'b0110) ; D[8]=1'bl; end
  else begin D[7:4] = DT1[3:0] ; D [8]=1'b0;end  end
assign DT0 = A[3:0] + B[3:0] ;//设没有来自低位的进位。
assign DTl = A[7:4] + B[7:4] + s; //s是来自低位ECD码相加的进位。
endmodule

乘法器

for语句

1
module MULT4B(R,A,B) ;
parameter s=4; //乘法器的位数
output[2*s:1]R;
input[s:1]A,B;
reg [2*s :1]R;
integer i;
 always (A or B)
 begin
 R=0;
 for (i=1; i<=s; i=i+1)
 if(B[i])R=R+(A<<(i-1));  //以B为参考,B不为0的位数让A左移一位进行累加
 end
endmodule


2
module MIULT4B (R,A,B);
parameter s=4;
output[2*s∶1]R;
input [s:1] A,B ;
reg [2*S:1] R,AT; reg [s :1]BT,CT;
always @(A,B ) begin
 R=0; AT ={{S { 1'B0}},A};
 BT= B;CT = s ;
 for (CT=s ; CT>0; CT=CT- 1)
  begin if(BT[1])R=R+AT;
  AT=AT<<1;
  BT=BT>>1;              //以B的第一位为参考,不为0则A进行累加,结束后A往左移,B往右移
end end endmodule 

repeat语句

module MULT4B(R,A,B);
parameter s=4;
output [2*s:1] R; input [s : 1] A, B ;
reg [2*s : 1]TA,R;
reg [s:1]TB;
 always @(A or B)begin
 R = 0 ; TA = A ;TB = B ;
 repeat (s) begin            //repeat语句中直接给出循坏的次数
  if(TB[1]) begin R=R+TA; end
  TA =TA<<1;
  TB =TB>>1;
  end
 end
endmodule

while语句

module MULT4B(AB,R);
parameter s=4;
input [s:1]A,B;
output [2*s:1]R;
reg [2*S:1] R,AT;
reg [s:1] BT,CT;
always@(A or B) begin
  R=O; AT={{s{1'b0}},A};   //AT=0000A;意思就是将AT的高s位清0
  BT=B;CT=s;
   while (CT>0) begin
     if(BT[1])R=R+AT; else R=R;
begin cT= CT-1;AT=AT<<1;BT=BT>>1;
end  end  end
endmodule

移位寄存器

同步预制功能

module SHIFT1(CLK,LOAD,DIN,QB);
 output QB; input CLK,LOAD; input[7:0] DIN; reg[7:0] REG8;
 always @(posedge CLK)  //同步预制
  if (LOAD) REG8<=DIN; else RGE8[6:0]<=RGE8[7:1];  //左移一位
 assign QB = RGE8[0];
endmodule

使用移位操作符 

module SHIFT4(DIN,CLK,RST,DOUT);
 output DOUT; input CLK,DIN,RST;  reg[3:0] SHFT;
 always @(posedge CLK or posedge RST)
  if (RST) SHFT<=4'B0; 
   else begin SHFT<=(SHFT>>1); SHFT[3]<=DIN; end
 assign DOUT = SHFT[0];
endmodule

计时器

同步加载计数器

module EDIV0 (input CLK,RST,input[3:0]D,output PM,output[3:0]DOUT);
reg [3:0] Q1; reg FULL;
 always @ (posedge CLK or negedge RST)
  if (!RST) begin Ql<=0 ; FULL<=0; end
  else if (LD) begin Q1<=D ; FULL<=1; end
  else begin Q1 <= Q1+l;FULL<=0 ; end
assign LD=(Q1==4'B1111); assign PM=FULI; assign DOUT=Q1;
endmodule

异步加载计数器

module fdiv1 (CLK,PM,D,DOUT,RST );
 input CLK; input RST; input[3:0] D; output PM; output[3:0] DOUT;
 reg [3:0] Q1;reg FULL;
  always @(posedge CLR or posedge LD or negedge RST )
   if(!RST)begin Q1<=0 ;   FULL<=0;  end
else if(LD)begin Q1<=D ;   FULL<=1;  end
     else begin  Q1<=Q1+1; FULL<=0; end
  assign LD=(Q1==4'B0000);//比同步多1
  assign PM=FULL;
  assign DOUT=Q1 ;
endmodule

异步清0加载计数器

module fdivl (CLK,PM, D ) ;
input CLR; input [3;0] D; output PM ; reg FULL ;
reg[3:0] Q1;
wire RST ;
always @(posedge CLK or posedge RST)
 if(RST) begin Ql<=0; FULL<=l; end
 else begin Q1<=Q1+l; FULL<=0; end
assign RST = (Q1==D);
assign PM  = FULL ;
endmodule

同步清0加载计数器

将异步清0加载计数器中的always语句改成下面的语句即可

always @ (posedge CLK)

分频器

偶数分频

对于N(N为偶数)分频,只需计数到N/2-1,然后时钟翻转、计数清零,如此循环就可以得到N(偶)分频。

module div_6(clk_out,clk,rst_n);
output clk_out;
input clk;  input rst_n;
reg [1:0] cnt;
reg clk_out;
parameter N=10;
   
always @ (posedge clk or negedge rst_n)begin
     if(rst_n==1'b0)
	      begin
            cnt <= 0;
            clk_out<= 0;
          end
     else  if(cnt==N/2-1)            
        begin 
			   clk_out<=~clk_out; 
				cnt<=0; 
	    end
     else
               cnt <= cnt + 1'b1;    
 end

奇数分频 

 实现奇数(N)分频,分别用上升沿计数到(N-1)/2,再计数到N-1;用下降沿计数到(N-1)/2,再计数到N-1,得到两个波形,然后把它们相或即可得到N分频。

module div_3 (q,clk,rst_n);
output q;
input rst_n;
input clk;
reg q1,q2;                
reg [1:0] count1,count2;
 
always@(posedge clk or negedge rst_n)begin   //q1计数上升沿
    if(rst_n==1'b0)
        begin
        q1<=1'b0;
        count1<=2'b00;
        end
    else if(count1==0)    
        begin
        q1<=~q1;
        count1<=count1+1'b1;
        end
    else if(count1==1'b1)
        begin
        q1=~q1;
        count1<=count1+1'b1;
        end
    else 
        count1<=2'b00;
 end
  
 always@(negedge clk or negedge rst_n)begin    //q2计数下降沿
     if(rst_n==1'b0)
         begin
         q2<=1'b0;
         count2<=2'b00;
         end
     else if(count2==0)    
         begin
         q2<=~q2;
         count2<=count2+1'b1;
         end
     else if(count2==1'b1)
         begin
         q2=~q2;
         count2<=count2+1'b1;
         end
     else 
         count2<=2'b00;
end
assign q=q1|q2;     

任务和函数

任务(task)

module TASKDEMO (S, D, C1,D1,C2,D2); l/主程序模块及端口定义
input s;input [3∶0]c1,D1,c2, D2;
output [3:0]D;//端口定义数目不受限制。
reg [ 3:0] out1 , out2;
task CMP ;
//任务定义,任务名CMP,此行不能出现端口定义语句
input [3: 0] A,B;output [3:0]DOUT ;//注意任务端口名的排序
begin if(A>B)DOUT= A;//任务过程语句描述一个比较电路
else DOUT=B; end//在任务结构中可以调用其他任务或函数,甚至自身。
endtask//任务定义结束
always @(*) begin//主程序过程开始
CMP (C1,D1,out1 );//调用一次任务。任务调用语句只能出现在过程结构中
CMP (C2,D2,out2) ;end//第二次调用任务
assign D=s ? out1:out2 ;
endmodule

函数(function)

module CN (input [3:0] A,output [2:0] OUT);
function [2:0] GP;//定义一个函数名为GP 的函数,GP同时作为位宽为3的输出参数
input [3:0] M;//M定义为此函数的输入值,位宽是4
reg [2:o] CNT,N ;
begin CNT=0; for (N=0; N<=3; N=N+1)//for循环语句
if(M[N]==1)CNT=CNT+1;GP=CNT;end//含1的位个数累加
endfunction
assign oUT=(~|A)? 0:GP(A);//主程序输入A或非缩位,若为1则输出函数计数结果
endmodule

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值