牛客网Verilog刷题——VL54

牛客网Verilog刷题——VL54

  • 题目
  • 答案

题目

  实现一个深度为8,位宽为4bit的双端口RAM,数据全部初始化为0000。具有两组端口,分别用于读数据和写数据,读写操作可以同时进行。当读数据指示信号read_en有效时,通过读地址信号read_addr读取相应位置的数据read_data,并输出;当写数据指示信号write_en有效时,通过写地址信号write_addr 和写数据write_data,向对应位置写入相应的数据。
  模块的信号接口图如下:

牛客网Verilog刷题——VL54_第1张图片

  模块的时序图如下:

牛客网Verilog刷题——VL54_第2张图片

  输入输出描述。

信号 类型 输入/输出 位宽 描述
clk wire Input 1 系统时钟信号
rst_n wire Input 1 异步复位信号,低电平有效
read_en wire Input 1 读使能信号,高电平表示进行读操作
write_en wire Input 1 写使能信号,高电平表示进行写操作
read_addr wire Input 8 读地址
write_addr wire Input 8 写地址
write_data wire Input 4 写数据,在写使能信号拉高时,同时输入写数据
read_data reg Output 4 读数据

答案

  在题目中,并未指出数据的读写操作是同步的还是异步的,从题目中给出的时序图看,题目要求在读使能有效的该时钟内读出数据,比如在读使能read_en有效时,地址为0,立刻读出地址0中的数据1,地址为1,则立刻读出地址1中的数据2,可见时序图要求的是异步读,但是在程序中,我们设置为同步读,仿真也是通过的(个人觉得题目有问题,没有指出读写是同步还是异步,仿真也有问题)。

`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
);
integer i;
reg [3:0] mem [255:0];

//写操作
always @(posedge clk or negedge rst_n)
  if(!rst_n)
    for(i=0;i<256;i=i+1) begin
		mem[i] <= 'd0;
	end
  else if(write_en)
    mem[write_addr] <= write_data;

//同步读操作
always @(posedge clk or negedge rst_n) 
  if(!rst_n)
    read_data <= 'd0;
  else if(read_en)
    read_data <= mem[read_addr];
  else
    read_data <= 'd0;

//异步读操作
/*
always @(*) 
  if(read_en)
    read_data = mem[read_addr];
  else
    read_data = 'd0;
*/

endmodule

你可能感兴趣的:(牛客刷题,fpga开发,Verilog)