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

Ebony ·
更新时间:2024-11-13
· 619 次阅读

本文主要思路是建立一个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; always@(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 always@(*) 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

其仿真结果如下:
在这里插入图片描述
可以看到写入的A5,A6,A7,A8数据都读了出来
在这里插入图片描述
这是控制栏的显示


作者:数字小白



存储器 存储

需要 登录 后方可回复, 如果你还没有账号请 注册新账号