基于verilog的直接相联cache

cache控制器

//直接相联cache,cache大小为32块,主存大小为1024块,1块=4字,1字=32bit
//主存地址为12位,其中[1:0]是块内偏移,[6:2]是索引,[11:7]是Tag
//cache V+D+Tag+Data=1+1+5+128=135

module cache(
input clk,
input rst,
//cpu<->cache
input [11:0]cpu_req_addr,
input cpu_req_rw,
input cpu_req_valid,
input [31:0]cpu_data_write,
output reg [31:0]cpu_data_read,
output reg cpu_ready,
//cache<->memory
output reg [11:0]mem_req_addr,
output reg mem_req_rw,
output reg mem_req_valid,
output reg [127:0]mem_data_write,
input [127:0]mem_data_read,
input mem_ready
);

parameter V = 134;
parameter D = 133;
parameter TagMSB = 132;
parameter TagLSB = 128;
parameter BlockMSB = 127;
parameter BlockLSB = 0 ;

parameter IDLE=0;
parameter CompareTag=1;
parameter Allocate=2;
parameter WriteBack=3;

reg [134:0] cache_data[0:31];           //134:V,133:D,[132:128]:TAG,[127:0]DATA
reg [1:0]state,next_state;
reg hit;

wire [4:0]cpu_req_index;
wire [4:0]cpu_req_tag;
wire [1:0]cpu_req_offset;

assign cpu_req_offset=cpu_req_addr[1:0];
assign cpu_req_index=cpu_req_addr[6:2];
assign cpu_req_tag=cpu_req_addr[11:7];

integer i;
//初始化cache
initial
begin
    for(i=0;i<32;i=i+1)
        cache_data[i]=135'd0;
end

always@(posedge clk,posedge rst)
if(rst)
    state<=IDLE;
else
    state<=next_state;
//
always@(*)
case(state)
    IDLE:if(cpu_req_valid)
            next_state=CompareTag;
         else
            next_state=IDLE;
    CompareTag:if(hit)
                   next_state=IDLE;
               else if(cache_data[cpu_req_index][V:D]==2'b11)               //if the block is valid and dirty then go to WriteBack
                   next_state=WriteBack;
               else 
                   next_state=Allocate;
    Allocate:if(mem_ready)
                   next_state=CompareTag;
             else
                   next_state=Allocate;
    WriteBack:if(mem_ready)
                   next_state=Allocate;
              else
                   next_state=WriteBack;
      default:next_state=IDLE;
endcase

always@(*)
if(state==CompareTag)
    if(cache_data[cpu_req_index][134]&&cache_data[cpu_req_index][TagMSB:TagLSB]==cpu_req_tag)
        hit=1'b1;
    else
        hit=1'b0;

always@(posedge clk)
if(state==Allocate)                 //read new block from memory to cache
    if(!mem_ready)
    begin
        mem_req_addr<={
    
    cpu_req_addr[11:2],2'b00};
        mem_req_rw<=1'b0;
        mem_req_valid<=1'b1; 
    end
    else
    begin
        mem_req_valid<=1'b0;
        cache_data[cpu_req_index][BlockMSB:BlockLSB]<=mem_data_read;
        cache_data[cpu_req_index][V:D]<=2'b10;
        cache_data[cpu_req_index][TagMSB:TagLSB]<=cpu_req_tag;
    end
else if(state==WriteBack)                          //write dirty block to memory
    if(!mem_ready)
    begin
        mem_req_addr<={
    
    cache_data[cpu_req_index][TagMSB:TagLSB],cpu_req_index,2'b00};
        mem_req_rw<=1'b1;
        mem_data_write<=cache_data[cpu_req_index][BlockMSB:BlockLSB];
        mem_req_valid<=1'b1;
    end
    else
    begin
        mem_req_valid<=1'b0;
    end
else
begin
    mem_req_valid=1'b0;
end

always@(posedge clk)
if(state==CompareTag&&hit)
    if(cpu_req_rw==1'b0)              //read hit
    begin
        cpu_ready<=1'b1;
        cpu_data_read<=cache_data[cpu_req_index][cpu_req_offset*32 +:32];
    end
    else                               //write hit,置脏位为1
    begin
        cpu_ready<=1'b1;
        cache_data[cpu_req_index][cpu_req_offset*32 +:32]=cpu_data_write;
        cache_data[cpu_req_index][D]=1'b1;
    end
else
    cpu_ready<=1'b0;

endmodule

主存文件mem.v

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2020/08/20 14:24:27
// Design Name: 
// Module Name: mem
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module mem(
input clk,
input rst,
input [11:0]mem_req_addr,                        //[1:0]块内地址
input mem_req_rw,
input mem_req_valid,
input [127:0]mem_data_write,
output reg [127:0]mem_data_read,
output reg mem_ready
    );

reg [31:0] mem [0:4095];                 //4096个字,1024个块

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

always@(posedge clk,posedge rst)
if(rst)
    mem_ready<=1'b0;
else if(mem_req_valid&&mem_req_rw==1'b1&&!mem_ready)                      //write
begin
    mem[mem_req_addr+3]=mem_data_write[127:96];
    mem[mem_req_addr+2]=mem_data_write[95:64];
    mem[mem_req_addr+1]=mem_data_write[63:32];
    mem[mem_req_addr]=mem_data_write[31:0];
    mem_ready<=1'b1;
end
else if(mem_req_valid&&mem_req_rw==1'b0&&!mem_ready)                      //read
begin
    mem_data_read={
    
    mem[mem_req_addr+3],mem[mem_req_addr+2],mem[mem_req_addr+1],mem[mem_req_addr]};
    mem_ready<=1'b1;
end
else if(mem_req_valid&&mem_ready)
    mem_ready<=1'b0;

endmodule

仿真文件

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2020/08/20 15:25:17
// Design Name: 
// Module Name: test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module test(

    );
parameter WriteMiss=0;
parameter WriteHit=1;
parameter ReadHit=2;
parameter ReadMiss=3;
parameter WriteDirtyMiss=4;
parameter ReadDirtyMiss=5;

reg clk;
reg rst;

reg [3:0]state,next_state;

reg [11:0]cpu_req_addr;
reg cpu_req_rw;
reg cpu_req_valid;
reg [31:0]cpu_data_write;
wire [31:0]cpu_data_read;
wire cpu_ready;

wire [11:0]mem_req_addr;
wire mem_req_rw;
wire mem_req_valid;
wire [127:0]mem_data_write;
wire [127:0]mem_data_read;
wire mem_ready;

initial
begin
    clk=0;
    forever
    #5 clk=~clk;
end
initial
begin
    rst=1;
    #10
    rst=0;
end

always@(posedge clk,posedge rst)
if(rst)
   state<=WriteMiss;
else
   state<=next_state;

always@(*)
case(state)
    WriteMiss:if(cpu_ready)
              begin
                  next_state=WriteHit;
                  cpu_req_valid=1'b0;
              end
              else
                  next_state=WriteMiss;
    WriteHit:if(cpu_ready)
             begin
                 next_state=ReadMiss;
                 cpu_req_valid=1'b0;
             end
             else
                 next_state=WriteHit;
    ReadMiss:if(cpu_ready)
             begin
                 next_state=ReadHit;
                 cpu_req_valid=1'b0;
             end
             else
                 next_state=ReadMiss;
    ReadHit:if(cpu_ready)
            begin
                next_state=WriteDirtyMiss;
                cpu_req_valid=1'b0;
            end
            else
                next_state=ReadHit;
    WriteDirtyMiss:if(cpu_ready)
                    begin
                        next_state=ReadDirtyMiss;
                        cpu_req_valid=1'b0;
                    end
                   else
                       next_state=WriteDirtyMiss;
    ReadDirtyMiss:next_state=ReadDirtyMiss;
    default:next_state=WriteMiss;
endcase

always@(posedge clk,posedge rst)
if(rst)
begin
    cpu_req_rw<=1'b0;
    cpu_req_addr<=21'd0;
    cpu_req_valid<=1'b0;
    cpu_data_write<=32'd0;
end
else
case(state)
    WriteMiss:begin
              cpu_req_rw<=1'b1;
              cpu_req_addr<=12'd0;
              cpu_data_write<=32'd8;
              cpu_req_valid<=1'b1;
              end
    WriteHit:begin
              cpu_req_rw<=1'b1;
              cpu_req_addr<=12'd0;
              cpu_data_write<=32'd9;
              cpu_req_valid<=1'b1;
             end
    ReadMiss:begin
              cpu_req_rw<=1'b0;
              cpu_req_addr<=12'd4;
              cpu_data_write<=cpu_data_write;
              cpu_req_valid<=1'b1;
            end
    ReadHit:begin
              cpu_req_rw<=1'b0;
              cpu_req_addr<=12'd0;
              cpu_data_write<=cpu_data_write;
              cpu_req_valid<=1'b1;
            end
    WriteDirtyMiss:begin
                       cpu_req_valid<=1'b1;
                       cpu_req_rw<=1'b1;
                       cpu_data_write<=32'd6;
                       cpu_req_addr<=32'd128;
                   end
    ReadDirtyMiss:begin
                       cpu_req_valid<=1'b1;
                       cpu_req_rw<=1'b0;
                       cpu_req_addr<=32'd0;
                       cpu_data_write<=cpu_data_write;
                  end
    default:begin
              cpu_req_rw<=1'b1;
              cpu_req_addr<=12'd0;
              cpu_data_write<=32'd8;
              cpu_req_valid<=1'b0;
            end
endcase


cache U1(.clk(clk),
.rst(rst),
.cpu_req_addr(cpu_req_addr),
.cpu_req_rw(cpu_req_rw),
.cpu_req_valid(cpu_req_valid),
.cpu_data_write(cpu_data_write),
.cpu_data_read(cpu_data_read),
.cpu_ready(cpu_ready),
//***********************//
.mem_req_addr(mem_req_addr),
.mem_req_rw(mem_req_rw),
.mem_req_valid(mem_req_valid),
.mem_data_write(mem_data_write),
.mem_data_read(mem_data_read),
.mem_ready(mem_ready));

mem U2(.clk(clk),
.rst(rst),
.mem_req_addr(mem_req_addr),
.mem_req_rw(mem_req_rw),
.mem_req_valid(mem_req_valid),
.mem_data_write(mem_data_write),
.mem_data_read(mem_data_read),
.mem_ready(mem_ready));

endmodule

猜你喜欢

转载自blog.csdn.net/qq_40268672/article/details/108130329
今日推荐