【verilog】数码管动态扫描实现方法

 

一. 实验目的

熟练掌握时序逻辑电路的设计方法

掌握寄存器文件的实现原理掌握

数码管动态扫描实现方法

 

二. 实验内容

用模块化设计,实现 16*16bit 的寄存器文件

– 具备 2 组读端口及 1 组写端口

– 通过读端口可从 0~15 号的任意地址读取数据

– 通过写端口可向 0~15 号的任意地址写入数据

– 读写端口为“全双工”的工作方式

– 0~15 号寄存器的复位初值依次为:“0x0000,0x1100,0x2200,...,0xFF00”

– 通过 1 组读端口及写端口,所有寄存器的值每 0.5s 秒钟加 1

– 通过拨动开关做为另 1 组读端口地址输入,将读出结果以16 进制显示在七段数码管上

 

三.实验结果

1)编写 verilog代码

Top 模块

 

module regfile(  
input clk, 
input reset_n, 
input [3:0]addr_a, 
input [3:0]addr_b, 
input [3:0]addr_c, 
input [15:0]data_c, 
input wen_c, 
output reg[15:0]q_a, 
output reg[15:0]q_b 
    );  	
reg[15:0] a0;reg[15:0] a1;reg[15:0] a2;
reg[15:0] a3;  	
reg[15:0] a4;
reg[15:0] a5;
reg[15:0] a6;
reg[15:0] a7;  	
reg[15:0] a8;
reg[15:0] a9;
reg[15:0] a10;
reg[15:0] a11;  	
reg[15:0] a12;
reg[15:0] a13;
reg[15:0] a14;
reg[15:0] a15;  	
    always @(posedge clk or negedge reset_n) 
 	 	if(~reset_n) 	 	 	 	 	 	//复位  	 	 	
                    begin  	 	 	 	
                       a0<=16'h0000;  	 	 	 	                  
                        a1<=16'h1100;  	 	 	 	
                        a2<=16'h2200;
  	 	 	 	a3<=16'h3300;
  	 	 	 	a4<=16'h4400;
  	 	 	 	a5<=16'h5500; 
 	 	 	 	a6<=16'h6600; 
 	 	 	 	a7<=16'h7700; 
 	 	 	 	a8<=16'h8800;  
	 	 	 	a9<=16'h9900; 
 	 	 	 	a10<=16'haa00; 
 	 	 	 	a11<=16'hbb00;
  	 	 	 	a12<=16'hcc00; 
 	 	 	 	a13<=16'hdd00;
  	 	 	 	a14<=16'hee00;
  	 	 	 	a15<=16'hff00; 
 	 	 	end 
 	 	else  	 	 	
begin
  	 	 	 if(wen_c)
  	 	 	 	begin 
 	 	 	 	 	case(addr_c)
  	 	 	 	 	 	4'b0000: a0<=data_c; 
 	 	 	 	 	 	4'b0001: a1<=data_c; 
 	 	 	 	 	  	4'b0010: a2<=data_c; 
 	 	 	 	 	  	4'b0011: a3<=data_c; 
 	 	 	 	 	  	4'b0100: a4<=data_c; 
 	 	 	 	 	  	4'b0101: a5<=data_c; 
	 	 	 	 	        4'b0110: a6<=data_c; 
 	 	 	 	                4'b0111: a7<=data_c;
                                      	 	4'b1000: a8<=data_c; 
	 	 	 	                4'b1001: a9<=data_c; 
	 	 	                       4'b1010: a10<=data_c; 
	 	                                4'b1011: a11<=data_c; 
 	 	 	                        4'b1100: a12<=data_c;
          	 	 	 	 	4'b1101: a13<=data_c; 
                                                4'b1110: a14<=data_c;
                                                4'b1111: a15<=data_c;
                                                default: a0<=0;     
                                        endcase 
 	 	 	 	 	 	q_b[15:0]<=data_c; 
 	 	 	 	end  	 	 	 	
                                    else  	 	 	 	 	
                                             begin 
 	 	 	 	 	 	case(addr_b) 
 	 	 	 	 	 	 	4'b0000: q_b[15:0]<=a0; 
 	 	 	 	 	 	 	4'b0001: q_b[15:0]<=a1; 
 	 	 	 	 	 	 	4'b0010: q_b[15:0]<=a2; 
 	 	 	 	 	 	 	4'b0011: q_b[15:0]<=a3; 
 	 	 	 	 	 	 	4'b0100: q_b[15:0]<=a4; 
 	 	 	 	 	 	 	4'b0101: q_b[15:0]<=a5; 
 	 	 	 	 	 	 	4'b0110: q_b[15:0]<=a6; 
 	 	 	 	 	 	 	4'b0111: q_b[15:0]<=a7; 
 	 	 	 	 	 	 	4'b1000: q_b[15:0]<=a8; 
 	 	 	 	 	 	 	4'b1001: q_b[15:0]<=a9; 
 	 	 	 	 	 	 	4'b1010: q_b[15:0]<=a10; 
 	 	 	 	 	 	 	4'b1011: q_b[15:0]<=a11; 
 	 	 	 	 	 	 	4'b1100: q_b[15:0]<=a12; 
 	 	 	 	 	 	 	4'b1101: q_b[15:0]<=a13; 
 	 	 	 	 	 	 	4'b1110: q_b[15:0]<=a14; 
 	 	 	 	 	 	 	4'b1111: q_b[15:0]<=a15;
  	 	 	 	 	 	 	default: q_b[15:0]<=16'h0000; 
 	 	 	 	 	 	endcase
  	 	 	 	 	end
  	 	 	end 
 	 	always@(posedge clk or negedge reset_n)
  	 	 	if(~reset_n)
  	 	 	 	q_a[15:0]<=16'h0000;
  	 	 	else 
 	 	 	 	case(addr_a) 
 	 	 	 	 	4'b0000: q_a[15:0]<=a0; 
 	 	 	 	 	4'b0001: q_a[15:0]<=a1; 
	 	 	 	        4'b0010: q_a[15:0]<=a2; 
 	 	                        4'b0011: q_a[15:0]<=a3;
                                      	4'b0100: q_a[15:0]<=a4; 
	 	                        4'b0101: q_a[15:0]<=a5; 
	 	                        4'b0110: q_a[15:0]<=a6; 
	 	                        4'b0111: q_a[15:0]<=a7; 
	 	                        4'b1000: q_a[15:0]<=a8; 
	 	                         4'b1001: q_a[15:0]<=a9; 
	 	                         4'b1010: q_a[15:0]<=a10; 
	 	                        4'b1011: q_a[15:0]<=a11; 
	 	                        4'b1100: q_a[15:0]<=a12; 
	 	                        4'b1101: q_a[15:0]<=a13; 
 	 	 	 	 	4'b1110: q_a[15:0]<=a14;
  	 	 	 	 	4'b1111: q_a[15:0]<=a15;
  	 	 	 	 	default: q_a[15:0]<=16'h0000;
 	 	 	 	endcase 
endmodule 

 

 

 

 

 

 

 

module inc(  	input clk,  	input reset_n,  	input [15:0]q_b,  	output reg[3:0] addr_b,  	output reg[3:0] addr_c,  	output reg[15:0] data_c,  	output reg wen_c 
    );  	reg [29:0]cnt;  	reg clk0;  	always@(posedge clk or negedge reset_n)  	 	if(~reset_n)  	 	 	cnt<=0;  	 	else  	 	 	begin  	 	 	 	cnt<=cnt+1;  	 	 	 	if(cnt==100000-1) 
 	 	 	 	 	clk0<=1; 
 	 	 	 	else if(cnt==1000000-1)  	 	 	 	 	begin  	 	 	 	 	 	clk0<=0;  	 	 	 	 	 	cnt<=0;  	 	 	 	 	end  	 	 	end 
 	always@(posedge clk0 or negedge reset_n) 
if(~reset_n) begin 
wen_c<=0; addr_b<=0; addr_c<=0; data_c<=0; 
end else 
 	begin  	 	if(wen_c) 
 	 	 	begin  	 	 	 	wen_c<=~wen_c;  	 	 	 	 	 	addr_b<=addr_b;  	 	 	 	 	 	if(addr_c>=4'b1111)  	 	 	 	 	 	 	addr_c<=4'b0000; 
 	 	 	 	 	 	else 
 	 	 	 	 	 	 	addr_c<=addr_c+1;  	 	 	 	 	 	 	data_c<=data_c; 
 	 	 	 	 	end  	 	 	 	else  	 	 	 	 	begin 
 	 	 	 	 	 	wen_c<=~wen_c;  	 	 	 	 	 	if(addr_b>=4'b1111)  	 	 	 	 	 	 	addr_b<=4'b0000; 
 	 	 	 	 	 	else 
 	 	 	 	 	 	 	addr_b<=addr_b+1;  	 	 	 	 	 	 	data_c<=q_b+1'b1; 
 	 	 	 	 	end  	 	 	end 
endmodule 
module seg(  	input clk,  	input reset_n,  	input [15:0]q_a,  	output reg[7:0]data,  	output reg[3:0]sel 
    );  	reg [29:0]cnt;  	reg [1:0]scn_cnt;  	reg clk0;  	always@(posedge clk or negedge reset_n) 
if(~reset_n) 
 	cnt<=0; else begin 
cnt<=cnt+1; 
if(cnt==10000-1)  	clk0<=1; 
else if(cnt==100000-1) 
 	begin  	 	clk0<=0;  	 	cnt<=0;  	end 
 	 	 	end 
 	always@(posedge clk0 or negedge reset_n)  	 	if(~reset_n)  	 	 	scn_cnt<=2'b00;  	 	else  	 	 	begin 
 	 	 	 	if(scn_cnt==2'b11)  	 	 	 	 	scn_cnt<=2'b00;  	 	 	 	else 
 	 	 	 	 	scn_cnt<=scn_cnt+1'b1; 
 	 	 	end 
 	always@(posedge clk0 or negedge reset_n)  	 	if(~reset_n)  	 	 	sel<=4'b1111;  	 	else 
 	 	 	case(scn_cnt)  	 	 	 	2'b00: 	sel<=4'b1110; 
 	 	 	 	2'b01: 	sel<=4'b1101; 
    2'b10: sel<=4'b1011;     2'b11: sel<=4'b0111;     default: sel<=4'b1111;    endcase 
 	always @(posedge clk0 or negedge reset_n)  	if(~reset_n)  	 	data=8'b11111111;  	else 
 	 	begin 
 	 	 	if(sel==4'b0111)  	 	 	 	begin 
 	 	 	 	 	case(q_a[15:12])  	 	 	 	 	 	4'h0: data=8'b00000011; 
 	 	 	 	 	 	4'h1: data=8'b10011111; 
	 	 	 	 	4'h2: data=8'b00100101; 
	 	 	 	 	4'h3: data=8'b00001101; 
	 	 	 	 	4'h4: data=8'b10011001; 
 	 	 	4'h5: data=8'b01001001;  	 	4'h6: data=8'b01000001;  	 	4'h7: data=8'b00011111; 
	 	 	4'h8: data=8'b00000001; 
 	 	4'h9: data=8'b00001001;  	 	4'ha: data=8'b00010001; 
	 	 	4'hb: data=8'b11000001; 
	 	 	4'hc: data=8'b01100011; 
	 	 	4'hd: data=8'b10000101; 
 	 	 	 	 	 	4'he: data=8'b01100001;  	 	 	 	 	 	4'hf: data=8'b01110001;  	 	 	 	 	 	default: data=8'b11111111; 
 	 	 	 	 	endcase  	 	 	 	end 
 	 	 	else if(sel==4'b1011) 
 	 	 	 	begin 
 	 	 	 	 	case(q_a[11:8])  	 	 	 	 	 	4'h0: data=8'b00000011; 
 	 	 	 	 	 	4'h1: data=8'b10011111; 
 	 	 	 	 	 	4'h2: data=8'b00100101; 
 	 	 	 	 	 	4'h3: data=8'b00001101; 
 	 	 	 	 	 	4'h4: data=8'b10011001; 
 	 	 	 	 	 	4'h5: data=8'b01001001; 
 	 	 	 	 	 	4'h6: data=8'b01000001; 
 	 	 	 	 	 	4'h7: data=8'b00011111; 
 	 	 	 	 	 	4'h8: data=8'b00000001; 
 	 	 	 	 	 	4'h9: data=8'b00001001;  	 	 	 	 	 	4'ha: data=8'b00010001;  	 	 	 	 	 	4'hb: data=8'b11000001; 
 	 	 	 	 	 	4'hc: data=8'b01100011; 
 	 	 	 	 	 	4'hd: data=8'b10000101;  	 	 	 	 	 	4'he: data=8'b01100001;  	 	 	 	 	 	4'hf: data=8'b01110001;  	 	 	 	 	 	default: data=8'b11111111; 
 	 	 	 	 	endcase  	 	 	 	end 
 	 	 	else if(sel==4'b1101)  	 	 	 	begin 
 	 	 	 	 	case(q_a[7:4])  	 	 	 	 	 	4'h0: data=8'b00000011; 
 	 	 	 	 	 	4'h1: data=8'b10011111; 
	 	 	 	 	4'h2: data=8'b00100101; 
	 	 	 	 	4'h3: data=8'b00001101; 
	 	 	 	 	4'h4: data=8'b10011001; 
 	 	 	4'h5: data=8'b01001001;  	 	4'h6: data=8'b01000001;  	 	4'h7: data=8'b00011111; 
	 	 	4'h8: data=8'b00000001; 
 	 	4'h9: data=8'b00001001;  	 	4'ha: data=8'b00010001; 
	 	 	4'hb: data=8'b11000001; 
	 	 	4'hc: data=8'b01100011; 
	 	 	4'hd: data=8'b10000101; 
 	 	 	 	 	 	4'he: data=8'b01100001;  	 	 	 	 	 	4'hf: data=8'b01110001;  	 	 	 	 	 	default: data=8'b11111111; 
 	 	 	 	 	endcase  	 	 	 	end 
 	 	 	else   	 	 	 	begin 
 	 	 	 	 	case(q_a[3:0])  	 	 	 	 	 	4'h0: data=8'b00000011; 
 	 	 	 	 	 	4'h1: data=8'b10011111; 
 	 	 	 	 	 	4'h2: data=8'b00100101; 
 	 	 	 	 	 	4'h3: data=8'b00001101; 
 	 	 	 	 	 	4'h4: data=8'b10011001; 
 	 	 	 	 	 	4'h5: data=8'b01001001; 
 	 	 	 	 	 	4'h6: data=8'b01000001; 
 	 	 	 	 	 	4'h7: data=8'b00011111; 
 	 	 	 	 	 	4'h8: data=8'b00000001; 
 	 	 	 	 	 	4'h9: data=8'b00001001;  	 	 	 	 	 	4'ha: data=8'b00010001;  	 	 	 	 	 	4'hb: data=8'b11000001; 
 	 	 	 	 	 	4'hc: data=8'b01100011; 
 	 	 	 	 	 	4'hd: data=8'b10000101;  	 	 	 	 	 	4'he: data=8'b01100001;  	 	 	 	 	 	4'hf: data=8'b01110001;  	 	 	 	 	 	default: data=8'b11111111; 
 	 	 	 	 	endcase  	 	 	 	end  	 	end endmodule 

 

2) Ucf 文件设置

 

 

四.实验分析

1.本实验主要分为三个部分,寄存器文件,数码管的控制,以及加一运算实现这三个模块

2..寄存器文件本质为一状态机

3.对于时间上地要求,0.5s 采用统计地方式实现,达到一定地周期数后产生脉冲 

 

在同一时刻对同一地址进行读写,会有何结果?会将时钟上升沿之前的内容读出,然后将新内容写进覆盖原先内容,因为在reg 模块中可见采用的是非阻塞赋值的方式,读写同时进行不存在先后

 

 

相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页