【Verilog】Verilog的八个经典入门例题

Verilog的八个经典入门例题


前言

西安电子科技大学大三上学期硬件描述语言与可编程逻辑设计上机作业,本文作者采用vivado软件编译,Vivado自带的Simulation工具仿真,效果完全等同于Quartus编译+Modelsim仿真的组合


提示:以下是本篇文章正文内容,提供的程序仅供参考

一、7人表决器设计

题目内容:设计一个表决器,实现功能大于3人同意,表决通过,输出“1’b1”,否则输出“1’b0”。

源程序(示例):

module vote_7in(
input a,b,c,d,e,f,g,
output out
    );
assign out = (a+b+c+d+e+f+g >3)?1:0;
endmodule

测试程序(示例):

`timescale 1ns / 1ns
module vote_7in_tb;
reg a,b,c,d,e,f,g;
wire out;

vote_7in U1(.a(a),.b(b),.c(c),.d(d),.e(e),.f(f),.g(g),.out(out));

initial 
begin
	{a,b,c,d,e,f,g} = 7'b0;
	#5 a = 1'b1;
	#5 b = 1'b1;
	#5 c = 1'b1;
	#5 d = 1'b1;
	#5 e = 1'b1;
	#5 f = 1'b1;
	#5 g = 1'b1;

end
endmodule

仿真波形截图(示例):
【Verilog】Verilog的八个经典入门例题

二、8位的ALU设计

题目内容: 设计一个8位的ALU(算术逻辑单元),该单元具有两个输入数据a,b和一个输入操作符Oper及输出数据c_out, sum,并且还具有下表所示的功能。

操作符功能
Adda+b
Subtracta-b
Subtract_ab-a
Ora | b
Anda&b
Xora^b
Xnora~^b

源程序(示例):

/*仅考虑无符号情况*/
module alu_8bit(
input[7:0] a,b,
input[2:0]Oper,
output reg c_out,
output reg[7:0] sum
    );
	
always@(a or b or Oper)
begin
	case(Oper)
	3'b000:  {c_out,sum} = a + b;
	3'b001:  {c_out,sum} = a - b;
	3'b010:  {c_out,sum} = b - a;
	3'b011:  {c_out,sum} = a | b;
	3'b100:  {c_out,sum} = a & b;
	3'b101:  {c_out,sum} = a ^ b;
	3'b110:  {c_out,sum} = a ~^ b;
	default: {c_out,sum} = 9'bx;
	endcase
end
endmodule

测试程序(示例):

`timescale 1ns / 1ns
module alu_8bit_tb;
	reg[7:0] a,b;
	reg[2:0] Oper;
	wire c_out;
	wire[7:0] sum;
	
	alu_8bit u1(.a(a),.b(b),.Oper(Oper),.c_out(c_out),.sum(sum));
	
	initial
	begin
	a = 8'b01110000; b = 4'b11110011; Oper = 3'b0;
		#5 Oper = 3'b000;
		#5 Oper = 3'b001;
		#5 Oper = 3'b010;
		#5 Oper = 3'b011;
		#5 Oper = 3'b100;
		#5 Oper = 3'b101;
		#5 Oper = 3'b110;
		#5 Oper = 3'b111;
	end
endmodule

仿真波形截图(示例):
【Verilog】Verilog的八个经典入门例题

三、JK触发器的设计

题目内容: 编写Verilog代码使之能正确描述下表所示的1bit JK触发器功能,其中Q+表示在时钟上升沿到来后的Q值。要求该触发器还具有异步复位的功能。

JKQ+
00Q
101
010
11~Q

源程序(示例):

module jk_ff(j,k,q,clk,rst);
input j,k,clk,rst;
output reg q;
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		q = 0;
	else
		case({j,k})
		2'b00:q = q;
		2'b10:q = 1;
		2'b01:q = 0;
		2'b11:q = ~q;
		endcase
end
endmodule

测试程序(示例):

`timescale 1ns/1ns
module jk_ff_tb;
reg j,k,clk,rst;
wire q;
jk_ff u1(.j(j),.k(k),.clk(clk),.rst(rst),.q(q));
always #5 clk = ~clk;
initial
begin
	rst = 0; clk = 0; j = 1; k = 0;
	#10 j=0;k=0;
	#10 j=1;k=0;
	#10 j=0;k=1;
	#10 j=1;k=1;
	#15	rst = 1;
	#10 j=0;k=0;
	#10 j=1;k=0;
	#10 j=0;k=1;
	#10 j=1;k=1;
end
endmodule

仿真波形截图(示例):
【Verilog】Verilog的八个经典入门例题

四、环形计数器

题目内容: 设计下图所示寄存顺序的环形计数器,异步复位,复位时计数器中的值为4’b0001。
要求:(1)用参数定义此计数器的位宽;
            (2)仿真测试对象为8bit的环形计数器;

0001
0010
0100
1000
0100
0010
0001

源程序(示例):

module ring_count(reset, clk, count);
parameter width = 4;
input reset, clk;
output reg[width - 1:0] count;
integer I;
always@(posedge clk or posedge reset)
begin
	if(reset == 1'b1)
		begin
		count <= 4'b0001;
		I <= 0;
		end
	else
	begin
		if(I<width - 1)
			begin
			count <= {count[2:0],count[width - 1]};
			I <= I + 1;
			end
		else if(I<5&&I>=width - 1)
			begin
			count <= {count[0],count[width - 1:1]};
			I <= I + 1;
			end
		else
			begin
				count <= {count[0],count[width - 1:1]};
				I <= 0;
			end
	end
end
endmodule

测试程序(示例):

`timescale 1ns/1ns
module ring_count_tb;
reg clk,reset;
wire [7:0] count;

ring_count u1(.reset(reset),.clk(clk),.count(count));

always #5 clk = ~clk;

initial
begin
clk <= 1'b0;
reset <= 1'b1;
#15 reset = 1'b0;
#100 reset = 1'b1;
end
endmodule

仿真波形截图(示例):

【Verilog】Verilog的八个经典入门例题

五、二进制整数除法器设计

要求:(1)分析除法器工作原理,不能使用整除运算符/ 和求余运算符% ;
            (2)设被除数位数=8,除数位数=4
            (3)输出商和余数

源程序(示例):

/*二进制无符号整数除法*/
module divider_2bit(a,b,c,d);
input [7:0]a;//a为被除数
input [3:0]b;//b为除数
output reg[7:0]c;//c为商
output reg[3:0]d;//d为余数

reg[15:0] temp_a=0;
reg[7:0] temp_c=0;

integer I;

always@(a or b)
begin
	temp_a = a;
	for(I=0;I<9;I=I+1)//效果等同于repeat(9),只有循环次数确定的for、while、repeat语句才可综合,否则不可综合
	begin
		temp_c = temp_c<<1;//移位运算符的结果是一串数,并不能改变移位对象的值
		if(temp_a[15:8]>=b)
		begin
			temp_c = temp_c + 1'b1;
			temp_a[15:8] = temp_a[15:8] - b;
			temp_a = temp_a<<1;//效果等同于temp_a = {temp_a[14:0],1'b0};切记使用位拼接运算符要注明位宽
		end
		else
			temp_a = temp_a<<1;//不可写作temp_a = {temp_a[14:0],0};因为0没有注明位宽
	end
	c <= temp_c;
	d <= temp_a[12:9];
end

endmodule

测试程序(示例):

`timescale 1ns / 1ns
module divider_2bit_tb;
reg[7:0] a;
reg[3:0] b;
wire[7:0]c;
wire[3:0]d;

divider_2bit u1(.a(a),.b(b),.c(c),.d(d));

initial
begin
a = 8'b0001_1011;
b = 4'b0101;
#100
a = 8'b1001_1011;
b = 4'b0001;
#100
a = 8'b0000_0011;
b = 4'b1101;
#100
a = 8'd250;
b = 4'd15;
#100
a = 8'd6;
b = 4'd3;
#100
a = 8'd97;
b = 4'd13;
end
endmodule

仿真波形截图(示例):

【Verilog】Verilog的八个经典入门例题

六、排序任务

设a,b,c,d四个数,按从小到大的顺序重新排列并输出到ra,rb,rc,rd中。
要求:(1)需在Verilog HDL描述中使用任务(task)。

源程序(示例):

module sort_task(a,b,c,d,ra,rb,rc,rd);
parameter width = 4;
input [width-1:0] a,b,c,d;
output reg[width-1:0] ra,rb,rc,rd;

always@(a or b or c or d)
begin
	sort(a,b,c,d,ra,rb,rc,rd);
end

task sort;
input [width-1:0] a,b,c,d;
output reg[width-1:0] ra,rb,rc,rd;
reg [width-1:0]temp;
integer i,j;
reg [width-1:0]data[3:0];

begin
data[0] = a;
data[1] = b;
data[2] = c;
data[3] = d;

for(i=0;i<3;i=i+1)
	begin
	for(j=0;j<3-i;j=j+1)
		begin
		if(data[j]>data[j+1])
			begin
			temp = data[j+1];
			data[j+1] = data[j];
			data[j] = temp;
			end
		end
	end

ra = data[0];
rb = data[1];
rc = data[2];
rd = data[3];
end

endtask

endmodule

测试程序(示例):

`timescale 1ns / 1ns
module sort_task_tb;
parameter width = 4;
reg[width-1:0] a,b,c,d;
wire[width-1:0] ra,rb,rc,rd;

sort_task u1(.a(a),.b(b),.c(c),.d(d),.ra(ra),.rb(rb),.rc(rc),.rd(rd));

initial
begin
a <= 4'd4;
b <= 4'd3;
c <= 4'd2;
d <= 4'd1;
#500
a <= 4'd0;
b <= 4'd7;
c <= 4'd3;
d <= 4'd5;
end
endmodule

仿真波形截图(示例):
【Verilog】Verilog的八个经典入门例题

七、简易频率计

设计一个8 位数字显示的简易频率计
要求:
①能够测试10Hz~10MHz 方波信号;
②电路输入的基准时钟为1Hz,要求测量值以8421BCD 码形式输出;
③系统有复位键;
④采用分层次分模块的方法;

源程序(示例):

module freq_cnt(clk_1Hz, fin, rst, d0, d1, d2, d3, d4, d5, d6, d7);  
  input clk_1Hz;
  input fin; 
  input rst;
  
  output[3:0] d0, d1, d2, d3, d4, d5, d6, d7; 
  wire[3:0] q0, q1, q2, q3, q4, q5, q6, q7;  
  //wire[3:0] d0, d1, d2, d3, d4, d5, d6, d7;  
  wire[3:0] en_out0,en_out1,en_out2,en_out3,en_out4,en_out5,en_out6,en_out7;
  wire count_en;  
  wire latch_en;  
  wire clear;
  
  

  control u_control(.clk_1Hz(clk_1Hz), .rst(rst), .count_en(count_en),  
                    .latch_en(latch_en), .clear(clear));  
    

  counter_10 counter0(.en_in(count_en), .clear(clear), .rst(rst),  
                      .fin(fin), .en_out(en_out0), .q(q0));  
  counter_10 counter1(.en_in(en_out0), .clear(clear), .rst(rst),  
                      .fin(fin), .en_out(en_out1), .q(q1));  
  counter_10 counter2(.en_in(en_out1), .clear(clear), .rst(rst),  
                      .fin(fin), .en_out(en_out2), .q(q2));  
  counter_10 counter3(.en_in(en_out2), .clear(clear), .rst(rst),  
                      .fin(fin), .en_out(en_out3), .q(q3));  
  counter_10 counter4(.en_in(en_out3), .clear(clear), .rst(rst),  
                      .fin(fin), .en_out(en_out4), .q(q4));  
  counter_10 counter5(.en_in(en_out4), .clear(clear), .rst(rst),  
                      .fin(fin), .en_out(en_out5), .q(q5));  
  counter_10 counter6(.en_in(en_out5), .clear(clear), .rst(rst),  
                      .fin(fin), .en_out(en_out6), .q(q6));  
  counter_10 counter7(.en_in(en_out6), .clear(clear), .rst(rst),  
                      .fin(fin), .en_out(en_out7), .q(q7));  
 
  ulatch u_latch(.clk_1Hz(clk_1Hz),.rst(rst),.latch_en(latch_en),
					.q0(q0),.q1(q1),.q2(q2),.q3(q3),.q4(q4),.q5(q5),.q6(q6),.q7(q7),
					.d0(d0),.d1(d1),.d2(d2),.d3(d3),.d4(d4),.d5(d5),.d6(d6),.d7(d7));
endmodule  
  

module control(clk_1Hz, rst, count_en, latch_en, clear);  
  input clk_1Hz;  
  input rst;  
  output count_en;  
  output latch_en;  
  output clear;  
  reg[1:0] state; 
  reg count_en;  
  reg latch_en;  
  reg clear;  
  always @(posedge clk_1Hz or negedge rst)  
  if(!rst)   
    begin    
      state <= 2'd0;  
      count_en <= 1'b0;  
      latch_en <=1'b0;  
      clear <= 1'b0;  
    end  
     else   
    begin  
      case(state)  
            2'd0:   
            begin 
            count_en <= 1'b1; 
            latch_en <=1'b0;  
            clear <= 1'b0;  
            state <= 2'd1;  
          end  
        2'd1:  
          begin   
            count_en <= 1'b0;  
            latch_en <=1'b1;  
            clear <= 1'b0;  
            state <= 2'd2;  
          end  
        2'd2:   
          begin 
            count_en <= 1'b0;  
            latch_en <=1'b0;  
            clear <= 1'b1;  
            state <= 2'd0;
          end  
        default:  
          begin  
            count_en <= 1'b0;  
            latch_en <=1'b0;  
            clear <= 1'b0;  
            state <= 2'd0;  
          end  
            
      endcase  
            
    end  
    
    
endmodule  
  

module counter_10(en_in, rst, clear, fin, en_out, q);  
  input en_in;  
  input rst;   
  input clear; 
  input fin;    
  output en_out; 
  output[3:0] q;  
    
  reg en_out;  
  reg[3:0] q;  
    
  always@ (posedge fin or negedge rst)  
  if(!rst) 
      begin  
        en_out <= 1'b0;  
        q <= 4'b0;  
      end  
        
    else if(en_in) 
      begin  
        if(q == 4'b1001)   
          begin  
            q <= 4'b0;  
            en_out <= 1'b1;  
          end  
             else   
          begin  
            q <= q + 1'b1;  
            en_out <=1'b0;  
          end  
      end  
        
    else if(clear) 
      begin  
        q <= 4'b0;  
        en_out <= 1'b0;  
      end  
    else  
    begin  
    q <= q;  
    en_out <=1'b0;  
    end   
    
endmodule  
   
module ulatch(clk_1Hz, latch_en, rst, q0, q1, q2, q3, q4, q5, q6, q7,  
            d0, d1, d2, d3, d4, d5, d6, d7);  
              
  input clk_1Hz, latch_en, rst;  
  input[3:0] q0, q1, q2, q3, q4, q5, q6, q7;  
  output[3:0] d0, d1, d2, d3, d4, d5, d6, d7;  
  reg[3:0] d0, d1, d2, d3, d4, d5, d6, d7;  
  always@ (posedge clk_1Hz or negedge rst)  
  if(!rst) 
    begin  
      d0 <= 4'b0; d1 <= 4'b0; d2 <= 4'b0; d3 <= 4'b0; d4 <= 4'b0;  
      d5 <= 4'b0; d6 <= 4'b0; d7 <= 4'b0;  
    end  
  else if(latch_en) 
    begin  
      d0 <= q0; d1 <= q1; d2 <= q2; d3 <= q3; d4 <= q4;  
      d5 <= q5; d6 <= q6; d7 <= q7;  
    end  
     else  
    begin  
      d0 <= d0; d1 <= d1; d2 <= d2; d3 <= d3; d4 <= d4;  
      d5 <= d5; d6 <= d6; d7 <= d7;  
    end  
  
endmodule


测试程序(示例):

`timescale 1ns/1ps  
//测试模块  
module freq_cnt_tb;  
  parameter CLK_1HZ_DELAY = 5_0000_0000; //1Hz基准信号  
  parameter FIN_DELAY = 100;             //5MHz待测信号  
  reg clk_1Hz;  
  reg fin;  
  reg rst;  
    
  wire[3:0] d0, d1, d2, d3, d4, d5, d6, d7;  
    
  initial  
    begin  
      rst =1'b0;  
      #1 rst = 1'b1;  
    end  
      
  initial  
    begin  
      fin = 1'b0;  
      forever  
      #FIN_DELAY fin = ~fin;  
    end  
      
  initial  
    begin  
      clk_1Hz = 1'b0;  
      forever  
      #CLK_1HZ_DELAY clk_1Hz = ~clk_1Hz;  
    end  
      
    freq_cnt freDetect1(.clk_1Hz(clk_1Hz), .rst(rst), .fin(fin),  
    .d0(d0), .d1(d1), .d2(d2), .d3(d3), .d4(d4), .d5(d5), .d6(d6), .d7(d7));  
      
     
endmodule  

仿真波形截图(示例):

【Verilog】Verilog的八个经典入门例题

八、序列检测器

要求:
(1)在每一个时钟下降沿检查输入数据,当输入数“10011”时,输出asm被置为1;其余情况asm为0。
(2)画出fsm(有限状态机);

源程序(示例):

module seq_detector(clk,ain,asm);
input clk,ain;
output reg asm;
reg[4:0] q;
q = 5'b00000;
always@(negedge clk) q <= {q[3:0],ain};

always@(negedge clk) 
	if(q == 5'b10011) asm = 1;
	else			  asm = 0;
endmodule

测试程序(示例):

`timescale 1ns/1ps
module seq_detector_tb;
wire asm,ain;
reg clk;
reg[19:0] arr;
seq_detector U0(.clk(clk),.ain(ain),.asm(asm));
initial 
begin 
	clk = 0;
	arr = 20'b_01001_11010_11001_10010;
	#500 $stop;
end
always #5 clk=~clk;
always @(negedge clk) arr = {arr[0],arr[19:1]};
assign ain = arr[0];
endmodule

仿真波形截图(示例):
【Verilog】Verilog的八个经典入门例题

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2023年3月23日 上午8:40
下一篇 2023年3月23日 上午8:42

相关推荐