存储器及读写模块设计实现
一、设计及实现功能
本设计存储模块总容量2KB,位宽32bit,考虑到节省功耗,将存储空间划分为2块memory实现,每块存储器1KB即256*32bit大小的存储块。2块memory依次编址
存储器读写模块需要实现的功能如下:
二、信号接口定义
存储器读写模块的接口如下:
memory模块1KB存储器规模为256*32bit,其接口及功能定义如下:
三、设计时序图
四、代码设计
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仿真结果如下: