📄 leg_tb.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 + -