基于Verilog的简单计算器设计
verilog简单乘法器
verilog简单乘法器Verilog简单乘法器Verilog是一种硬件描述语言,用于描述数字系统的行为。
在数字电路设计中,乘法器是一个常见的电路组件,它用于执行乘法运算。
本文将介绍一个简单的Verilog乘法器的设计与实现。
乘法器是一种数字电路,用于计算两个数的乘积。
它接收两个输入数,将它们相乘得到一个输出。
在本文中,我们将实现一个4位乘法器,即输入和输出都是4位的二进制数。
我们需要定义输入和输出端口。
在Verilog中,我们可以使用“input”和“output”关键字来声明端口。
对于4位乘法器,我们可以声明两个4位的输入端口A和B,以及一个8位的输出端口P。
module simple_multiplier(input [3:0] A,input [3:0] B,output [7:0] P);接下来,我们需要实现乘法器的功能。
乘法器的实现可以通过多次执行加法运算来实现。
具体地,我们可以将输入的两个4位数逐位相乘,然后将得到的部分乘积相加得到最终的乘积。
在Verilog中,我们可以使用“assign”关键字来执行赋值操作。
我们可以定义一些临时变量,用于存储部分乘积和最终乘积的结果。
然后,通过多次执行加法运算,将部分乘积相加得到最终乘积。
下面是一个实现4位乘法器的简单示例代码:reg [7:0] temp;reg [7:0] result;always @(*) begintemp = A[0] * B;result = temp;temp = A[1] * B;result = result + (temp << 1);temp = A[2] * B;result = result + (temp << 2);temp = A[3] * B;result = result + (temp << 3);endassign P = result;在上述代码中,我们使用了一个“always”块来执行乘法器的功能。
基于Verilog HDL的32位分频计数器的设计
分频计数器的基本原理
• 选择合适频率的晶振,然后对其分频,得到 系统需要的时钟频率,再对这一频率时钟进行计 数据。一般的计数器都有输入时钟信号,这里以 晶振的输出时钟作为分频计数据器的输入时钟 CLK。复位信号对各信号进行复位。片选信号用 于选通芯片,以备读写计数值。写信号用于写计 数初始值。读信号用于读取计数值。地址信号 ADDR决定读写计数值的高位还是低位。CLKl为 分频输出的时钟信号。c为输出的进位信号。 DATA为双向数据信号+当系统为分频计数器写 入初始值时是输入,当系统读取计数值时是输出。
基于Verilog HDL的32位分频计 数器的设计
微电子 高翔
Verilog HDL的优点
• Verilog HDL是一种通用的硬件描述语言,易 • 学易用
• Verilog HDL允许在同一个电路模型内进行不 • 同抽象层次的描述
• Verilog HDL 绝大多数流行的综合工具都支持
• 所有的制造厂商都提供用于Verilog HDL综合 • 之后的逻辑仿真的元件库
原理图
实现功能综合
程序仿真
总结
• 首先本文介绍了硬件描述语言的发展状况,并对国内发展 提出了建议,然后对本
• 文要用的硬件语言VerilogHDL进行了详细介绍,并对仿真 所用的软件进行了介
•
绍。
• 其次介绍了32位分频器计数器的原理,并介绍了其它的 分频器,讨论了优缺点,
• 并且详细介绍了本文所用的分频计数器的原理和介绍、分 析。
HDL语言的发展。基于Verilog HDL的优越性,IEEE于
verilog实验 计数器实验报告
计数器1、实现目标及介绍实验实现了一个简易的计数器,计数范围可达899(0~899),通过key4按键计数,每按下一次,计数加一,百位数显示在led上,个位与十位显示在数码管上。
为十进制计数,数码管1计数到九后置零。
数码管2获得进位加一,数码管2到9后当再次获得个位进位时再次向百位进一,点亮led1,每百位点亮一个led。
此外key4为清零键,可随时按键清零。
2、效果展示计数99清零计数100视频展示(双击观看)3、代码实现与模块分析1.顶层模块module jishuqi(input wire clk,rst, //时钟和复位输入input wire key1, //拨码计output wire [7:0]led,output wire [8:0] segment_led_1,segment_led_2 //数码管输出);wire key_pulse;reg [7:0] cnt; //计时计数器reg [7:0] hud; //百位计数initial hud[7:0] <= 8'b11111111;always @(posedge clk or negedge rst)begin //数码管显示要按照十进制的方式显示if(!rst)begin cnt <= 8'h00;hud [7:0] <= 8'b11111111;endelse if(key_pulse)beginif(cnt[3:0] == 4'd9) //个位进位判断begincnt[3:0] <= 4'd0;if(cnt[7:4] == 4'd9 ) //十位进位判断begincnt[7:4] <= 4'd0;hud[7:0] <= hud[7:0] - 1'b1;endelsecnt[7:4] <= cnt[7:4] + 1'b1;endelse cnt[3:0] <= cnt[3:0] + 1'b1;endelsecnt <= cnt;endassign led = hud;//例化调用数码管显示模块segment u2(.seg_data_1 (cnt[7:4]), //g_data input.seg_data_2 (cnt[3:0]), //g_data input.seg_led_1 (segment_led_1), //MSB~LSB = SEG,DP,G,F,E,D,C,B,A.seg_led_2 (segment_led_2) //MSB~LSB = SEG,DP,G,F,E,D,C,B,A);//例化调用消抖模块debounce u1 (.clk (clk),.rst (rst),.key (key1),.key_pulse (key_pulse));endmodule2.数码管显示模块module segment (seg_data_1,seg_data_2,seg_led_1,seg_led_2);input [3:0] seg_data_1;//数码管需要显示0~9十个数字,所以最少需要4位输入做译码input [3:0] seg_data_2; //小脚丫上第二个数码管output [8:0] seg_led_1;//在小脚丫上控制一个数码管需要9个信号MSB~LSB=DIG、DP、G、F、E、D、C、B、Aoutput [8:0] seg_led_2;//在小脚丫上第二个数码管的控制信号MSB~LSB=DIG、DP、G、F、E、D、C、B、Areg [8:0] seg [9:0];//定义了一个reg型的数组变量,相当于一个10*9的存储器,存储器一共有10个数,每个数有9位宽initial//在过程块中只能给reg型变量赋值,Verilog中有两种过程块always和initial //initial和always不同,其中语句只执行一次beginseg[0] = 9'h3f; //对存储器中第一个数赋值9'b00_0011_1111,相当于共阴极接地,DP点变低不亮,7段显示数字0seg[1] = 9'h06; //7段显示数字 1seg[2] = 9'h5b; //7段显示数字 2seg[3] = 9'h4f; //7段显示数字 3seg[4] = 9'h66; //7段显示数字 4seg[5] = 9'h6d; //7段显示数字 5seg[6] = 9'h7d; //7段显示数字 6seg[7] = 9'h07; //7段显示数字7seg[8] = 9'h7f; //7段显示数字8seg[9] = 9'h6f; //7段显示数字9endassign seg_led_1 = seg[seg_data_1]; //连续赋值,这样输入不同四位数,就能输出对于译码的9位输出assign seg_led_2 = seg[seg_data_2];endmodule3.按键消抖模块//按键消抖module debounce (clk,rst,key,key_pulse);parameter N = 2; //要消除的按键的数量input clk;input rst;input [N-1:0] key; //输入的按键output [N-1:0] key_pulse; //按键动作产生的脉冲reg [N-1:0] key_rst_pre; //定义一个寄存器型变量存储上一个触发时的按键值reg [N-1:0] key_rst; //定义一个寄存器变量储存储当前时刻触发的按键值wire [N-1:0] key_edge; //检测到按键由高到低变化是产生一个高脉冲//利用非阻塞赋值特点,将两个时钟触发时按键状态存储在两个寄存器变量中always @(posedge clk or negedge rst)beginif (!rst)beginkey_rst <= {N{1'b1}}; //初始化时给key_rst赋值全为1,{}中表示N个1key_rst_pre <= {N{1'b1}};endelsebeginkey_rst <= key; //第一个时钟上升沿触发之后key的值赋给key_rst,同时key_rst的值赋给key_rst_prekey_rst_pre <= key_rst; //非阻塞赋值。
verilog实现简易24小时计数器
verilog实现简易24⼩时计数器1.顶层数码管显⽰模块`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company:// Engineer://// Create Date: 18:57:45 08/18/2019// Design Name:// Module Name: dynamic_seg_top// Project Name:// Target Devices:// Tool versions:// Description: //实现简易时钟计数功能//// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://module dynamc_seg_top//---------------------<端⼝声明>---------------------------------------(input clk_50MHZ , //时钟,50Mhzinput rst_n , //复位,低电平有效output reg [ 7:0] seg_sel , //数码管位选output reg [ 7:0] seg_data //数码管段选,即内容显⽰);//---------------------<信号定义>---------------------------------------wire clk_1KHZ ;reg [3:0] data_tmp ;reg [7:0] cnt ;wire [23:0] data ;//----------------------------------------------------------------------// 1k分频例化,扫描⼀个数码管时间为1ms//----------------------------------------------------------------------CLK_DIV #(.width(16),.cnt(50_000))uut(.clk_50MHZ(clk_50MHZ),.rst_n(rst_n),.clk_out(clk_1KHZ));//======================================================================////时,分,秒计数例化////======================================================================clock_cntclk_cnt_uut(.clk_50MHZ(clk_50MHZ),.rst_n(rst_n),.data(data));//----------------------------------------------------------------------// 数码管扫描,8位循环扫描,频率为1k//----------------------------------------------------------------------always @(posedge clk_1KHZ or negedge rst_n)beginif(!rst_n)seg_sel <= 8'b0111_1111;else if(seg_sel==8'b1111_1110)seg_sel <= 8'b0111_1111;elseseg_sel <= ~(~seg_sel>>1);end//----------------------------------------------------------------------// 位选,不同计数对应不同位选编码,也对应分割的不同数据//----------------------------------------------------------------------always @(*)begincase(seg_sel)8'b0111_1111: data_tmp = data[ 3: 0] ; // 位18'b1011_1111: data_tmp = data[ 7: 4] ; // 位28'b1101_1111: data_tmp = 4'ha ; // 位38'b1110_1111: data_tmp = data[11:8] ; // 位48'b1111_0111: data_tmp = data[15:12] ; // 位58'b1111_1011: data_tmp = 4'hb ; // 位68'b1111_1101: data_tmp = data[19:16] ; // 位78'b1111_1110: data_tmp = data[23:20] ; // 位8default: data_tmp = 4'b0000 ;endcaseend//----------------------------------------------------------------------// 段选,将不同分割数据进⾏段选编码,实验平台为2个4位⼀体共阳数码管//----------------------------------------------------------------------always @(*)begincase(data_tmp)4'h0: seg_data = 9'hc0;4'h1: seg_data = 9'hf9;4'h2: seg_data = 9'ha4;4'h3: seg_data = 9'hb0;4'h4: seg_data = 9'h99;4'h5: seg_data = 9'h92;4'h6: seg_data = 9'h82;4'h7: seg_data = 9'hf8;4'h8: seg_data = 9'h80;4'h9: seg_data = 9'h90;4'ha: seg_data = 9'hbf;//4'hb: seg_data = 9'hbf;//第三位和第六位显⽰时钟的分隔线default:seg_data = 9'hc0;endcaseendendmodule2.时分秒计数模块`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company:// Engineer://// Create Date: 19:51:36 02/25/2020// Design Name:// Module Name: clock_cnt// Project Name:// Target Devices:// Tool versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments:////////////////////////////////////////////////////////////////////////////////////module clock_cnt(input clk_50MHZ,input rst_n,output [23:0]data);reg [7:0] second ;//时钟“秒”reg [7:0] minute ;//时钟“分”reg [7:0] hour ;//时钟“⼩时”wire clk_1HZ ;//----------------------------------------------------------------------//-- 例化计数分频产⽣1HZ时钟//----------------------------------------------------------------------CLK_DIV #(.width(28),.cnt(50_000_000))uut(.clk_50MHZ(clk_50MHZ),.rst_n(rst_n),.clk_out(clk_1HZ));//----------------------------------------------------------------------//-- 秒计数,从0-59计数,1秒加⼀,到59清零//----------------------------------------------------------------------always @(posedge clk_1HZ or negedge rst_n)beginif(!rst_n)second<=8'd0;else if (second[3:0]==4'd9)beginsecond[3:0]<=8'd0;if(second[7:4]==4'd5)second[7:4]<=4'd0;elsesecond[7:4]<=second[7:4]+4'd1;endelsesecond[3:0]<=second[3:0]+4'd1;end//----------------------------------------------------------------------//-- 分计数,从0-59计数,1分钟加⼀,到59清零//----------------------------------------------------------------------always @(posedge clk_1HZ or negedge rst_n)beginif(!rst_n)minute<=8'd0;else if ((second[3:0]==4'd9)&(second[7:4]==4'd5))beginif(minute[3:0]==4'd9)beginminute[3:0] <=4'd0;if(minute[7:4]==4'd5)minute[7:4] <=4'd0;elseminute[7:4] <=minute[7:4]+4'd1;endelsebeginminute[3:0]<=minute[3:0]+4'd1;endendelseminute<=minute;end//----------------------------------------------------------------------//-- ⼩时计数,从0-23计数,1⼩时加⼀,到23清零//----------------------------------------------------------------------always @(posedge clk_1HZ or negedge rst_n)beginif(!rst_n)hour<=8'd0;else if ((second[3:0]==4'd9)&(second[7:4]==4'd5)&(minute[3:0]==4'd9)&(minute[7:4]==4'd5)) beginif(hour[7:4]==4'd2)beginif(hour[3:0]==4'd3)beginhour[3:0] <=4'd0;hour[7:4]<=4'd0;endelsebeginhour[7:4]<=hour[7:4];hour[3:0] <=hour[3:0]+4'd1;endendelsebeginif(hour[3:0]==4'd9)beginhour[3:0] <=4'd0;hour[7:4] <=hour[7:4]+4'd1;endelsebeginhour[3:0] <=hour[3:0]+4'd1;hour[7:4] <=hour[7:4];endendendelsehour<=hour;endassign data[3:0] =second [3:0];//将“秒”的个位数送到数码管第⼀位assign data[7:4] =second [7:4];//将“秒”的⼗位数送到数码管第⼆位assign data[11:8] =minute [3:0];//将“分“的个位数送到数码管第四位assign data[15:12] =minute [7:4];//将”分”的⼗位数送到数码管第五位assign data[19:16] =hour [3:0];//将“时“的个位数送到数码管第七位assign data[23:20] =hour [7:4];//将”时”的个位数送到数码管第⼋位endmodule3.任意时钟分频模块`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company:// Engineer://// Create Date: 18:54:40 02/25/2020// Design Name:// Module Name: CLK_DIV// Project Name:// Target Devices:// Tool versions:// Description: //任意时钟分频模块//// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments:////////////////////////////////////////////////////////////////////////////////////module CLK_DIV #(parameter width = 28,parameter cnt = 50_000_000)(input clk_50MHZ,input rst_n ,output clk_out);reg [width-1:0] cnt_p;reg cnt_n;reg clk_p;reg clk_n;//上升沿计数器,实现0-49_999_999计数always@(posedge clk_50MHZ or negedge rst_n)beginif(!rst_n)cnt_p <= 1'b0;else if(cnt_p == (cnt-1))cnt_p <= 1'b0;elsecnt_p <= cnt_p + 1'b1;end//上升沿触发时钟分频,实现1HZ时钟输出always@(posedge clk_50MHZ or negedge rst_n)beginif(!rst_n)clk_p<=1'b0;else if(cnt_p<(cnt>>1))clk_p<=1'b0;elseclk_p<=1'b1;endalways@(negedge clk_50MHZ or negedge rst_n)beginif(!rst_n)cnt_n <= 1'b0;else if(cnt_n == (cnt-1))cnt_n <= 1'b0;elsecnt_n <= cnt_n + 1'b1;endalways@(negedge clk_50MHZ or negedge rst_n)beginif(!rst_n)clk_n<=1'b0;else if(cnt_n<(cnt>>1))clk_n<=1'b0;elseclk_n<=1'b1;endwire clk1=clk_50MHZ; //当分频系数为1时,输出时钟wire clk2=clk_p; //当分频系数为偶数时,输出等于clk_pwire clk3=clk_p&clk_n;//当分频系数为奇数时,输出等于clk_p&clk_n assign clk_out=(cnt==1)?clk1:(cnt[0]? clk2:clk3);endmodule4.时分秒仿真testbench⽂件`timescale 100ps / 1ps////////////////////////////////////////////////////////////////////////////////// Company:// Engineer://// Create Date: 22:18:22 02/25/2020// Design Name: clock_cnt// Module Name: C:/mydesign/dybamic_seg1/clk_tb.v// Project Name: dybamic_seg// Target Device:// Tool versions:// Description://// Verilog Test Fixture created by ISE for module: clock_cnt//// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://////////////////////////////////////////////////////////////////////////////////module clk_tb;// Inputsreg clk_50MHZ;reg rst_n;// Outputswire [23:0] data;// Instantiate the Unit Under Test (UUT)clock_cnt uut (.clk_50MHZ(clk_50MHZ),.rst_n(rst_n),.data(data));initial begin// Initialize Inputsclk_50MHZ = 0;rst_n = 0;// Wait 100 ns for global reset to finish#10;rst_n = 1;#10;// Add stimulus hereendalways #1 clk_50MHZ=~clk_50MHZ;endmodule5.显⽰模块仿真testbench⽂件`timescale 1ns / 1ps////////////////////////////////////////////////////////////////////////////////// Company:// Engineer://// Create Date: 15:11:16 02/26/2020// Design Name: dynamc_seg_top// Module Name: C:/mydesign/dybamic_seg1/dy_segtb.v// Project Name: dybamic_seg// Target Device:// Tool versions:// Description://// Verilog Test Fixture created by ISE for module: dynamc_seg_top //// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://////////////////////////////////////////////////////////////////////////////////module dy_segtb;// Inputsreg clk_50MHZ;reg rst_n;// Outputswire [7:0] seg_sel;wire [7:0] seg_data;// Instantiate the Unit Under Test (UUT)dynamc_seg_top uut (.clk_50MHZ(clk_50MHZ),.rst_n(rst_n),.seg_sel(seg_sel),.seg_data(seg_data));initial begin// Initialize Inputsclk_50MHZ = 0;rst_n = 0;// Wait 100 ns for global reset to finish#10;rst_n = 1;#10;// Add stimulus hereendalways #1 clk_50MHZ=~clk_50MHZ;endmodule。
verilog设计一四位计数器
学院:信息技术学院班级:专业:电子信息科学与技术姓名:日期:学号:1、熟悉行为级语法;2、熟悉有限状态机设计一四位计数器,进行仿真,并检测输出结果;提示:在时钟上升沿,如果复位信号有效,则复位为0,如果复位信号无效,则计数器需要加一。
完成一个序列信号电路检测器,检测信号为10010,当检测到此序列时输出端口输出高电平,其余时间输出低电平。
提示:先画出状态转换图或写出状态转换表,根据状态表或者状态图完成代码的设计;编写测试模块对该功能模块进行仿真。
要求实验报告包括完整的状态转化图或者转化表。
序列信号电路检测器:module mian (z, x, clock, clear);output z;reg z;input clock, clear;input x;parameter s0 = 3'd0,s1 = 3'd1,s2 = 3'd2,s3 = 3'd3,s5 = 3'd5,s4 = 3'd4;reg [2:0] state;reg [2:0] next_state;always @(posedge clock) if(clear)state <= s0;elsestate <= next_state;always @(state)begincase(state)s0: show = 0;s1: show = 0;s2: show = 0;s3: show = 0;s4: show = 0;s5: show = 1; endcaseendalways @(x or state) begincase(state)s0: if(x == 0)next_state = s0;elsenext_state = s1;s1: if(x == 0)next_state = s2;elsenext_state = s1;s2: if(x == 0)next_state = s3;elsenext_state = s1;s3: if(x == 0)next_state = s0;elsenext_state = s4;s4: if(x == 0)next_state = s5;elsenext_state = s1;s5: if(x == 0)next_state = s0;elsenext_state = s1;endcaseendendmodulemodule stimulus_mv;wire z;reg x;reg clock, clear; mianMVP(z, x, clock, clear);initialbegin clock = 0;forever #5 clock = ~clock;endinitialbeginclear = 1;repeat(2)@(negedge clock);clear = 0;endinitialbegin#30 x = 1;#10 x = 0;#10 x = 0;#10 x = 1;#10 x = 0;endendmodule1.输出:四位计数器3.1功能块代码module counter(out, clock, clear);output out;input clock, clear;reg [3:0] out;always @(posedge clock or negedge clear) beginif(clear)out <= 4'd0;elseout <= out + 1;endendmodule3.2测试模块代码module counter_stimulus;reg clock, clear;wire [3:0] out;initial$monitor($time, "count = %b , clear = %b", out[3:0], clear); counter MVP(out, clock, clear);alwaysbeginclear = 1'b1;#15 clear = 1'b0;#200 clear = 1'b1;#50 clear = 1'b1;endinitialbeginclock = 1'b0;forever #5 clock = ~clock;endinitialbegin#400 $Finish;endendmodule4分析总结4.1遇到的问题及解决方法4.2实验心得及存在的问题。
Verilog实现加减乘除计算器
Verilog实现加减乘除计算器主要内容: 1. 按键按下后,进⾏加减乘除操作 2. Verilog往TXT⽂本⽂件中写⼊数据 3. 完成计算模块 4. 最终实现加减乘除计算器1. 实现按键按下后,选择option,进⾏加减乘除操作,除法计算结果为商&余数module jsq(clk,rst_n,key,option,x,y,result,quotient,remainder);parameter N = 16; // 输⼊数的位数input clk; // 输⼊时钟input rst_n; // 低电平有效的复位(清零)input key;input [1:0]option;input [N-1:0] x;input [N-1:0] y;output [2*N-1:0] result;output [N-1:0] quotient; //输出计算的商output [N-1:0] remainder; //输出计算的余数reg [2*N-1:0] result_r;reg [N-1:0] quotient_r,remainder_r;always @ (posedge clk or negedge rst_n)beginif (!rst_n)beginresult_r <= 1'b0;quotient_r <= 1'b0;remainder_r <= 1'b0;endelsebeginif (key == 1'b0)begin//按键按下case(option)2'b00: result_r = x + y;2'b01: result_r <= x + (~y + 1'b1);2'b10: result_r = x * y;2'b11: //result_r = x / y;beginquotient_r = x / y;remainder_r = x % y;endendcaseendelsebegin// 按键释放result_r <= 1'b0;quotient_r <= 1'b0;remainder_r <= 1'b0;endendendassign result = result_r ;assign quotient= quotient_r;assign remainder = remainder_r;endmoduleView Code`timescale 1ns/1ps`define clock_period 20module jsq_tb;reg clk;reg rst_n;reg key;reg [1:0]option;reg [15:0] x,y;wire [31:0] result;wire [15:0] quotient;wire [15:0] remainder;initial beginclk = 1'b1;rst_n = 1'b0;key = 1'b1; // 复位时,按键释放# 20//复位20nsrst_n = 1'b1;# 20key = 1'b0;option = 2'b10;# 100key = 1'b1;# 20key = 1'b0;option = 2'b11;# 100// key = 1'b1;// # 20$stop;endalways #(`clock_period/2) clk = ~clk; //50Mjsq #(.N(16)) jsq_0(.clk(clk),.rst_n(rst_n),.key(key),.option(option),.x(x),.y(y),.result(result),.quotient(quotient),.remainder(remainder));initial beginx = 0;repeat(20)#(`clock_period) x = {$random}%100; //通过位拼接操作{}产⽣0—59范围的随机数endinitial beginy = 0;repeat(20)#(`clock_period) y = {$random}%50;end/*integer i;initial beginx = 0;y = 0;for(i = 0; i < 20; i = i + 1)begin//利⽤$random系统函数产⽣随机数。
基于Verilog-的任意模长可加减计数器设计
基于Verilog的任意模长可加减计数器设计一、设计要求计数器是一种在时钟的触发下,完成计数功能的时序逻辑电路,输出结果由输入时钟和计数器上一状态的计数共同决定。
本设计要求实现的计数器,具有以下功能:(1)要求实现计数器工作状态的控制;(2)要求实现计数器的异步清零功能;(3)要求实现计数器递增和递减的功能;(4)要求实现计数器的计数范围(模长)任意改变;二、设计思路计数器工作状态的控制,可以设计一个使能端,在外部时钟的触发下,只有当使能端信号有效(高电平),才启动计数器的计数功能(递增或递减),否则计数器输出结果不变。
计数器的异步清零功能,可以设计一个外部输入的清零端,在外部输入信号有效(低电平)的情况下,直接清零计数器,不用等待下一个外部时钟的触发,即计数器的清零是异步的。
计数器计数方向的控制,设计一个加减可控的信号端口,在时钟的触发、异步清零无效以及计数器使能端有效的情况下,该输入端为高电平则计数器完成递增功能,低电平则完成递减功能。
实现计数器的任意模长,即进入下一个计数周期,其计数的最大值可以发生变化。
设计一个4位(最大模长为16)的输入端口,可以在当前计数周期结束,即计数器产生一个溢出信号的同时,判断该端口输入的信号是否发生变化,通过相邻两个计数周期的端口数据作异或运算,结果为高电平则代表模长发生变化,即进入的下一个计数周期,其计数最大值要发生变化。
三、程序设计本次设计使用的是Quartus 11.0开发环境,该软件没有自带仿真功能(9.0版本以后都没自带),需要使用第三方的Modelsim 软件,故本设计的程序包括计数器的Verilog设计以及仿真测试需要的testbench激励文件两部分。
计数器的Verilog设计:module Prj(clk,rst_input,en,add_sub, ﻩdata_input,full,data_output);inputclk; ﻩﻩ // 外部时钟input rst_input; ﻩﻩ// 外部清零(异步)ﻩﻩﻩ // 计数使能input en;ﻩﻩinput add_sub; ﻩ//计数方向input [3:0] data_input; // 计数器模长输入output reg full; ﻩ // 计完当前模长output[3:0] data_output; // 计数器输出reg[3:0] current_counter;// 当前计数值(输出)reg update_length_en;// 改变模长的使能信号// 当前计数周期与上个计数周期的模长输入reg [3:0]current_clk_data_input,last_clk_data_in put;reg[3:0] counter_length; // 下个计数周期的模长reg[1:0] k;always @(posedgeclk,negedge rst_input)ﻩbeginﻩif(!rst_input)// 异步清零ﻩﻩbeginﻩﻩfull=0;ﻩcurrent_counter=0;ﻩendelse if(en)// 计数使能beginﻩﻩif(add_sub)// 加法器beginﻩﻩﻩﻩif(current_counter<(counter_length-1)) ﻩﻩﻩbeginﻩﻩﻩcurrent_counter=current_counter+1;ﻩﻩﻩfull=0;ﻩﻩﻩﻩendﻩﻩﻩelse// 加法器计数完产生full脉冲以触发// 判断下个计数周期的模长是否变化ﻩﻩﻩﻩﻩbeginﻩﻩﻩﻩﻩcurrent_counter=0;ﻩﻩfull=1; //full输出ﻩﻩﻩﻩﻩﻩendﻩﻩﻩﻩendﻩelse // 减法器ﻩbeginﻩif(current_counter>0)ﻩﻩﻩbeginﻩﻩﻩﻩcurrent_counter=current_counter-1; ﻩﻩﻩﻩfull=0;ﻩﻩﻩendﻩﻩﻩelse // 减法器计数完ﻩﻩbegincurrent_counter=counter_length-1;ﻩﻩﻩfull=1;ﻩﻩﻩﻩﻩﻩﻩendendﻩﻩﻩendend//驱动当前计数输出assigndata_output=current_counter;initialbeginﻩk=1; //k=1 表示启动计数器的第一个计数周期endalways @(posedge full) // 加法器/减法器完成当前周期计数ﻩ// 计完当前周期(即full有效)才更新beginﻩlast_clk_data_input<=data_input; // 上个周期的模长current_clk_data_input=data_input;//当前周期的模长update_length_en<=last_clk_data_input^current_clk_data_input;// update_length_en为更新计数器模长的使能端,// 异或运算使能端为0代表模长变化1不变k=k+1; // k的初值为1,k变化说明计数模长更改过了if(k==2'd3)ﻩﻩk=2;endalways @(posedgeclk)beginﻩﻩif(update_length_en) // 使能有效计数模长变化ﻩﻩcounter_length=current_clk_data_input;ﻩﻩelseﻩbeginﻩﻩif(k>=2)//下个周期计数器模长不变(保持上次更改的) ﻩﻩcounter_length=last_clk_data_input;ﻩif(k==1)ﻩ//整个计数器系统,最初的模长(一次没更改过)ﻩﻩﻩcounter_length=data_input;endendendmodule测试激励文件testbench:`timescale 1 ps/ 1 psmodule Prj_vlg_tst();reg add_sub;reg clk;reg [3:0] data_input;reg en;reg rst_input;wire [3:0] data_output;wire full;Prj i1(ﻩ.add_sub(add_sub),ﻩ.clk(clk),ﻩ.data_input(data_input),.data_output(data_output),ﻩ.en(en),ﻩ.full(full),.rst_input(rst_input));parameter clk_period=10; // 时钟周期initial //初始化使能端、清零端和时钟信号beginen=1;rst_input=1;clk=1;#(46*clk_period) en=0;#(3*clk_period) en=1;#(4*clk_period) rst_input=0;#(2*clk_period) rst_input=1;endalways #(clk_period/2) clk=~clk;initialbegin// 计数器模长分别为6 4 5 3// 左边为上一模长持续的时钟个数data_input=4'b0110;#(22*clk_period) data_input=4'b0100; #(12*clk_period) data_input=4'b0101;#(12*clk_period) data_input=4'b0011;#(5*clk_period);endinitialbegin// 计数器计数方向的改变//左边为递增递减持续的时钟个数add_sub=1;#(9*clk_period) add_sub=0;#(10*clk_period) add_sub=1;#(13*clk_period) add_sub=0;#(4*clk_period) add_sub=1;endendmodule四、仿真结果如图1所示,最开始计数器输入的模长data_input为6,在计数方向控制端add_sub为高电平的情况下,可以从0计数到5,在add_sub为低电平的情况下,可以实现计数器的递减;当计数器模长data_input变为4的时候,先计完当前周期的模长(0到5),才开始模长为4的计数(0到3)。
用VerilogHDL设计计数器
⽤VerilogHDL设计计数器⽤Verilog HDL设计计数器⼀、实验⽬的1. 学习使⽤Verilog HDL语⾔,并学会使⽤进⾏QuartusⅡ软件编程和仿真;2. 掌握数字电路的设计⽅法,熟悉设计过程及其步骤;3. 培养学⽣的动⼿能⼒,能学以致⽤,为今后从事电⼦线路设计打下良好基础;4. 巩固加深对数电知识的理解,在仿真调试过程中,能结合原理来分析实验现象;⼆、实验内容1.设计内容及要求1)利⽤Verilog HDL设计⼀个以⾃⼰学号后三位为模的计数器;2)编写源程序;3)给出仿真电路图和仿真波形图;2.需求分析:由于本⼈的学号后3位为212,所以应编⼀个以212为模的加法计数器。
若采⽤同步清零的⽅法,则计数为0~211,化为⼆进制数即为0 0000 0000计到0 1101 0011。
3.编写源代码:module count_212(out,data,load,reset,clk);output [8:0] out;input [8:0] data;inputload,reset,clk;reg [8:0] out;always @(posedgeclk)//clk上升沿触发beginif(!reset)out=9'h000; //同步清零,低电平有效else if (load)out=data; //同步预置else if (out>=211)out=9'h000; //计数最⼤值为211,超过清零else out=out+1; //计数endendmodule程序说明:该计数器为⼀个9位计数器,计数范围0~211,具有同步同步置数和同步清零功能。
时钟的上升沿有效,当clk信号的上升沿到来时,如果清零信号为0,则清零;若不为0,计数器进⾏计数,计⾄211处同步清零。
4.画出仿真电路图:图1为同步置数、同步清零加法计数器的仿真电路图图1 仿真电路图5.画出仿真波形先对逻辑波形进⾏初始化设置,将清零信号‘restest’置1,置数信号‘load’置0,得到的仿真波形图2所⽰,波形终⽌处如图3所⽰,图4为计数到211后⾃动清零。
verilog计数器代码
Verilog计数器代码1. 介绍计数器是数字电子电路中常见的组件之一,用于记录和显示特定事件的次数。
Verilog是一种硬件描述语言,可用于设计和模拟数字电路。
本文将介绍如何使用Verilog编写一个简单的计数器代码。
2. 计数器的基本原理计数器的基本原理是通过输入的时钟信号进行计数。
每当时钟信号的边沿到来时,计数器的值加1。
计数器可以根据需要进行设置,例如可以设置计数器的初始值、计数器的上限等。
3. Verilog计数器代码的编写下面是一个简单的Verilog计数器代码示例:module counter (input wire clk,input wire reset,output reg [7:0] count);always @(posedge clk or posedge reset) beginif (reset)count <= 0;elsecount <= count + 1;endendmodule代码中定义了一个名为counter的模块,该模块具有三个端口:clk、reset和count。
其中,clk为时钟信号输入端口,reset为复位信号输入端口,count为计数值输出端口。
always @(posedge clk or posedge reset)表示在时钟信号的上升沿或复位信号的上升沿时执行下面的代码块。
if (reset)表示当复位信号为高电平时,将计数器的值设置为0,否则将计数器的值加1。
4. 计数器的测试为了验证计数器的功能,我们可以编写一个简单的测试代码来模拟时钟信号和复位信号的变化。
下面是一个测试代码示例:module counter_tb;reg clk;reg reset;wire [7:0] count;counter uut (.clk(clk),.reset(reset),.count(count));always begin#5 clk = ~clk;endinitial beginclk = 0;reset = 0;#10 reset = 1;#20 reset = 0;#100 $finish;endendmodule测试代码中定义了一个名为counter_tb的测试模块。
verilog设计十进制计数器(含进位位)
verilog设计⼗进制计数器(含进位位)⼗进制计数器:设计要求:1、每当计数器值为4’b001时,⾃动回到4’b00002、每个时钟沿计数器值加13、进位输出carry应该与4'b1001同周期输出4、异步复位module cnt10 ( clk, rst_n, carry, cnt );input clk, rst_n;output carry;output [3:0] cnt;reg carry;reg [3:0] cnt;always @( posedge clk or negedge rst_n )beginif ( ~rst_n )begincnt <= 4'b0000;endelse if ( cnt == 4'b1001 )begincnt <= 4'b0000;endelsebegincnt <= cnt + 4'b0001;endendalways @(posedge clk or negedge rst_n)beginif(!rst_n)begincarry <= 1'b0;endelse if(cnt == 4'b1000)begincarry <= 1'b1;endelsecarry<= 1'b0;endendmoduleView Code测试程序:`timescale 1ns/1psmodule cnt10_tb();reg clk, rst_n;wire carry;wire [3:0] cnt;always #10 clk = ~clk;cnt10 cnt10_tb(.clk(clk),.rst_n(rst_n),.carry(carry),.cnt(cnt));initialbeginclk = 1'b0;rst_n = 1'b1;#10 rst_n = 1'b0;#10 rst_n = 1'b1;endendmodule波形图:在这个⼗进制计数器中,唯⼀要注意的⼀点就是进位位carry变化的时刻,如果是为了使下⼀级能正确接收到前⼀级的进位位标识,要在计数到九时使进位位有效;如上图波形所⽰。
10进制计数器verilog代码
以下是一个简单的10进制计数器的Verilog代码。
这个计数器在每个时钟周期内递增,并在计数到10后回滚到0。
verilog复制代码
module counter_10 (
input wire clk,
input wire reset,
output reg [3:0] count
);
always @(posedge clk or posedge reset) begin
if (reset) begin
count <= 4'b0000;
end else begin
count <= count + 1;
end
end
endmodule
在这个模块中,clk是时钟输入,reset是复位输入,count是4位的输出,表示当前的计数值。
在每个时钟上升沿,count都会递增。
当count达到10(即二进制的1010)时,它会被复位回0。
如果复位信号被激活,无论时钟状态如何,count都会被立即复位。
请注意,这是一个非常基础的计数器设计,没有包括一些更复杂的功能,比如预置值、异步/同步复位等。
如果你需要这些功能,你可能需要修改或扩展这个设计。
用VerilogHDL设计2位16进制计数器
基于FPGA的系统设计与应用实验二计数器设计实验一、实验目的:学习计数器的设计、仿真和硬件测试方法。
二、实验内容及步骤:1.用Verilog HDL设计2位16进制计数器,由DE2的KEY0输入计数值,在HEX1,HEX0上显示计数值。
2.使用嵌入式逻辑分析仪进行仿真;3.将实验程序下载到DE2运行。
实验注意事项:去抖动三、程序代码module lib22(out1,out2,clk,rst,key);output [6:0] out1,out2;input clk,rst;input key;reg [19:0]count;reg [7:0]in;reg [6:0]out1,out2;reg C,K;reg [9:0] r1;always@(posedge clk)if(count==20'd5000)beginC=~C;count<=1'b0;endelsecount=count+1'b1;always @ (posedge C)beginif(r1<10'd1000)beginK<=1'b0;r1<=r1+1'b1;endelsebeginK<=1'b1;r1<=1'b0;endendalways @ (posedge C,negedge rst) if(!rst)in<=1'b0;else if(!K)beginin=in+8'b1;endalways @ (in[3:0])case(in[3:0])4'b0000:out1=7'b1000000;4'b0001:out1=7'b1111001;4'b0010:out1=7'b0100100;4'b0011:out1=7'b0110000;4'b0100:out1=7'b0011001;4'b0101:out1=7'b0010010;4'b0110:out1=7'b0000010;4'b0111:out1=7'b1011000;4'b1000:out1=7'b0000000;4'b1001:out1=7'b0010000;4'b1010:out1=7'b0001000;4'b1011:out1=7'b0000011;4'b1100:out1=7'b1000110;4'b1101:out1=7'b1100001;4'b1110:out1=7'b0000110;4'b1111:out1=7'b0001110;default:out1=7'b1111111; endcasealways @ (in[7:4])case(in[7:4])4'b0000:out2=7'b1000000;4'b0001:out2=7'b1111001;4'b0010:out2=7'b0100100;4'b0011:out2=7'b0110000;4'b0100:out2=7'b0011001;4'b0101:out2=7'b0010010;4'b0110:out2=7'b0000010;4'b0111:out2=7'b1011000;4'b1000:out2=7'b0000000;4'b1001:out2=7'b0010000;4'b1010:out2=7'b0001000;4'b1011:out2=7'b0000011;4'b1100:out2=7'b1000110;4'b1101:out2=7'b1100001;4'b1110:out2=7'b0000110;4'b1111:out2=7'b0001110;default:out2=7'b1111111; endcaseendmodule四、实验原理图:DE2按键电路图五、实验总结与分析:1.不加去斗时,出现的结果不稳定,不同的DE2板子结果不一样,在加上去斗时,实验结果很稳定;2.去斗可以是检测抖动阶段也可以是不抖动阶段;3.实验二包含了实验一的一些内容,例如数码管的显示,但是加了去抖动程序,使结果更加的稳定。
verilog计数器代码
verilog计数器代码
Verilog语言可以用于编写数字逻辑电路的描述,包括计数器。
下面是一个简单的4位同步计数器的Verilog代码示例:
verilog.
module counter(。
input wire clk, // 时钟输入。
input wire rst, // 复位输入。
output reg [3:0] count // 4位计数器输出。
);
always @(posedge clk or posedge rst) begin.
if (rst) begin.
count <= 4'b0000; // 复位时计数器清零。
end else begin.
count <= count + 1; // 每个时钟周期计数器加1。
end.
end.
endmodule.
在这个例子中,我们定义了一个名为`counter`的模块,它有一
个时钟输入`clk`和一个复位输入`rst`,以及一个4位的计数器输
出`count`。
在`always`块中,我们使用了时钟的上升沿来触发计数
器的增加操作,并且在复位信号为高电平时将计数器清零。
这只是一个简单的示例,实际的计数器可能会更复杂,具体取
决于所需的功能和性能要求。
希望这个示例能够帮助你开始编写Verilog计数器的代码。
基于Verilog的简单计算器设计
module alu4(input wire [3:0]alusel,input wire [3:0]a,input wire [3:0]b,output reg nf, //令标志位output reg zf, //负标志位output reg cf, //进位标志output reg ovf, //溢出位标志output reg [7:0]y,output reg [3:0]rem //余数);reg [4:0]temp;reg [7:0]pv;reg [7:0]dp;integer i;reg [1:0]remL;reg [1:0]quotL;always@(*)beginy=0;rem=0;cf=0;ovf=0;nf=0;temp=5'b00000;case(alusel)4'b0001:y=a; //传递4'b0010: //加法begintemp={1'b0,a}+{1'b0,b};y=temp[3:0];cf=temp[4];ovf=y[3]^a[3]^b[3]^cf;end4'b0011: //减法1begintemp={1'b0,a}-{1'b0,b};y=temp[3:0];cf=temp[4];ovf=y[3]^a[3]^b[3]^cf;end4'b0100: //减法二begintemp={1'b0,b}-{1'b0,a};y=temp[3:0];cf=temp[4];ovf=y[3]^a[3]^b[3]^cf;end4'b0101: //乘法beginpv=8'b00000000;dp={4'b0000,b};for (i=0;i<=3;i=i+1)beginif(a[i]==1)pv=pv+dp;dp={dp[6:0],1'b0};endy=pv;end4'b0110:div({1'b0,b[3:0]},a,y,rem); //除法14'b0111:div({1'b0,a[3:0]},b,y,rem); //除法24'b1000:y=~a; //非4'b1001:y=a&b; //与4'b1010:y=a|b; //或4'b1011:y=a^b; //异或4'b1100:y={a[2:0],1'b0}; //左移1位4'b1101:y={a[2:0],a[3]}; //循环左移1位4'b1110:y={a[0],a[3:1]}; //循环右移1位4'b1111:y={a[3],a[3:1]}; //算数右移1位default:y=a;endcasenf=y[3];if(y==4'b0000)zf=1;elsezf=0;if(y>=10)cf=1;elsecf=0;if(y>99)ovf=1;elseovf=0;endtask div( //定义除法input wire[3:0]numerator,input [3:0]denom,output [3:0]y,output [3:0]rem);beginreg [7:0]numer;reg [4:0]d;reg [4:0]n1;reg [3:0]n2;beginnumer={4'b0000,numerator};d={1'b0,denom};n2=b;n1={1'b0,numer[7:4]};repeat(4)beginn1={n1[3:0],n2[3]};n2={n2[2:0],1'b0};if(n1>=d)beginn1=n1-d;n2[0]=1;endendy=n2;rem=n1[3:0];endendendtaskbinbcd B(.a(a), //调用BCD码模块,元件例化.b(b),.y(y),.rem(rem),);Endmodulemodule binbcd( //将二进制转换成BCD码input wire [3:0]a,input wire [3:0]b,input wire [3:0]rem,input wire [3:0]y,output reg [7:0]p,output wire [4:0]q,output wire [4:0]n,output wire [4:0]m);assign n[4]=a[3]&a[2]|a[3]&a[1];assign n[3]=a[3]&~a[2]&~a[1];assign n[2]=~a[3]&a[2]|a[2]&a[1];assign n[1]=a[3]&a[2]&~y[1]|~y[3]&y[1];assign n[0]=a[0];assign m[4]=b[3]&b[2]|b[3]&b[1];assign m[3]=b[3]&~b[2]&~b[1];assign m[2]=~b[3]&b[2]|b[2]&b[1];assign m[1]=b[3]&b[2]&~b[1]|~b[3]&b[1];assign m[0]=b[0];assign q[4]=rem[3]&rem[2]|rem[3]&rem[1];assign q[3]=rem[3]&~rem[2]&~rem[1];assign q[2]=~rem[3]&rem[2]|rem[2]&rem[1]; assign q[1]=rem[3]&rem[2]&~rem[1]|~rem[3]&rem[1]; assign q[0]=rem[0];reg[17:0]z;integer j;always @(*)beginfor (j=0;j<=17;j=j+1)z[j]=0;z[10:3]=y;repeat(5)beginif(z[11:8]>4)z[11:8]=z[11:8]+3;if(z[15:12]>4)z[15:12]=z[15:12]+3;z[17:1]=z[16:0];endp=z[17:0];endendmodule。
用verilog语言设计简单计算器
目录第一章设计任务及要求 (1)1.1课程设计依据 (1)1.2课程设计内容 (1)1.3课程设计要求 (1)第二章设计思路 (1)2.1设计原理 (1)2.1.1计算器原理 (1)2.1.2数码管显示原理 (2)2.1.3 8位扫描原理 (2)2.2设计总体框图 (3)第三章设计源序及分析 (3)3.1计算器模块 (3)3.1.1计算器源程序 (3)3.1.2模块分析 (4)3.2数码管显示模块 (4)3.2.1数码管源程序 (4)3.2.2模块分析 (5)3.3循环扫描模块 (5)3.3.1循环扫描程序 (5)3.3.2模块分析 (6)3.4总程序 (6)3.4.1总体源程序 (6)3.4.2程序分析 (8)第四章序仿真结果及分析 (9)4.1计算器设计仿真及分析 (9)4.2数码管仿真图及分析 (9)4.3总体仿真图 (10)第五章结果验证 (11)5.1实验结果及分析 (11)第六章心得体会 (11)第一章设计任务及要求1.1课程设计依据在掌握常用数字电路功能和原理的基础上,根据EDA技术课程所学知识,利用硬件描述语言Verilog HDL、EDA软件Quartus II和硬件平台Cyclone/Cyclone II FPGA进行电路系统的设计。
1.2课程设计内容设计一个简单计算器,输入为8位二进制数,分别用两位数码管显示,输出的计算结果为16位二进制数,并用四位数码管显示,能够实现+、-、 *、/ 四种运算,其中除法的结果显示分为商和余数两部分,分别用两位数码管显示。
1.3课程设计要求1、要求独立完成设计任务。
2、课程设计说明书封面格式要求见《天津城市建设学院课程设计教学规范》附表1。
3、课程设计的说明书要求简洁、通顺,计算正确,图纸表达内容完整、清楚、规范。
4、测试要求:根据题目的特点,采用相应的时序仿真或者在实验系统上观察结果。
5、课程设计说明书要求:1)说明题目的设计原理和思路、采用方法及设计流程。
Verilog机组实验计数器
计数器+ALU实验
实验内容
1、ALU实现及仿真
2、计数器实现及仿真
3、ALU+计数器综合实现及仿真
实验原理
1、A LU实现及仿真
使用Verilog HDL代码编程方式构建ALU181元件符号,生成ALU模块。
主要步骤:
(1)建立工程(注意工程名字和文件夹名字一致)
(2)编辑ALU181.v文件,并生成元件符号
(3)建立原理图文件,调用该元件符号
(4)编译
(5)波形仿真(不需引脚绑定)
2、计数器实现及仿真
(1)设计计数器Counter元件。
通过.v文件构建元件符号Counter,生成计数器。
(2)进行波形仿真
(3)进行引脚绑定,下载到实验箱进行验证。
3、ALU+计数器综合实现及仿真
(1)设计计数器Counter元件。
通过.v文件构建元件符号Counter,生成计数器(2)设计ALU元件。
通过.v文件构建元件符号ALU181
(3)计数器产生的信号S[3..0]作为ALU中S[3..0]的输入信号。
实验中程序运行结果及截图
实验心得
通过这次实验的学习。
我们了解到了ALU和计数器的基本原理,通过自己动手实验,进一步了解了其基本结构在实际实验中是怎样发挥作用的。
在实验的过程中,我和小组成员互相配合,共同摸索,虽然几经失败,但是最后在老师的帮助下发现了错误,并且加以改正,最后成功做出了实验,完成了一个简单的ALU+计数器。
在此过程中,增强了动手能力,加深了理解,增进了友谊,是一次不可多得的宝贵的实验经历。
VerilogHDL简单计算器设计-文档
目录第一章设计目的及任务要求 (1)1.1 设计目的 (1)1.2 设计任务 (1)1.3 课设要求 (1)第二章设计思路 (1)2.1 设计总体框图 (1)2.2 设计原理 (1)2.2.1 计算其原理 (1)2.2.2 数码显示原理 (2)2.2.3 八位数码管扫描的原理 (2)第三章设计源程序及分析 (2)3.1 计算器模块 (2)3.1.1 计算器源程序 (2)3.1.2 计算器程序分析 (2)3.2 数码管显示部分 (3)3.2.1 数码管显示源程序 (3)3.2.2 数码管显示程序分析 (4)3.3 循环扫描模块 (4)3.3.1 循环扫描程序 (4)3.3.2 循环程序分析 (5)3.4 总程序及其分析 (5)第四章时序仿真和结果验证 (8)4.1 计算器时序仿真及其分析 (8)4.2 数码管时序仿真及分析 (8)4.3 总体时序仿真图 (8)4.4 结果验证 (8)第五章心得体会 (9)第一章设计目的及任务要求1.1 设计目的(1)进一步加强熟练EDA基础知识。
(2)熟练掌握Quartus 6.0软件的使用以及用该软件编程和仿真的全过程。
(3)培养独立思考问题,解决问题的能力以及查阅相关资料和资料的正确使用能力,为明年的毕业设计打下良好的设计基础。
1.2 设计任务设计一个简单计算器,输入为8位二进制数,分别用两位数码管显示,输出的计算结果为16位二进制数,并用四位数码管显示,能够实现+、-、 *、/ 四种运算,其中除法的结果显示分为商和余数两部分,分别用两位数码管显示。
1.3 课设要求(1)说明题目的设计原理和思路、采用方法及设计流程。
(2)系统框图、Verilog语言设计程序或原理图。
(3)对各子模块的功能以及各子模块之间的关系做较详细的描述。
(4)详细说明调试方法和调试过程。
(5)说明测试结果:仿真时序图和结果显示图,并对其进行说明和分析。
第二章设计思路2.1 设计总体框图有分析可知,本次课程设计可以分成五个木块来实现相应的功能,分别是输入模块,计算模块,扫描模块,输出模块以及显示模块。
用verilog语言设计四位简单计算器
用verilog语言设计四位简单计算器module jsq(clk,keyin,keyout,leda,ledb,num3);input clk;input [3:0]keyin;output [3:0]keyout;reg [3:0]keyout;output [3:0]leda;reg [3:0]leda;output [3:0]ledb;reg [3:0]ledb;integer clk_klv;output [31:0]num3;always @(posedge clk) //分频clk_klv=clk_klv+1;reg [1:0]keyhang=0; //按键扫描reg [3:0]keynum=0; //最近按键的值reg keyen=0; //按键锁定作用,每次都必须重新按下才有效reg keysign=0; //当前按键的属性,0代表数字,1代表 +-*/=复位reg [7:0]delay=0; //按键消抖reg order2=0; //作用:延迟一个时钟,keyen跳变输出,确保keynum 被赋值always @(posedge clk_klv[10])beginif(order2==0)begincase({keyhang,keyin})6'b00_1110: begin delay=0;if(keyen==0)begin keysign=0;keynum=4'h0;order2=1;end endkeysign=0;keynum=4'h1;order2=1;end end6'b00_1011: begin delay=0;if(keyen==0)begin keysign=0;keynum=4'h2;order2=1;end end6'b00_0111: begin delay=0;if(keyen==0)begin keysign=0;keynum=4'h3;order2=1;end end6'b01_1110: begin delay=0;if(keyen==0)begin keysign=0;keynum=4'h4;order2=1;end end6'b01_1101: begin delay=0;if(keyen==0)begin keysign=0;keynum=4'h5;order2=1;end end6'b01_1011: begin delay=0;if(keyen==0)begin keysign=0;keynum=4'h6;order2=1;end end6'b01_0111: begin delay=0;if(keyen==0)begin keysign=0;keynum=4'h7;order2=1;end end6'b10_1110: begin delay=0;if(keyen==0)begin keysign=0;keynum=4'h8;order2=1;end end6'b10_1101: begin delay=0;if(keyen==0)begin keysign=0;keynum=4'h9;order2=1;end end6'b10_1011: begin delay=0;if(keyen==0)begin keysign=1;keynum=4'ha;order2=1;end endkeysign=1;keynum=4'hb;order2=1;end end6'b11_1110: begin delay=0;if(keyen==0)begin keysign=1;keynum=4'hc;order2=1;end end6'b11_1101: begin delay=0;if(keyen==0)begin keysign=1;keynum=4'hd;order2=1;end end6'b11_1011: begin delay=0;if(keyen==0)begin keysign=1;keynum=4'he;order2=1;end end6'b11_0111: begin delay=0;if(keyen==0)begin keysign=1;keynum=4'hf;order2=1;end enddefault: beginkeyhang=keyhang+1;delay=delay+1;if(delay>=100)keyen= 0;endendcasecase(keyhang)0:keyout=4'b1110;1:keyout=4'b1101;2:keyout=4'b1011;3:keyout=4'b0111;endcaseendelsebegin keyen=1;order2=0;endendreg [2:0]order=0; //当前状态integer num1=0,num2=0,num3=0; //第一个,第二个,结果reg [3:0]sign; //+-*/reg [7:0]lednum=100; //显示的数字reg [3:0]in_num=0; //限制显示的数字位,限制在2为:0~99 always @(posedge keyen)begincase(order)0: if(keysign) begin sign[3:0]=keynum[3:0];order=order+1; in_num=0;end //在没有按下+-*/之前会存储数字elseif(num1<10000)begin num1=num1*10+keynum;lednum=num1;in_num=in_num+1; end1: if(keysign) begincase(sign)//在没有按下=号之前会存储数字4'ha:num3=num1+num2;4'hb:num3=num1-num2;4'hc:num3=num1*num2;4'hd:num3=num1/num2;endcaselednum=num3+0;order=order+1;endelse if(num2<10000)begin num2=num2*10;num2=num2+keynum;lednum=num2;in_num=in_num+1; endendcaseif(keynum==4'hf)beginorder=0;num1=0;num2=0;num3=0;lednum=100;end //复位endalways @(*) //显示函数if(lednum<=99)beginleda=lednum/10;ledb=lednum%10;endelsebeginleda=15;ledb=15;endendmodule。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
module alu4(
input wire [3:0]alusel,
input wire [3:0]a,
input wire [3:0]b,
output reg nf, //令标志位output reg zf, //负标志位output reg cf, //进位标志output reg ovf, //溢出位标志output reg [7:0]y,
output reg [3:0]rem //余数
);
reg [4:0]temp;
reg [7:0]pv;
reg [7:0]dp;
integer i;
reg [1:0]remL;
reg [1:0]quotL;
always@(*)
begin
y=0;
rem=0;
cf=0;
ovf=0;
nf=0;
temp=5'b00000;
case(alusel)
4'b0001:y=a; //传递
4'b0010: //加法
begin
temp={1'b0,a}+{1'b0,b};
y=temp[3:0];
cf=temp[4];
ovf=y[3]^a[3]^b[3]^cf;
end
4'b0011: //减法1
begin
temp={1'b0,a}-{1'b0,b};
y=temp[3:0];
cf=temp[4];
ovf=y[3]^a[3]^b[3]^cf;
end
4'b0100: //减法二
begin
temp={1'b0,b}-{1'b0,a};
y=temp[3:0];
cf=temp[4];
ovf=y[3]^a[3]^b[3]^cf;
end
4'b0101: //乘法
begin
pv=8'b00000000;
dp={4'b0000,b};
for (i=0;i<=3;i=i+1)
begin
if(a[i]==1)
pv=pv+dp;
dp={dp[6:0],1'b0};
end
y=pv;
end
4'b0110:div({1'b0,b[3:0]},a,y,rem); //除法1
4'b0111:div({1'b0,a[3:0]},b,y,rem); //除法2
4'b1000:y=~a; //非
4'b1001:y=a&b; //与
4'b1010:y=a|b; //或
4'b1011:y=a^b; //异或
4'b1100:y={a[2:0],1'b0}; //左移1位
4'b1101:y={a[2:0],a[3]}; //循环左移1位
4'b1110:y={a[0],a[3:1]}; //循环右移1位
4'b1111:y={a[3],a[3:1]}; //算数右移1位
default:y=a;
endcase
nf=y[3];
if(y==4'b0000)
zf=1;
else
zf=0;
if(y>=10)
cf=1;
else
cf=0;
if(y>99)
ovf=1;
else
ovf=0;
end
task div( //定义除法
input wire[3:0]numerator,
input [3:0]denom,
output [3:0]y,
output [3:0]rem
);
begin
reg [7:0]numer;
reg [4:0]d;
reg [4:0]n1;
reg [3:0]n2;
begin
numer={4'b0000,numerator};
d={1'b0,denom};
n2=b;
n1={1'b0,numer[7:4]};
repeat(4)
begin
n1={n1[3:0],n2[3]};
n2={n2[2:0],1'b0};
if(n1>=d)
begin
n1=n1-d;
n2[0]=1;
end
end
y=n2;
rem=n1[3:0];
end
end
endtask
binbcd B(.a(a), //调用BCD码模块,元件例化.b(b),
.y(y),
.rem(rem),
);
Endmodule
module binbcd( //将二进制转换成BCD码input wire [3:0]a,
input wire [3:0]b,
input wire [3:0]rem,
input wire [3:0]y,
output reg [7:0]p,
output wire [4:0]q,
output wire [4:0]n,
output wire [4:0]m
);
assign n[4]=a[3]&a[2]|a[3]&a[1];
assign n[3]=a[3]&~a[2]&~a[1];
assign n[2]=~a[3]&a[2]|a[2]&a[1];
assign n[1]=a[3]&a[2]&~y[1]|~y[3]&y[1];
assign n[0]=a[0];
assign m[4]=b[3]&b[2]|b[3]&b[1];
assign m[3]=b[3]&~b[2]&~b[1];
assign m[2]=~b[3]&b[2]|b[2]&b[1];
assign m[1]=b[3]&b[2]&~b[1]|~b[3]&b[1];
assign m[0]=b[0];
assign q[4]=rem[3]&rem[2]|rem[3]&rem[1];
assign q[3]=rem[3]&~rem[2]&~rem[1];
assign q[2]=~rem[3]&rem[2]|rem[2]&rem[1]; assign q[1]=rem[3]&rem[2]&~rem[1]|~rem[3]&rem[1]; assign q[0]=rem[0];
reg[17:0]z;
integer j;
always @(*)
begin
for (j=0;j<=17;j=j+1)
z[j]=0;
z[10:3]=y;
repeat(5)
begin
if(z[11:8]>4)
z[11:8]=z[11:8]+3;
if(z[15:12]>4)
z[15:12]=z[15:12]+3;
z[17:1]=z[16:0];
end
p=z[17:0];
end
endmodule。