硬件语言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/1ns
module 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)
begin
if(~rst_n)
begin
second <=0;
flag <=0;
end
else
begin
if(second == 6'd60 && flag == 1'b0)
begin
second <=1;
end
else if(flag == 1'b0)
begin
second <= second + 1;
end
end
end
always@(posedge clk or negedge rst_n)
begin
if(~rst_n)
begin
minute <=0;
end
else
begin
if(second == 6'd60)
begin
minute <= minute+1;
end
else if(minute ==6'd60)
begin
second <=0;
flag <=1;
end
end
end
endmodule
2.VL51 可置位计数器
1.题目:
请编写一个十六进制计数器模块,计数器输出信号递增每次到达0,给出指示信号zero,当置位信号set 有效时,将当前输出置为输入的数值set_num。
2.解题思路
2.1 注意置位信号,当置位信号为 1 的时候 计数信号从 置位信号开始。
2.2 注意 zero 信号的输出。
3.解题代码
`timescale 1ns/1ns
module 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)
begin
if(~rst_n)
begin
cnt <=0;
end
else
begin
if(cnt == 4'd15 && set== 1'b0)
begin
cnt <=0;
end
else if(set == 1'b0)
begin
cnt <= cnt+1;
end
else if(set == 1'b1)
begin
cnt <= set_num;
end
end
end
always@(posedge clk or negedge rst_n)
begin
if(~rst_n)
begin
zero <=0;
end
else
begin
if(cnt == 1'b0)
begin
zero <=1;
end
else
begin
zero <=0;
end
end
end
always@(posedge clk or negedge rst_n)
begin
if(~rst_n)
begin
number <=0;
end
else
begin
number <=cnt;
end
end
endmodule
3.VL52 加减计数器
1.题目:
请编写一个十进制计数器模块,当mode信号为1,计数器输出信号递增,当mode信号为0,计数器输出信号递减。每次到达0,给出指示信号zero。
模块的接口信号图如下:
2.解题思路
2.1 条件判断 计数的加减。
3.解题代码
`timescale 1ns/1ns
module 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)
begin
if(~rst_n)
begin
cnt <=0;
end
else
begin
if(mode == 1'b1)
begin
if(cnt == 4'd9)
begin
cnt <=0;
end
else
begin
cnt <= cnt+1;
end
end
else if(mode == 1'b0)
begin
if(cnt == 4'd0)
begin
cnt <=4'd9;
end
else
begin
cnt <= cnt-1;
end
end
end
end
always@(posedge clk or negedge rst_n)
begin
if(~rst_n)
begin
zero <=0;
end
else
begin
if(cnt == 4'd0)
begin
zero <=1;
end
else
begin
zero <=0;
end
end
end
always@(posedge clk or negedge rst_n)
begin
if(~rst_n)
begin
number <=0;
end
else
begin
number <=cnt;
end
end
endmodule
4.VL53 单端口RAM
1.题目:
设计一个单端口RAM,它有: 写接口,读接口,地址接口,时钟接口和复位;存储宽度是4位,深度128。注意rst为低电平复位
2.解题思路,
2.1 当 enb =1 根据addr 把 wr_data 输入数据到寄存器。
2.2 当 enb =0 根据 addr 把寄存器里面的数据输出。
3.解题代码
`timescale 1ns/1ns
module 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)
begin
if(~rst)
begin
for(i=0;i<=127;i=i+1)
begin
data[i]= 4'd0;
end
end
else
begin
if(enb == 1'b1)
begin
data[addr] <= w_data;
end
end
end
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)
begin
if(~rst_n)
begin
for(i=0;i<=7;i=i+1)
begin
data[i] <=4'd0;
end
end
else
begin
if(write_en == 1'b1)
begin
data[write_addr] <= write_data;
end
end
end
always@(posedge clk or negedge rst_n)
begin
if(~rst_n)
begin
read_data <=0;
end
else
begin
if(read_en == 1'b1)
begin
read_data <= data[read_addr];
end
else
begin
read_data <= 4'd0;
end
end
end
endmodule