欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

简单4个8位存储器读写verilog实现

程序员文章站 2022-04-06 23:34:34
...

本文主要思路是建立一个4个8位寄存器,然后在顶层文件中对这四个寄存器写入数值,最后在四个存储器中读取数值。
其模块框图如下:

下面是verilog代码实现:
(1)存储器模块

module device_regs(clk,reset,data_in,data_adr,wr_en,rd_en,read_data);
input clk,reset;
input wr_en, rd_en;
input [7:0] data_in;
input [1:0] data_adr;
output [7:0] read_data;
reg [7:0] reg0,reg1,reg2,reg3;
wire [7:0] reg0_nxt,reg1_nxt,reg2_nxt,reg3_nxt;
reg[7:0] read_data,read_data_nxt;
wire reg_match0,reg_match1,reg_match2,reg_match3;

assign reg_match0 = (data_adr == 2'b00);
assign reg_match1 = (data_adr == 2'b01);
assign reg_match2 = (data_adr == 2'b10);
assign reg_match3 = (data_adr == 2'b11);

assign reg0_nxt = (reg_match0&&wr_en)? data_in:reg0;
assign reg1_nxt = (reg_match0&&wr_en)? data_in:reg1;
assign reg2_nxt = (reg_match0&&wr_en)? data_in:reg2;
assign reg3_nxt = (reg_match0&&wr_en)? data_in:reg3;

aaa@qq.com(posedge clk or negedge reset)begin
 if(!reset)begin
  reg0 <= 'd0;
  reg1 <= 'd0;
  reg2 <= 'd0;
  reg3 <= 'd0;
  read_data <= 4'b0000;
 end
 else begin
  reg0 <= reg0_nxt;
  reg1 <= reg1_nxt;
  reg2 <= reg2_nxt;
  reg3 <= reg3_nxt;
  read_data <= read_data_nxt;
 end
end

aaa@qq.com(*) begin
 read_data_nxt = read_data;
 if(rd_en)begin
 case(1'b1)
  reg_match0:read_data_nxt = reg0;
  reg_match1:read_data_nxt = reg1;
  reg_match2:read_data_nxt = reg2;
  reg_match3:read_data_nxt = reg3;
 endcase
 end
end

endmodule

(2)测试文件,包括读写任务

`timescale 1ns/1ns
module testbench_top();
reg[1:0] address_tb;
reg[7:0] wrdata_tb;
wire[7:0] rddata_tb;
reg wr_en_tb,rd_en_tb;
reg clk_tb;
reg reset_tb;

parameter CLKTB_HALF_PERIOD = 5;
parameter RST_DEASSERT_DELAY = 100;
parameter REG0_OFFSET = 2'b00,
 REG1_OFFSET = 2'b01,
 REG2_OFFSET = 2'b10,
 REG3_OFFSET = 2'b11;
 
initial begin
 clk_tb = 0;
 forever #CLKTB_HALF_PERIOD clk_tb = ~clk_tb;
end
//generate clk
initial begin
reset_tb = 1'b0;
#RST_DEASSERT_DELAY reset_tb= 1'b1;

end
//generate reset
initial begin
address_tb = 2'b00;
wrdata_tb = 'h0;
wr_en_tb = 1'b0;
rd_en_tb = 1'b0;
end
//initialize varible
device_regs             device_regs_tb
   (.clk(clk_tb),
   .reset(reset_tb),
   .data_in(wrdata_tb),
   .data_adr(address_tb),
   .wr_en(wr_en_tb),
   .rd_en(rd_en_tb),
   .read_data(rddata_tb));
//module example

task reg_write;
 input [1:0] address_in;
 input [7:0] data_in;
 begin
  @(posedge clk_tb);
   #1 address_tb = address_in;
  @(posedge clk_tb);
   #1 wr_en_tb = 1'b1;
      wrdata_tb = data_in;
  @(posedge clk_tb);
   #1;
      address_tb = 2'b11;
      wr_en_tb = 1'b0;
      wrdata_tb = 8'h00;
 end
endtask
//task write

task reg_read;
 input address_in;
 input expected_data;
 begin
  @(posedge clk_tb)
   #1 address_tb = address_in;
  @(posedge clk_tb)
   #1 rd_en_tb = 1'b1;
  @(posedge clk_tb)
   #1 rd_en_tb = 1'b0;
      address_tb = 2'b11;
  @(posedge clk_tb);
   $display("expected_data = %h,actual_data = %h",expected_data,rddata_tb);
 end
endtask
//task read

initial begin
 #1000;
 reg_write(REG0_OFFSET,8'hA5);
 reg_read(REG0_OFFSET,8'hA5);
 reg_write(REG0_OFFSET,8'hA6);
 reg_read(REG0_OFFSET,8'hA6);
 reg_write(REG0_OFFSET,8'hA7);
 reg_read(REG0_OFFSET,8'hA7);
 reg_write(REG0_OFFSET,8'hA8);
 reg_read(REG0_OFFSET,8'hA8);
end

endmodule 

其仿真结果如下:
简单4个8位存储器读写verilog实现
可以看到写入的A5,A6,A7,A8数据都读了出来
简单4个8位存储器读写verilog实现
这是控制栏的显示

相关标签: verilog 储存器