⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 leg_icache.v

📁 verilog hdl编写,六段流水线CPU.程序完整
💻 V
字号:
/////////////////////////////////////////////////////////////////////
////                                                             ////
////  LEG cpu core                                               ////
////                                                             ////
////  This file is part of the LEG FPGA SOC project              ////
////                                                             ////
////                                                             ////
////  To Do:                                                     ////
////   - make it smaller and faster                              ////
////   - rewrite the register file and data path                 ////
////  Author(s):                                                 ////
////      - Alex Li, Alexli8055@hotmail.com                      ////
////                                                             ////
/////////////////////////////////////////////////////////////////////
////                                                             ////
//// Copyright (C) 2006-2007 Li datou                            ////
////                         Alexli8055@hotmail.com              ////
////                                                             ////
////                                                             ////
//// This source file may be used and distributed freely without ////
//// restriction provided that this copyright statement is not   ////
//// removed from the file and any derivative work contains the  ////
//// original copyright notice and the associated disclaimer.    ////
////                                                             ////
//// ARM, the ARM Powered logo, Thumb, and StrongARM are         ////
//// registerd trademarks of ARM Limited, this core is simply    ////
//// build for fun, please do not use for commerical propose     ////
////                                                             ////
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
////                                                             ////
/////////////////////////////////////////////////////////////////////
////                                                             ////
//// Date of Creation: 2006.11.28                                ////
////                                                             ////
//// Version: 0.0.1                                              ////
////                                                             ////
////  Description                                                ////
////  leg core instruction cache module.                         ////
////                                                             ////
////                                                             ////
/////////////////////////////////////////////////////////////////////
////                                                             ////
//// Change log:                                                 ////
////                                                             ////
/////////////////////////////////////////////////////////////////////

`include "leg_define.v"
//very simple data cache, need to be refined further
module leg_icache(
        //to cpu
        i_address,
        i_dataout,
        i_read,
        i_wait,
        //to coprocessor
        ic_control,
        //to mem bus
        ADR_O,
        DAT_I,
        STB_O,
        CYC_O,
        ACK_I,
        SEL_O,
        TGD_I,
        TGD_O,   
        WE_O,    
        //system
        clk,
        rst
        );

parameter       IDLE            = 4'b0001;
parameter       HIT_DETECT      = 4'b0010;
parameter       RELOAD_1        = 4'b0100;
parameter       RELOAD_2        = 4'b1000;

//total 4kB inst cache, implemented in 8 m4k

input   [31:0]  i_address;
output  [31:0]  i_dataout;
output          i_wait;
input           i_read;
input           ic_control;

//wishbone master interface
output  [31:0]  ADR_O;
input   [31:0]  DAT_I;  //system data bus is 32 bit
output  [3:0]   SEL_O;
output          STB_O;
output          CYC_O;
input           ACK_I;
input   [3:0]   TGD_I;  //DQM IN
output  [3:0]   TGD_O;  //DQM OUT
output          WE_O;
input           clk;
input           rst;


reg             i_read_d;
reg     [3:0]   i_cache_state;
reg     [31:0]  i_addr_d;
//reg     [8:0]   i_mem_waddr;
wire            i_tag_hit;
reg     [1:0]   send_counter;
reg     [1:0]   receive_counter;     
reg             mem_read;           
wire            receive_valid;
wire            i_wait;

//
wire    [09:0]  i_cache_mem_raddr;
wire    [31:0]  i_cache_mem_rdata;
wire    [09:0]  i_cache_mem_waddr;
wire    [31:0]  i_cache_mem_wdata;
wire            i_cache_mem_we;

wire    [07:0]  i_cache_tag_raddr;
wire    [19:0]  i_cache_tag_rdata;
wire    [07:0]  i_cache_tag_waddr;
wire    [19:0]  i_cache_tag_wdata;
wire            i_cache_tag_we;


//total 4k i cache memory
//32 bit address
//31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04   03   02  01 00
//---------------------tag field-----------------------------|--------tag addr--------|line addr|------
//hit or miss
assign          i_tag_hit = (i_addr_d[31:12] == i_cache_tag_rdata) ? 1'b1 : 1'b0;

assign          i_cache_mem_wdata = DAT_I;
assign          i_cache_mem_waddr = {i_addr_d[11:04],receive_counter};
assign          i_cache_mem_raddr = (i_cache_state == RELOAD_2)? i_addr_d[11:02] : i_address[11:02];
assign          receive_valid     = (TGD_I == 4'b1111)? 1'b1 : 1'b0;
assign          i_cache_mem_we    = receive_valid;


assign          i_cache_tag_raddr = i_address[11:04];
assign          i_cache_tag_waddr = i_addr_d[11:04];
assign          i_cache_tag_we    = (i_cache_state == RELOAD_1 && i_read_d)? 1'b1 : 1'b0;
assign          i_cache_tag_wdata = i_addr_d[31:12];

//if the received data is the one that cpu need, foward to cpu directly
wire            received_foward;
assign          received_foward = (receive_valid && i_addr_d[03:02] == receive_counter) ? 1'b1 : 1'b0;
assign          i_dataout = i_cache_mem_rdata;
//assign          i_dataout = (received_foward)? DAT_I : i_cache_mem_rdata;
assign          i_wait = ((i_tag_hit == 1'b0 && i_cache_state == HIT_DETECT) || i_cache_state == RELOAD_1 || i_cache_state == RELOAD_2) ? 1'b1 : 1'b0;
//assign          i_wait = ((!i_tag_hit && i_cache_state == HIT_DETECT) || (i_cache_state == RELOAD_1 && !received_foward) || (i_cache_state == RELOAD_2 && !received_foward))? 1'b1 : 1'b0;
//wishbone if
assign          ADR_O = {i_addr_d[31:04],send_counter,2'b00};
assign          CYC_O = (i_cache_state == RELOAD_1)? 1'b1 : 1'b0;
assign          STB_O = (i_cache_state == RELOAD_1)? 1'b1 : 1'b0;
assign          SEL_O = 4'b1111;        //i cache always expects a word from memory
assign          WE_O  = 1'b0;           //always read ,no write operation 

always@(posedge clk or posedge rst)
begin
        if (rst) begin
                i_read_d <= 1'h0;
        end
        else begin
                if (!i_wait)
                        i_read_d <= i_read; 
        end
end


//keep the input address 
always@(posedge clk or posedge rst)
begin
        if (rst) begin
                i_addr_d <= 32'h0;
        end
        else begin
                if (!i_wait)
                        i_addr_d <= i_address; 
        end
end

//i cache fsm

always@(posedge clk or posedge rst)
begin
        if (rst) begin
                i_cache_state <= IDLE;
                send_counter <= 2'b00;
                receive_counter <= 2'b00;     
                mem_read <= 1'b0;           
        end
        else begin
                case(i_cache_state)
                IDLE: begin
                        if (i_read) begin
                                i_cache_state <= HIT_DETECT;
                        end
                end
                HIT_DETECT: begin
                        if (!i_tag_hit && i_read_d) begin       //hit miss
                                i_cache_state <= RELOAD_1;
                                mem_read <= 1'b1;
                                send_counter <= 2'b00;
                                receive_counter <= 2'b00;
                        end
                end
                RELOAD_1: begin
                        //send 4 memory request, burst
                        if (send_counter == 2'b11) begin
                                i_cache_state <= RELOAD_2;
                                mem_read <= 1'b0;
                        end
                        else
                                send_counter <= send_counter + 2'b01;
                        //get received data, if can
                        if (receive_valid)
                                receive_counter <= receive_counter + 2'b01;
                end
                RELOAD_2: begin
                        if (receive_counter == 2'b11) begin
                                i_cache_state <= HIT_DETECT;
                                send_counter <= 2'b00;
                                receive_counter <= 2'b00;
                        end
                        else if (receive_valid)
                                receive_counter <= receive_counter + 2'b01;
                end
                //other case
                default: begin
                        i_cache_state <= IDLE;
                        send_counter <= 2'b00;
                        receive_counter <= 2'b00;     
                        mem_read <= 1'b0;  
                end
                endcase
        end
end

//cache memory instance
leg_dpram_syn   i_cache_mem(
                        .raddr(i_cache_mem_raddr),
                        .rdata(i_cache_mem_rdata),
                        .waddr(i_cache_mem_waddr),
                        .wdata(i_cache_mem_wdata),
                        .re(1'b1),
                        .we(i_cache_mem_we),
                        .clk(clk),
                        .rst(rst)
                        );
defparam        i_cache_mem.AW = 10;    //1024 WORD, TOTAL 4K BYTES, 8 m4k
defparam        i_cache_mem.DW = 32;    //32 bit inst

//cache tag instance
//no flag at this simple implementation
leg_dpram_syn   i_cache_tag(
                        .raddr(i_cache_tag_raddr),
                        .rdata(i_cache_tag_rdata),
                        .waddr(i_cache_tag_waddr),
                        .wdata(i_cache_tag_wdata),
                        .re(1'b1),
                        .we(i_cache_tag_we),
                        .clk(clk),
                        .rst(rst)
                        );
defparam        i_cache_tag.AW = 8;     //256 WORD, TOTAL 512 ENTRY
defparam        i_cache_tag.DW = 20;    //20 bit, total 2 m4k



endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -