2KB存储器及读写模块verilog实现

存储器及读写模块设计实现


一、设计及实现功能

    本设计存储模块总容量2KB,位宽32bit,考虑到节省功耗,将存储空间划分为2块memory实现,每块存储器1KB即256*32bit大小的存储块。2块memory依次编址

在这里插入图片描述
存储器读写模块需要实现的功能如下:
在这里插入图片描述

二、信号接口定义

存储器读写模块的接口如下:
在这里插入图片描述
memory模块1KB存储器规模为256*32bit,其接口及功能定义如下:
在这里插入图片描述

三、设计时序图

## 1.引入库

在这里插入图片描述

四、代码设计

mem模块设计:

//-----------------
//Designer:Liang Genyuan
//Project:mem模块设计
//-----------------
module mem( clk,
            cen,
            wen,
            bwen,
            a,
            d,
            q);

input clk;
input cen;
input wen;
input[31:0]bwen;
input[7:0]a;
input[31:0]d;
output[31:0]q;
reg [31:0]  q;

reg [31:0]mem[255:0];    //1KB memory;

always@ (posedge clk)begin
    if(cen==1)begin
        q<=32'b0000_0000;
    end
    else if(wen==1)begin
        q<=mem[a];
    end
    else begin
        q<=32'h0000_0000;
	 end
end

integer i;
	initial begin
	    for(i=0; i<256;i=i+1) begin
	        mem[i] = 32'h0000_0000;
	    end
	end

always@(posedge clk)begin
    if((cen==0)&&(wen==0))begin
        mem[a][0]<=bwen[0]?d[0]:mem[a][0];
        mem[a][1]<=bwen[1]?d[1]:mem[a][1];
        mem[a][2]<=bwen[2]?d[2]:mem[a][2];
        mem[a][3]<=bwen[3]?d[3]:mem[a][3];
        mem[a][4]<=bwen[4]?d[4]:mem[a][4];
        mem[a][5]<=bwen[5]?d[5]:mem[a][5];
        mem[a][6]<=bwen[6]?d[6]:mem[a][6];
        mem[a][7]<=bwen[7]?d[7]:mem[a][7];
        mem[a][8]<=bwen[8]?d[8]:mem[a][8];
        mem[a][9]<=bwen[9]?d[9]:mem[a][9];
        mem[a][10]<=bwen[10]?d[10]:mem[a][10];
        mem[a][11]<=bwen[11]?d[11]:mem[a][11];
        mem[a][12]<=bwen[12]?d[12]:mem[a][12];
        mem[a][13]<=bwen[13]?d[13]:mem[a][13];
        mem[a][14]<=bwen[14]?d[14]:mem[a][14];
        mem[a][15]<=bwen[15]?d[15]:mem[a][15];
        mem[a][16]<=bwen[16]?d[16]:mem[a][16];
        mem[a][17]<=bwen[17]?d[17]:mem[a][17];
        mem[a][18]<=bwen[18]?d[18]:mem[a][18];
        mem[a][19]<=bwen[19]?d[19]:mem[a][19];
        mem[a][20]<=bwen[20]?d[20]:mem[a][20];
        mem[a][21]<=bwen[21]?d[21]:mem[a][21];
        mem[a][22]<=bwen[22]?d[22]:mem[a][22];
        mem[a][23]<=bwen[23]?d[23]:mem[a][23];
        mem[a][24]<=bwen[24]?d[24]:mem[a][24];
        mem[a][25]<=bwen[25]?d[25]:mem[a][25];
        mem[a][26]<=bwen[26]?d[26]:mem[a][26];
        mem[a][27]<=bwen[27]?d[27]:mem[a][27];
        mem[a][28]<=bwen[28]?d[28]:mem[a][28];
        mem[a][29]<=bwen[29]?d[29]:mem[a][29];
        mem[a][30]<=bwen[30]?d[30]:mem[a][30];
        mem[a][31]<=bwen[31]?d[31]:mem[a][31];
    end
end

endmodule

memory读写模块模块设计:

//-----------------
//Designer:Liang Genyuan
//Project:存储器读写模块
//-----------------
module memory (clk,
					nrst,
					stall,
					op_code,
					rwaddr,
					wdata,
					rdata);
input clk;
input nrst;
input stall;
input [2:0]  op_code;
input [10:0] rwaddr;
input [31:0] wdata;
output[31:0] rdata;

reg [31:0]rdata;
wire [31:0]q_1;       //q_1,q_2为两个寄存器上输出信号
wire [31:0]q_2;
reg [31:0]q_all;         //q_all为从q_1,q_2中选择出的信号
reg [31:0]d_1;
reg [31:0]d_2;
reg [31:0]d_all;        //d_all为从wdata得到的信号,再经过选择信号输给对应mem
reg [31:0]bwen;
reg       wen;
wire      cen_1;
wire      cen_2;

//read operation:
//Load Byte=000
//Load half word=001
//Load word=010

//write operation:
//Store Byte=100
//Store half word=101
//Store word=111

 mem  mem1( .clk (clk),
            .cen (cen_1),
            .wen (wen),
            .bwen(bwen),
            .a   (rwaddr[9:2]),
            .d   (d_1),
            .q   (q_1)
			 );

 mem  mem2( .clk (clk),
            .cen (cen_2),
            .wen (wen),
            .bwen(bwen),
            .a   (rwaddr[9:2]),
            .d   (d_2),
            .q   (q_2)
			 );


always@(*)begin
    if(op_code==3'b100)begin
        bwen=32'h0000_0011;
    end
    else if(op_code==3'b101)begin
        bwen=32'h0000_1111;
    end
    else if(op_code==3'b111)begin
        bwen=32'h1111_1111;
    end
    else begin
        bwen=32'h0000_0000;
    end
end
always@(posedge clk or negedge nrst) begin
	if(!nrst)begin
		rdata<=32'b0;
	end
	else begin
    case(op_code)
    	3'b000:begin//load_byte
					case(rwaddr[1:0])
        			2'b00:rdata<={{24{q_all[7]}},{q_all[7:0]}};
        			2'b01:rdata<={{24{q_all[15]}},{q_all[15:8]}};
        			2'b10:rdata<={{24{q_all[23]}},{q_all[23:16]}};
        			2'b11:rdata<={{24{q_all[31]}},{q_all[31:24]}};
					endcase
				 end
    	3'b001:begin//load_halfword
        		if (rwaddr[1]==0) 
					rdata <={{16{q_all[15]}},q_all[15:0]};	 
        		else 		
					rdata <={{16{q_all[31]}},q_all[31:16]};
				 end
    	3'b010:begin//load word
        	      rdata <= q_all;
				 end
	 endcase
	end
end
	
				 
always@(posedge clk or negedge nrst) begin
	if(!nrst)begin
		d_all<=32'b0;
	end
	else begin
		case(op_code)
		3'b100:begin//store byte
					case(rwaddr[1:0])
					2'b00:d_all[7:0]  <=wdata[7:0];
					2'b01:d_all[15:8] <=wdata[7:0];
					2'b10:d_all[23:15]<=wdata[7:0];
					2'b11:d_all[31:24]<=wdata[7:0];
					endcase
				 end
		3'b101:begin//store half byte
					if(rwaddr[1]==0)
						d_all[15:0]<=wdata[15:0];
					else
						d_all[31:16]<=wdata[15:0];
				end
		3'b111:begin//store word
					d_all<=wdata;
				 end
	   default:d_all<=32'h00000000;
		endcase
	end
end



always@(posedge clk or negedge nrst)begin        
    if(!nrst)begin
		  q_all<=32'h00000000;
	 end
	 else begin
		if(rwaddr[10]==0)begin      //rwaddr[10]=0选择第一片memory,rwaddr[10]=1选择第二片memory
			q_all<=q_1;
		end
		else begin
			q_all<=q_2;
		end
	 end
end

always@(posedge clk or negedge nrst)begin        
    if(!nrst)begin
        d_1<=32'h00000000;
		  d_2<=32'h00000000;
	 end
	 else begin
		if(rwaddr[10]==0)begin      //rwaddr[10]=0选择第一片memory,rwaddr[10]=1选择第二片memory
			d_1<=d_all;
		end
		else begin
			d_2<=d_all;
		end
	 end
end

assign cen_1=rwaddr[10]?1:0;    //rwaddr[10]=0选中cen_1,rwaddr[10]=1选中cen_2
assign cen_2=rwaddr[10]?0:1;

always@(*)begin
	if(stall)begin   //stall为1时不进行读写操作,
		wen=1;
	end
	else begin
		wen=~op_code[2];
	end
end
endmodule

五、仿真测试

测试文件编写如下:

`timescale 1 ps/ 1 ps
module memory_vlg_tst();
reg clk;
reg nrst;
reg [2:0] op_code;
reg [13:0] rwaddr;
reg stall;
reg [31:0] wdata;                                              
wire [31:0]  rdata;

// assign statements (if any)                          
memory i1 (
// port map - connection between master ports and signals/registers   
	.clk(clk),
	.nrst(nrst),
	.op_code(op_code),
	.rdata(rdata),
	.rwaddr(rwaddr),
	.stall(stall),
	.wdata(wdata)
);

parameter CYCLE=20;

initial                                                
begin                                                  
#10;
clk=0;
nrst=1;
#10;
clk=1;
nrst=0;
#10;
clk=0;
nrst=1;
forever
#(CYCLE/2)
clk=~clk;
end                                                    

initial begin
    #20;
    op_code=3'b111;
    rwaddr=11'b01_1111111_00;
    stall=0;
    wdata=32'h0000_0001;
    #100;
    op_code=3'b010;
    rwaddr=11'b01_1111111_00;
    stall=0;
    wdata=32'h0000_0000;
    #100;
    op_code=3'b100;
    rwaddr=11'b11_1111110_00;
    stall=0;
    wdata=32'h0000_1111;
    #100;
    op_code=3'b000;
    rwaddr=11'b11_1111110_00;
    stall=0;
    wdata=32'h000_0001;
    #100;
    op_code=3'b101;
    rwaddr=11'b01_1111111_00;
    stall=0;
    wdata=32'h0000_1111;
    #100;
    op_code=3'b001;
    rwaddr=11'b01_1111111_00;
    stall=0;
    wdata=32'h0000_1110;
    #100;
    op_code=3'b001;
    rwaddr=11'b01_1111111_00;
    stall=1;
    wdata=32'h0000_1100;
end

endmodule

modelsim仿真结果如下:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

俩个圆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值