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

📄 leg_tb.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 testbench .                                       ////
////                                                             ////
////                                                             ////
/////////////////////////////////////////////////////////////////////
////                                                             ////
//// Change log:                                                 ////
////                                                             ////
/////////////////////////////////////////////////////////////////////

`include "leg_define.v"
module leg_mem(
        i_cache_data,
        d_cache_data,
        i_addr,
        d_addr,
        i_read,
        d_dataout,
        d_re,
        d_we,
        clk,
        rst
        );

input   [31:0]  i_addr;
input   [31:0]  d_addr;
output  [31:0]  i_cache_data;
output  [31:0]  d_cache_data;
input   [31:0]  d_dataout;
input           clk;
input           i_read;
input           d_re;
input           d_we;
input           rst;


reg     [31:0]  mem [131071:0];
reg     [31:0]  i_cache_data;
reg     [31:0]  d_cache_data_r;
wire    [15:0]  i_caddr;
assign          i_caddr = i_addr[17:2];
reg     [63:0]  temp_mem [31:0];
integer         cache_index;
integer         stop;
wire    [63:0]  temp_rdata = temp_mem[cache_index[4:0]];
wire    [63:0]  temp_wdata = {d_addr,d_dataout};

wire            cache_re = (d_re && d_addr[31:18])? 1'b1 : 1'b0;
wire            cache_we = (d_we && d_addr[31:18])? 1'b1 : 1'b0;
wire    [31:0]  cache_data_out;

reg             cache_red;
reg             cache_wed;

always@(posedge clk or posedge rst)
begin
        if (rst)
                i_cache_data <= 32'h0;
        else begin
                if (i_read)
                        i_cache_data <= mem[i_caddr];
        end
end

always@(posedge clk or posedge rst)
begin
        if (rst) begin
                d_cache_data_r <=  32'h00000000;
        end
        else begin
                if (d_re && !cache_re) begin
                        d_cache_data_r <=  mem[d_addr[17:2]];
                end
        end
end

always@(posedge clk)
begin
        if (d_we && !cache_we) begin
                mem[d_addr] <= d_dataout;
        end
end



assign          d_cache_data = (cache_red) ? cache_data_out : d_cache_data_r;

always@(posedge clk or posedge rst)
begin
        if (rst) begin
                cache_red <= 1'b0;
                cache_wed <= 1'b0;
        end
        else begin
                cache_red <= cache_re;
                cache_wed <= cache_we;
        end
end

leg_dcache      high_cache(
        //to cpu
        .d_address(d_addr),
        .d_wait(),
        .d_re(cache_re),
        .d_we(cache_we),
        .d_datain(d_dataout),
        .d_dataout(cache_data_out),
        .d_be(4'b1111),
        //to coprocessor
        .dc_control,
        //to mem bus
        .ADR_O(),
        .DAT_I(32'h0),
        .DAT_O(),
        .STB_O(),
        .CYC_O(),
        .ACK_I(4'b0),
        .SEL_O(),
        .TGD_I(4'b0),
        .TGD_O(),
        .WE_O(),       
        //system
        .clk(clk),
        .rst(rst)
        );


/*
                if (d_addr[31:18]) begin  
                        //search for the right place to put data
                        for (cache_index = 0; cache_index < 64; cache_index = cache_index + 1)
                        begin
                                if (cache_index == 0) begin
                                        stop =0;
                                end
                                //first round, try to find the best match addr
                                if (temp_rdata[63:32] == d_addr && cache_index <= 31) begin//find last addr
                                        temp_mem[cache_index][31:0] <= d_dataout;
                                        $display("----------------now write high address %h, hit", d_addr);
                                end
                                else if (cache_index >= 32) begin      //then at next round, find the first blank item
                                        if (stop == 0 && temp_rdata[63:32] ==0) begin
                                                temp_mem[cache_index[4:0]] <= temp_wdata;
                                                stop = 1;
                                                $display("----------------now write high address %h, miss", d_addr);
                                        end
                                end
                        end  
                        
                end
                else 
                
      //FOR ADDRESS > MEMORY ,use temporary space instead
                        if (d_addr[31:18]) begin
                                for (cache_index = 0; cache_index < 32; cache_index = cache_index + 1) 
                                begin
                                        if (temp_rdata[63:32] == d_addr) begin//find last addr
                                                d_cache_data <= temp_rdata[31:0];
                                                //cache_index = 0;
                                                $display("----------------now read high address %h, hit", d_addr);
                                        end
                                end
                        end
                        else           
                
*/

//simple i cache simluation model 
initial begin
i_cache_data =0;
        $readmemh("inst_code.txt", mem);
for (cache_index = 0; cache_index < 32; cache_index = cache_index + 1) 
begin
        temp_mem[cache_index] = 64'h0;
end
stop =0;
cache_index = 0;
end


endmodule



module leg_tb;

reg             clk;
reg             rst;
//data path
wire    [1:0]  d_irq;
wire            d_re;
wire            d_we;
wire    [31:0]  d_addr;
wire    [31:0]  d_datain;
wire    [31:0]  d_dataout;
wire            d_wait;
wire    [3:0]   d_be;
//instr path
wire    [31:0]  i_addr;
wire            i_read;
wire            i_wait = 1'b0;


initial
begin
#0        clk =0;
          #10  forever   #10 clk = ~clk;
end

initial
begin
        rst =0;
          #10 rst = 1;
          #100 rst = 0;
          #5000_0000 $stop;
end

wire    [31:0]  d_cache_data;
wire    [31:0]  i_cache_data;

reg     mem_rst;
initial
begin
        mem_rst =0;
          #10 mem_rst = 1;
          #20 mem_rst = 0;
end

leg     leg_top(
              //data path
                .d_irq(2'b0),
                .d_re(d_re),
                .d_we(d_we),
                .d_addr(d_addr),
                .d_datain(d_cache_data),
                .d_dataout(d_dataout),
                .d_wait(1'b0),
                .d_be(d_be),
              //instr path
                .i_datain(i_cache_data),
                .i_addr(i_addr),
                .i_read(i_read),
                .i_wait(1'b0),
              //system
                .clk(clk),
                .rst(rst)
              );
           
wire    clk_mem;
assign  clk_mem = clk;
leg_mem mem_inst(
        .i_cache_data(i_cache_data),
        .d_cache_data(d_cache_data),
        .i_addr(i_addr),
        .d_addr(d_addr),
        .d_dataout(d_dataout),
        .d_re(d_re),
        .d_we(d_we),
        .i_read(i_read),
        .clk(clk_mem),
        .rst(rst)
        );
        
        
//always@(posedge clk)
//begin
//        if (d_re)
//                $display("%d: info------ now read addr %h" ,$time, d_addr);
//        if (d_we)
//                $display("%d: info------ now write %h to addr %h", $time, d_dataout, d_addr );
//end

endmodule

⌨️ 快捷键说明

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