硬件语言Verilog HDL牛客刷题day07 计数器与存储器部分
1.VL50 简易秒表
1.题目:
请编写一个模块,实现简易秒表的功能:具有两个输出,当输出端口second从1-60循环计数,每当second计数到60,输出端口minute加一,一直到minute=60,暂停计数。
2.解题思路
2.1注意时序 分钟的 第一个计数1 是在 秒计数 60 的下一个周期上,而不是 正好60 同一个周期所以我们的判断是 , second == 60 ?
2.2 注意当 minute ==60 之后不在计数。 所以需要一个标志位。
3.解题代码
`timescale 1ns/1nsmodule count_module(input clk,input rst_n,output reg [5:0]second,output reg [5:0]minute);
reg flag;//开始结束判断位
always@(posedge clk or negedge rst_n)beginif(~rst_n)beginsecond <=0; flag <=0;endelsebeginif(second == 6'd60 && flag == 1'b0)beginsecond <=1;endelse if(flag == 1'b0)beginsecond <= second + 1;endend end always@(posedge clk or negedge rst_n)beginif(~rst_n)beginminute <=0;endelsebeginif(second == 6'd60)beginminute <= minute+1;endelse if(minute ==6'd60)beginsecond <=0;flag <=1;endendendendmodule
2.VL51 可置位计数器
1.题目:
请编写一个十六进制计数器模块,计数器输出信号递增每次到达0,给出指示信号zero,当置位信号set 有效时,将当前输出置为输入的数值set_num。
2.解题思路
2.1 注意置位信号,当置位信号为 1 的时候 计数信号从 置位信号开始。
2.2 注意 zero 信号的输出。
3.解题代码
`timescale 1ns/1nsmodule count_module(input clk,input rst_n,input set,input [3:0] set_num,output reg [3:0]number,output reg zero);
reg[3:0] cnt;
always@(posedge clk or negedge rst_n)beginif(~rst_n)begincnt <=0;endelse beginif(cnt == 4'd15 && set== 1'b0)begincnt <=0;endelse if(set == 1'b0)begincnt <= cnt+1;endelse if(set == 1'b1)begincnt <= set_num;endendendalways@(posedge clk or negedge rst_n)beginif(~rst_n)beginzero <=0;endelsebeginif(cnt == 1'b0)beginzero <=1;endelsebeginzero <=0;endendendalways@(posedge clk or negedge rst_n)beginif(~rst_n)beginnumber <=0;endelsebeginnumber <=cnt;endendendmodule
3.VL52 加减计数器
1.题目:
请编写一个十进制计数器模块,当mode信号为1,计数器输出信号递增,当mode信号为0,计数器输出信号递减。每次到达0,给出指示信号zero。
模块的接口信号图如下:
2.解题思路
2.1 条件判断 计数的加减。
3.解题代码
`timescale 1ns/1nsmodule count_module(input clk,input rst_n,input mode,output reg [3:0]number,output reg zero);
reg[3:0] cnt;always@(posedge clk or negedge rst_n)beginif(~rst_n)begincnt <=0;endelsebeginif(mode == 1'b1)beginif(cnt == 4'd9)begincnt <=0;endelsebegincnt <= cnt+1;endendelse if(mode == 1'b0)beginif(cnt == 4'd0)begincnt <=4'd9;endelsebegincnt <= cnt-1;endendendendalways@(posedge clk or negedge rst_n)beginif(~rst_n)beginzero <=0;endelsebeginif(cnt == 4'd0)beginzero <=1;endelsebeginzero <=0;endendendalways@(posedge clk or negedge rst_n)beginif(~rst_n)beginnumber <=0;endelsebeginnumber <=cnt;endendendmodule
4.VL53 单端口RAM
1.题目:
设计一个单端口RAM,它有: 写接口,读接口,地址接口,时钟接口和复位;存储宽度是4位,深度128。注意rst为低电平复位
2.解题思路,
2.1 当 enb =1 根据addr 把 wr_data 输入数据到寄存器。
2.2 当 enb =0 根据 addr 把寄存器里面的数据输出。
3.解题代码
`timescale 1ns/1nsmodule RAM_1port(input clk,input rst,input enb,input [6:0]addr,input [3:0]w_data,output wire [3:0]r_data
);
//*code*//reg[3:0] data[127:0];
integer i;
always@(posedge clk or negedge rst)beginif(~rst)beginfor(i=0;i<=127;i=i+1)begindata[i]= 4'd0;endendelsebeginif(enb == 1'b1)begindata[addr] <= w_data;endendend
assign r_data = (!enb) ? data[addr] : 1'b0;//*code*//
endmodule
5.VL54 RAM的简单实现
1.题目:
实现一个深度为8,位宽为4bit的双端口RAM,数据全部初始化为0000。具有两组端口,分别用于读数据和写数据,读写操作可以同时进行。当读数据指示信号read_en有效时,通过读地址信号read_addr读取相应位置的数据read_data,并输出;当写数据指示信号write_en有效时,通过写地址信号write_addr 和写数据write-data,向对应位置写入相应的数据。
程序的信号接口图如下:
时序图如下:
2.解题思路
2.1 根据对应的使能来 运行对应的功能。
3.解题代码
`timescale 1ns/1ns
module ram_mod(input clk,input rst_n,input write_en,input [7:0]write_addr,input [3:0]write_data,input read_en,input [7:0]read_addr,output reg [3:0]read_data
);reg[3:0] data[7:0];
integer i;
always@(posedge clk or negedge rst_n)beginif(~rst_n)beginfor(i=0;i<=7;i=i+1)begindata[i] <=4'd0;endendelsebeginif(write_en == 1'b1)begindata[write_addr] <= write_data;endendendalways@(posedge clk or negedge rst_n)beginif(~rst_n)beginread_data <=0;endelsebeginif(read_en == 1'b1)beginread_data <= data[read_addr];endelsebeginread_data <= 4'd0;endendend endmodule