Co-authored-by: cxy004 <cxy004@qq.com>
Co-authored-by: Hooo1941 <Hooo1941@users.noreply.github.com>
This commit is contained in:
Paul Pan 2021-07-28 16:39:10 +08:00
parent 906eb052fa
commit ebcd281f4b
10 changed files with 1523 additions and 135 deletions

View File

@ -0,0 +1,751 @@
/*------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Copyright (c) 2016, Loongson Technology Corporation Limited.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. Neither the name of Loongson Technology Corporation Limited nor the names of
its contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL LOONGSON TECHNOLOGY CORPORATION LIMITED BE LIABLE
TO ANY PARTY FOR 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.
--------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
`timescale 1ns / 1ps
//*************************************************************************
// > File Name : soc_top.v
// > Description : SoC, included cpu, 2 x 3 bridge,
// inst ram, confreg, data ram
//
// -------------------------
// | cpu |
// -------------------------
// | axi
// |
// ---------------------
// | 1 x 2 bridge |
// ---------------------
// | |
// | |
// ----------- -----------
// | axi ram | | confreg |
// ----------- -----------
//
// > Author : LOONGSON
// > Date : 2017-08-04
//*************************************************************************
//for simulation:
//1. if define SIMU_USE_PLL = 1, will use clk_pll to generate cpu_clk/sys_clk,
// and simulation will be very slow.
//2. usually, please define SIMU_USE_PLL=0 to speed up simulation by assign
// cpu_clk=clk, sys_clk = clk.
// at this time, frequency of cpu_clk is 91MHz.
`define SIMU_USE_PLL 0 //set 0 to speed up simulation
module soc_axi_lite_top2 #(parameter SIMULATION=1'b0)
(
input resetn,
input clk,
//------gpio-------
output [15:0] led,
output [1 :0] led_rg0,
output [1 :0] led_rg1,
output [7 :0] num_csn,
output [6 :0] num_a_g,
input [7 :0] switch,
output [3 :0] btn_key_col,
input [3 :0] btn_key_row,
input [1 :0] btn_step
);
//debug signals
wire [31:0] debug_wb_pc;
wire [3 :0] debug_wb_rf_wen;
wire [4 :0] debug_wb_rf_wnum;
wire [31:0] debug_wb_rf_wdata;
wire [31:0] debug_wb1_pc;
wire [3 :0] debug_wb1_rf_wen;
wire [4 :0] debug_wb1_rf_wnum;
wire [31:0] debug_wb1_rf_wdata;
//clk and resetn
wire cpu_clk;
wire sys_clk;
reg cpu_resetn_t, cpu_resetn;
reg sys_resetn_t, sys_resetn;
always @(posedge cpu_clk)
begin
cpu_resetn_t <= resetn;
cpu_resetn <= cpu_resetn_t;
end
always @(posedge sys_clk)
begin
sys_resetn_t <= resetn;
sys_resetn <= sys_resetn_t;
end
//simulation clk.
reg clk_91m;
initial
begin
clk_91m = 1'b0;
end
always #5.5 clk_91m = ~clk_91m;
generate if(SIMULATION && `SIMU_USE_PLL==0)
begin: speedup_simulation
assign cpu_clk = clk_91m;
assign sys_clk = clk;
end
else
begin: pll
clk_pll clk_pll
(
.clk_in1 (clk ),
.cpu_clk (cpu_clk),
.sys_clk (sys_clk)
);
end
endgenerate
//cpu axi
wire [3 :0] cpu_arid ;
wire [31:0] cpu_araddr ;
wire [3 :0] cpu_arlen ;
wire [2 :0] cpu_arsize ;
wire [1 :0] cpu_arburst;
wire [1 :0] cpu_arlock ;
wire [3 :0] cpu_arcache;
wire [2 :0] cpu_arprot ;
wire cpu_arvalid;
wire cpu_arready;
wire [3 :0] cpu_rid ;
wire [31:0] cpu_rdata ;
wire [1 :0] cpu_rresp ;
wire cpu_rlast ;
wire cpu_rvalid ;
wire cpu_rready ;
wire [3 :0] cpu_awid ;
wire [31:0] cpu_awaddr ;
wire [3 :0] cpu_awlen ;
wire [2 :0] cpu_awsize ;
wire [1 :0] cpu_awburst;
wire [1 :0] cpu_awlock ;
wire [3 :0] cpu_awcache;
wire [2 :0] cpu_awprot ;
wire cpu_awvalid;
wire cpu_awready;
wire [3 :0] cpu_wid ;
wire [31:0] cpu_wdata ;
wire [3 :0] cpu_wstrb ;
wire cpu_wlast ;
wire cpu_wvalid ;
wire cpu_wready ;
wire [3 :0] cpu_bid ;
wire [1 :0] cpu_bresp ;
wire cpu_bvalid ;
wire cpu_bready ;
//cpu axi wrap
wire cpu_wrap_aclk ;
wire cpu_wrap_aresetn;
wire [3 :0] cpu_wrap_arid ;
wire [31:0] cpu_wrap_araddr ;
wire [3 :0] cpu_wrap_arlen ;
wire [2 :0] cpu_wrap_arsize ;
wire [1 :0] cpu_wrap_arburst;
wire [1 :0] cpu_wrap_arlock ;
wire [3 :0] cpu_wrap_arcache;
wire [2 :0] cpu_wrap_arprot ;
wire cpu_wrap_arvalid;
wire cpu_wrap_arready;
wire [3 :0] cpu_wrap_rid ;
wire [31:0] cpu_wrap_rdata ;
wire [1 :0] cpu_wrap_rresp ;
wire cpu_wrap_rlast ;
wire cpu_wrap_rvalid ;
wire cpu_wrap_rready ;
wire [3 :0] cpu_wrap_awid ;
wire [31:0] cpu_wrap_awaddr ;
wire [3 :0] cpu_wrap_awlen ;
wire [2 :0] cpu_wrap_awsize ;
wire [1 :0] cpu_wrap_awburst;
wire [1 :0] cpu_wrap_awlock ;
wire [3 :0] cpu_wrap_awcache;
wire [2 :0] cpu_wrap_awprot ;
wire cpu_wrap_awvalid;
wire cpu_wrap_awready;
wire [3 :0] cpu_wrap_wid ;
wire [31:0] cpu_wrap_wdata ;
wire [3 :0] cpu_wrap_wstrb ;
wire cpu_wrap_wlast ;
wire cpu_wrap_wvalid ;
wire cpu_wrap_wready ;
wire [3 :0] cpu_wrap_bid ;
wire [1 :0] cpu_wrap_bresp ;
wire cpu_wrap_bvalid ;
wire cpu_wrap_bready ;
//cpu axi sync
wire [3 :0] cpu_sync_arid ;
wire [31:0] cpu_sync_araddr ;
wire [3 :0] cpu_sync_arlen ;
wire [2 :0] cpu_sync_arsize ;
wire [1 :0] cpu_sync_arburst;
wire [1 :0] cpu_sync_arlock ;
wire [3 :0] cpu_sync_arcache;
wire [2 :0] cpu_sync_arprot ;
wire cpu_sync_arvalid;
wire cpu_sync_arready;
wire [3 :0] cpu_sync_rid ;
wire [31:0] cpu_sync_rdata ;
wire [1 :0] cpu_sync_rresp ;
wire cpu_sync_rlast ;
wire cpu_sync_rvalid ;
wire cpu_sync_rready ;
wire [3 :0] cpu_sync_awid ;
wire [31:0] cpu_sync_awaddr ;
wire [3 :0] cpu_sync_awlen ;
wire [2 :0] cpu_sync_awsize ;
wire [1 :0] cpu_sync_awburst;
wire [1 :0] cpu_sync_awlock ;
wire [3 :0] cpu_sync_awcache;
wire [2 :0] cpu_sync_awprot ;
wire cpu_sync_awvalid;
wire cpu_sync_awready;
wire [3 :0] cpu_sync_wid ;
wire [31:0] cpu_sync_wdata ;
wire [3 :0] cpu_sync_wstrb ;
wire cpu_sync_wlast ;
wire cpu_sync_wvalid ;
wire cpu_sync_wready ;
wire [3 :0] cpu_sync_bid ;
wire [1 :0] cpu_sync_bresp ;
wire cpu_sync_bvalid ;
wire cpu_sync_bready ;
//axi ram
wire [3 :0] ram_arid ;
wire [31:0] ram_araddr ;
wire [3 :0] ram_arlen ;
wire [2 :0] ram_arsize ;
wire [1 :0] ram_arburst;
wire [1 :0] ram_arlock ;
wire [3 :0] ram_arcache;
wire [2 :0] ram_arprot ;
wire ram_arvalid;
wire ram_arready;
wire [3 :0] ram_rid ;
wire [31:0] ram_rdata ;
wire [1 :0] ram_rresp ;
wire ram_rlast ;
wire ram_rvalid ;
wire ram_rready ;
wire [3 :0] ram_awid ;
wire [31:0] ram_awaddr ;
wire [3 :0] ram_awlen ;
wire [2 :0] ram_awsize ;
wire [1 :0] ram_awburst;
wire [1 :0] ram_awlock ;
wire [3 :0] ram_awcache;
wire [2 :0] ram_awprot ;
wire ram_awvalid;
wire ram_awready;
wire [3 :0] ram_wid ;
wire [31:0] ram_wdata ;
wire [3 :0] ram_wstrb ;
wire ram_wlast ;
wire ram_wvalid ;
wire ram_wready ;
wire [3 :0] ram_bid ;
wire [1 :0] ram_bresp ;
wire ram_bvalid ;
wire ram_bready ;
//conf
wire [3 :0] conf_arid ;
wire [31:0] conf_araddr ;
wire [3 :0] conf_arlen ;
wire [2 :0] conf_arsize ;
wire [1 :0] conf_arburst;
wire [1 :0] conf_arlock ;
wire [3 :0] conf_arcache;
wire [2 :0] conf_arprot ;
wire conf_arvalid;
wire conf_arready;
wire [3 :0] conf_rid ;
wire [31:0] conf_rdata ;
wire [1 :0] conf_rresp ;
wire conf_rlast ;
wire conf_rvalid ;
wire conf_rready ;
wire [3 :0] conf_awid ;
wire [31:0] conf_awaddr ;
wire [3 :0] conf_awlen ;
wire [2 :0] conf_awsize ;
wire [1 :0] conf_awburst;
wire [1 :0] conf_awlock ;
wire [3 :0] conf_awcache;
wire [2 :0] conf_awprot ;
wire conf_awvalid;
wire conf_awready;
wire [3 :0] conf_wid ;
wire [31:0] conf_wdata ;
wire [3 :0] conf_wstrb ;
wire conf_wlast ;
wire conf_wvalid ;
wire conf_wready ;
wire [3 :0] conf_bid ;
wire [1 :0] conf_bresp ;
wire conf_bvalid ;
wire conf_bready ;
//for lab6
wire [4 :0] ram_random_mask;
//cpu axi
//debug_*
mycpu_top u_cpu(
.ext_int (6'd0 ), //high active
.aclk (cpu_clk ),
.aresetn (cpu_resetn ), //low active
.arid (cpu_arid ),
.araddr (cpu_araddr ),
.arlen (cpu_arlen ),
.arsize (cpu_arsize ),
.arburst (cpu_arburst ),
.arlock (cpu_arlock ),
.arcache (cpu_arcache ),
.arprot (cpu_arprot ),
.arvalid (cpu_arvalid ),
.arready (cpu_arready ),
.rid (cpu_rid ),
.rdata (cpu_rdata ),
.rresp (cpu_rresp ),
.rlast (cpu_rlast ),
.rvalid (cpu_rvalid ),
.rready (cpu_rready ),
.awid (cpu_awid ),
.awaddr (cpu_awaddr ),
.awlen (cpu_awlen ),
.awsize (cpu_awsize ),
.awburst (cpu_awburst ),
.awlock (cpu_awlock ),
.awcache (cpu_awcache ),
.awprot (cpu_awprot ),
.awvalid (cpu_awvalid ),
.awready (cpu_awready ),
.wid (cpu_wid ),
.wdata (cpu_wdata ),
.wstrb (cpu_wstrb ),
.wlast (cpu_wlast ),
.wvalid (cpu_wvalid ),
.wready (cpu_wready ),
.bid (cpu_bid ),
.bresp (cpu_bresp ),
.bvalid (cpu_bvalid ),
.bready (cpu_bready ),
//debug interface 0
.debug_wb_pc (debug_wb_pc ),
.debug_wb_rf_wen (debug_wb_rf_wen ),
.debug_wb_rf_wnum (debug_wb_rf_wnum ),
.debug_wb_rf_wdata(debug_wb_rf_wdata),
//debug interface 1
.debug_wb1_pc (debug_wb1_pc ),
.debug_wb1_rf_wen (debug_wb1_rf_wen ),
.debug_wb1_rf_wnum (debug_wb1_rf_wnum ),
.debug_wb1_rf_wdata(debug_wb1_rf_wdata)
);
//cpu axi wrap
axi_wrap u_cpu_axi_wrap(
.m_aclk ( cpu_clk ),
.m_aresetn ( cpu_resetn ),
//ar
.m_arid ( cpu_arid ),
.m_araddr ( cpu_araddr ),
.m_arlen ( cpu_arlen ),
.m_arsize ( cpu_arsize ),
.m_arburst ( cpu_arburst ),
.m_arlock ( cpu_arlock ),
.m_arcache ( cpu_arcache ),
.m_arprot ( cpu_arprot ),
.m_arvalid ( cpu_arvalid ),
.m_arready ( cpu_arready ),
//r
.m_rid ( cpu_rid ),
.m_rdata ( cpu_rdata ),
.m_rresp ( cpu_rresp ),
.m_rlast ( cpu_rlast ),
.m_rvalid ( cpu_rvalid ),
.m_rready ( cpu_rready ),
//aw
.m_awid ( cpu_awid ),
.m_awaddr ( cpu_awaddr ),
.m_awlen ( cpu_awlen ),
.m_awsize ( cpu_awsize ),
.m_awburst ( cpu_awburst ),
.m_awlock ( cpu_awlock ),
.m_awcache ( cpu_awcache ),
.m_awprot ( cpu_awprot ),
.m_awvalid ( cpu_awvalid ),
.m_awready ( cpu_awready ),
//w
.m_wid ( cpu_wid ),
.m_wdata ( cpu_wdata ),
.m_wstrb ( cpu_wstrb ),
.m_wlast ( cpu_wlast ),
.m_wvalid ( cpu_wvalid ),
.m_wready ( cpu_wready ),
//b
.m_bid ( cpu_bid ),
.m_bresp ( cpu_bresp ),
.m_bvalid ( cpu_bvalid ),
.m_bready ( cpu_bready ),
.s_aclk ( cpu_wrap_aclk ),
.s_aresetn ( cpu_wrap_aresetn ),
//ar
.s_arid ( cpu_wrap_arid ),
.s_araddr ( cpu_wrap_araddr ),
.s_arlen ( cpu_wrap_arlen ),
.s_arsize ( cpu_wrap_arsize ),
.s_arburst ( cpu_wrap_arburst ),
.s_arlock ( cpu_wrap_arlock ),
.s_arcache ( cpu_wrap_arcache ),
.s_arprot ( cpu_wrap_arprot ),
.s_arvalid ( cpu_wrap_arvalid ),
.s_arready ( cpu_wrap_arready ),
//r
.s_rid ( cpu_wrap_rid ),
.s_rdata ( cpu_wrap_rdata ),
.s_rresp ( cpu_wrap_rresp ),
.s_rlast ( cpu_wrap_rlast ),
.s_rvalid ( cpu_wrap_rvalid ),
.s_rready ( cpu_wrap_rready ),
//aw
.s_awid ( cpu_wrap_awid ),
.s_awaddr ( cpu_wrap_awaddr ),
.s_awlen ( cpu_wrap_awlen ),
.s_awsize ( cpu_wrap_awsize ),
.s_awburst ( cpu_wrap_awburst ),
.s_awlock ( cpu_wrap_awlock ),
.s_awcache ( cpu_wrap_awcache ),
.s_awprot ( cpu_wrap_awprot ),
.s_awvalid ( cpu_wrap_awvalid ),
.s_awready ( cpu_wrap_awready ),
//w
.s_wid ( cpu_wrap_wid ),
.s_wdata ( cpu_wrap_wdata ),
.s_wstrb ( cpu_wrap_wstrb ),
.s_wlast ( cpu_wrap_wlast ),
.s_wvalid ( cpu_wrap_wvalid ),
.s_wready ( cpu_wrap_wready ),
//b
.s_bid ( cpu_wrap_bid ),
.s_bresp ( cpu_wrap_bresp ),
.s_bvalid ( cpu_wrap_bvalid ),
.s_bready ( cpu_wrap_bready )
);
//clock sync: from CPU to AXI_Crossbar
axi_clock_converter u_axi_clock_sync(
.s_axi_aclk (cpu_clk ),
.s_axi_aresetn (cpu_resetn ),
.s_axi_awid (cpu_wrap_awid ),
.s_axi_awaddr (cpu_wrap_awaddr ),
.s_axi_awlen (cpu_wrap_awlen ),
.s_axi_awsize (cpu_wrap_awsize ),
.s_axi_awburst (cpu_wrap_awburst ),
.s_axi_awlock (cpu_wrap_awlock ),
.s_axi_awcache (cpu_wrap_awcache ),
.s_axi_awprot (cpu_wrap_awprot ),
.s_axi_awqos (4'd0 ),
.s_axi_awvalid (cpu_wrap_awvalid ),
.s_axi_awready (cpu_wrap_awready ),
.s_axi_wid (cpu_wrap_wid ),
.s_axi_wdata (cpu_wrap_wdata ),
.s_axi_wstrb (cpu_wrap_wstrb ),
.s_axi_wlast (cpu_wrap_wlast ),
.s_axi_wvalid (cpu_wrap_wvalid ),
.s_axi_wready (cpu_wrap_wready ),
.s_axi_bid (cpu_wrap_bid ),
.s_axi_bresp (cpu_wrap_bresp ),
.s_axi_bvalid (cpu_wrap_bvalid ),
.s_axi_bready (cpu_wrap_bready ),
.s_axi_arid (cpu_wrap_arid ),
.s_axi_araddr (cpu_wrap_araddr ),
.s_axi_arlen (cpu_wrap_arlen ),
.s_axi_arsize (cpu_wrap_arsize ),
.s_axi_arburst (cpu_wrap_arburst ),
.s_axi_arlock (cpu_wrap_arlock ),
.s_axi_arcache (cpu_wrap_arcache ),
.s_axi_arprot (cpu_wrap_arprot ),
.s_axi_arqos (4'd0 ),
.s_axi_arvalid (cpu_wrap_arvalid ),
.s_axi_arready (cpu_wrap_arready ),
.s_axi_rid (cpu_wrap_rid ),
.s_axi_rdata (cpu_wrap_rdata ),
.s_axi_rresp (cpu_wrap_rresp ),
.s_axi_rlast (cpu_wrap_rlast ),
.s_axi_rvalid (cpu_wrap_rvalid ),
.s_axi_rready (cpu_wrap_rready ),
.m_axi_aclk (sys_clk ),
.m_axi_aresetn (sys_resetn ),
.m_axi_awid (cpu_sync_awid ),
.m_axi_awaddr (cpu_sync_awaddr ),
.m_axi_awlen (cpu_sync_awlen ),
.m_axi_awsize (cpu_sync_awsize ),
.m_axi_awburst (cpu_sync_awburst ),
.m_axi_awlock (cpu_sync_awlock ),
.m_axi_awcache (cpu_sync_awcache ),
.m_axi_awprot (cpu_sync_awprot ),
.m_axi_awqos ( ),
.m_axi_awvalid (cpu_sync_awvalid ),
.m_axi_awready (cpu_sync_awready ),
.m_axi_wid (cpu_sync_wid ),
.m_axi_wdata (cpu_sync_wdata ),
.m_axi_wstrb (cpu_sync_wstrb ),
.m_axi_wlast (cpu_sync_wlast ),
.m_axi_wvalid (cpu_sync_wvalid ),
.m_axi_wready (cpu_sync_wready ),
.m_axi_bid (cpu_sync_bid ),
.m_axi_bresp (cpu_sync_bresp ),
.m_axi_bvalid (cpu_sync_bvalid ),
.m_axi_bready (cpu_sync_bready ),
.m_axi_arid (cpu_sync_arid ),
.m_axi_araddr (cpu_sync_araddr ),
.m_axi_arlen (cpu_sync_arlen ),
.m_axi_arsize (cpu_sync_arsize ),
.m_axi_arburst (cpu_sync_arburst ),
.m_axi_arlock (cpu_sync_arlock ),
.m_axi_arcache (cpu_sync_arcache ),
.m_axi_arprot (cpu_sync_arprot ),
.m_axi_arqos ( ),
.m_axi_arvalid (cpu_sync_arvalid ),
.m_axi_arready (cpu_sync_arready ),
.m_axi_rid (cpu_sync_rid ),
.m_axi_rdata (cpu_sync_rdata ),
.m_axi_rresp (cpu_sync_rresp ),
.m_axi_rlast (cpu_sync_rlast ),
.m_axi_rvalid (cpu_sync_rvalid ),
.m_axi_rready (cpu_sync_rready )
);
axi_crossbar_1x2 u_axi_crossbar_1x2(
.aclk ( sys_clk ), // i, 1
.aresetn ( sys_resetn ), // i, 1
.s_axi_arid ( cpu_sync_arid ),
.s_axi_araddr ( cpu_sync_araddr ),
.s_axi_arlen ( cpu_sync_arlen[3:0] ),
.s_axi_arsize ( cpu_sync_arsize ),
.s_axi_arburst ( cpu_sync_arburst ),
.s_axi_arlock ( cpu_sync_arlock ),
.s_axi_arcache ( cpu_sync_arcache ),
.s_axi_arprot ( cpu_sync_arprot ),
.s_axi_arqos ( 4'd0 ),
.s_axi_arvalid ( cpu_sync_arvalid ),
.s_axi_arready ( cpu_sync_arready ),
.s_axi_rid ( cpu_sync_rid ),
.s_axi_rdata ( cpu_sync_rdata ),
.s_axi_rresp ( cpu_sync_rresp ),
.s_axi_rlast ( cpu_sync_rlast ),
.s_axi_rvalid ( cpu_sync_rvalid ),
.s_axi_rready ( cpu_sync_rready ),
.s_axi_awid ( cpu_sync_awid ),
.s_axi_awaddr ( cpu_sync_awaddr ),
.s_axi_awlen ( cpu_sync_awlen[3:0] ),
.s_axi_awsize ( cpu_sync_awsize ),
.s_axi_awburst ( cpu_sync_awburst ),
.s_axi_awlock ( cpu_sync_awlock ),
.s_axi_awcache ( cpu_sync_awcache ),
.s_axi_awprot ( cpu_sync_awprot ),
.s_axi_awqos ( 4'd0 ),
.s_axi_awvalid ( cpu_sync_awvalid ),
.s_axi_awready ( cpu_sync_awready ),
.s_axi_wid ( cpu_sync_wid ),
.s_axi_wdata ( cpu_sync_wdata ),
.s_axi_wstrb ( cpu_sync_wstrb ),
.s_axi_wlast ( cpu_sync_wlast ),
.s_axi_wvalid ( cpu_sync_wvalid ),
.s_axi_wready ( cpu_sync_wready ),
.s_axi_bid ( cpu_sync_bid ),
.s_axi_bresp ( cpu_sync_bresp ),
.s_axi_bvalid ( cpu_sync_bvalid ),
.s_axi_bready ( cpu_sync_bready ),
.m_axi_arid ( {ram_arid ,conf_arid } ),
.m_axi_araddr ( {ram_araddr ,conf_araddr } ),
.m_axi_arlen ( {ram_arlen ,conf_arlen } ),
.m_axi_arsize ( {ram_arsize ,conf_arsize } ),
.m_axi_arburst ( {ram_arburst,conf_arburst} ),
.m_axi_arlock ( {ram_arlock ,conf_arlock } ),
.m_axi_arcache ( {ram_arcache,conf_arcache} ),
.m_axi_arprot ( {ram_arprot ,conf_arprot } ),
.m_axi_arqos ( ),
.m_axi_arvalid ( {ram_arvalid,conf_arvalid} ),
.m_axi_arready ( {ram_arready,conf_arready} ),
.m_axi_rid ( {ram_rid ,conf_rid } ),
.m_axi_rdata ( {ram_rdata ,conf_rdata } ),
.m_axi_rresp ( {ram_rresp ,conf_rresp } ),
.m_axi_rlast ( {ram_rlast ,conf_rlast } ),
.m_axi_rvalid ( {ram_rvalid ,conf_rvalid } ),
.m_axi_rready ( {ram_rready ,conf_rready } ),
.m_axi_awid ( {ram_awid ,conf_awid } ),
.m_axi_awaddr ( {ram_awaddr ,conf_awaddr } ),
.m_axi_awlen ( {ram_awlen ,conf_awlen } ),
.m_axi_awsize ( {ram_awsize ,conf_awsize } ),
.m_axi_awburst ( {ram_awburst,conf_awburst} ),
.m_axi_awlock ( {ram_awlock ,conf_awlock } ),
.m_axi_awcache ( {ram_awcache,conf_awcache} ),
.m_axi_awprot ( {ram_awprot ,conf_awprot } ),
.m_axi_awqos ( ),
.m_axi_awvalid ( {ram_awvalid,conf_awvalid} ),
.m_axi_awready ( {ram_awready,conf_awready} ),
.m_axi_wid ( {ram_wid ,conf_wid } ),
.m_axi_wdata ( {ram_wdata ,conf_wdata } ),
.m_axi_wstrb ( {ram_wstrb ,conf_wstrb } ),
.m_axi_wlast ( {ram_wlast ,conf_wlast } ),
.m_axi_wvalid ( {ram_wvalid ,conf_wvalid } ),
.m_axi_wready ( {ram_wready ,conf_wready } ),
.m_axi_bid ( {ram_bid ,conf_bid } ),
.m_axi_bresp ( {ram_bresp ,conf_bresp } ),
.m_axi_bvalid ( {ram_bvalid ,conf_bvalid } ),
.m_axi_bready ( {ram_bready ,conf_bready } )
);
//axi ram
axi_wrap_ram u_axi_ram
(
.aclk ( sys_clk ),
.aresetn ( sys_resetn ),
//ar
.axi_arid ( ram_arid ),
.axi_araddr ( ram_araddr ),
.axi_arlen ( {4'd0,ram_arlen} ),
.axi_arsize ( ram_arsize ),
.axi_arburst ( ram_arburst ),
.axi_arlock ( ram_arlock ),
.axi_arcache ( ram_arcache ),
.axi_arprot ( ram_arprot ),
.axi_arvalid ( ram_arvalid ),
.axi_arready ( ram_arready ),
//r
.axi_rid ( ram_rid ),
.axi_rdata ( ram_rdata ),
.axi_rresp ( ram_rresp ),
.axi_rlast ( ram_rlast ),
.axi_rvalid ( ram_rvalid ),
.axi_rready ( ram_rready ),
//aw
.axi_awid ( ram_awid ),
.axi_awaddr ( ram_awaddr ),
.axi_awlen ( {4'd0,ram_awlen[3:0]} ),
.axi_awsize ( ram_awsize ),
.axi_awburst ( ram_awburst ),
.axi_awlock ( ram_awlock ),
.axi_awcache ( ram_awcache ),
.axi_awprot ( ram_awprot ),
.axi_awvalid ( ram_awvalid ),
.axi_awready ( ram_awready ),
//w
.axi_wid ( ram_wid ),
.axi_wdata ( ram_wdata ),
.axi_wstrb ( ram_wstrb ),
.axi_wlast ( ram_wlast ),
.axi_wvalid ( ram_wvalid ),
.axi_wready ( ram_wready ),
//b ram
.axi_bid ( ram_bid ),
.axi_bresp ( ram_bresp ),
.axi_bvalid ( ram_bvalid ),
.axi_bready ( ram_bready ),
//random mask
.ram_random_mask ( ram_random_mask )
);
//confreg
confreg #(.SIMULATION(SIMULATION)) u_confreg
(
.timer_clk ( sys_clk ), // i, 1
.aclk ( sys_clk ), // i, 1
.aresetn ( sys_resetn ), // i, 1
.arid (conf_arid ),
.araddr (conf_araddr ),
.arlen (conf_arlen ),
.arsize (conf_arsize ),
.arburst (conf_arburst ),
.arlock (conf_arlock ),
.arcache (conf_arcache ),
.arprot (conf_arprot ),
.arvalid (conf_arvalid ),
.arready (conf_arready ),
.rid (conf_rid ),
.rdata (conf_rdata ),
.rresp (conf_rresp ),
.rlast (conf_rlast ),
.rvalid (conf_rvalid ),
.rready (conf_rready ),
.awid (conf_awid ),
.awaddr (conf_awaddr ),
.awlen (conf_awlen ),
.awsize (conf_awsize ),
.awburst (conf_awburst ),
.awlock (conf_awlock ),
.awcache (conf_awcache ),
.awprot (conf_awprot ),
.awvalid (conf_awvalid ),
.awready (conf_awready ),
.wid (conf_wid ),
.wdata (conf_wdata ),
.wstrb (conf_wstrb ),
.wlast (conf_wlast ),
.wvalid (conf_wvalid ),
.wready (conf_wready ),
.bid (conf_bid ),
.bresp (conf_bresp ),
.bvalid (conf_bvalid ),
.bready (conf_bready ),
.ram_random_mask ( ram_random_mask ),
.led ( led ), // o, 16
.led_rg0 ( led_rg0 ), // o, 2
.led_rg1 ( led_rg1 ), // o, 2
.num_csn ( num_csn ), // o, 8
.num_a_g ( num_a_g ), // o, 7
.switch ( switch ), // i, 8
.btn_key_col ( btn_key_col), // o, 4
.btn_key_row ( btn_key_row), // i, 4
.btn_step ( btn_step ) // i, 2
);
endmodule

View File

@ -0,0 +1,285 @@
`timescale 1ns / 1ps
`define TRACE_REF_FILE "../../../../../../../cpu132_gettrace/golden_trace.txt"
`define CONFREG_NUM_REG soc_lite.u_confreg.num_data
`define CONFREG_OPEN_TRACE soc_lite.u_confreg.open_trace
`define CONFREG_NUM_MONITOR soc_lite.u_confreg.num_monitor
`define CONFREG_UART_DISPLAY soc_lite.u_confreg.write_uart_valid
`define CONFREG_UART_DATA soc_lite.u_confreg.write_uart_data
`define END_PC 32'hbfc00100
module tb2_top ();
logic resetn;
logic clk;
//goio
logic [15:0] led;
logic [1:0] led_rg0;
logic [1:0] led_rg1;
logic [7:0] num_csn;
logic [6:0] num_a_g;
logic [7:0] switch;
logic [3:0] btn_key_col;
logic [3:0] btn_key_row;
logic [1:0] btn_step;
assign switch = 8'hff;
assign btn_key_row = 4'd0;
assign btn_step = 2'd3;
initial begin
$dumpfile("dump.vcd");
$dumpvars();
resetn = 1'b0;
#2000;
resetn = 1'b1;
end
initial begin
clk = 1'b0;
forever begin
#5 clk = ~clk;
end
end
soc_axi_lite_top2 #(
.SIMULATION(1'b1)
) soc_lite (
.resetn(resetn),
.clk (clk),
//------gpio-------
.num_csn (num_csn),
.num_a_g (num_a_g),
.led (led),
.led_rg0 (led_rg0),
.led_rg1 (led_rg1),
.switch (switch),
.btn_key_col(btn_key_col),
.btn_key_row(btn_key_row),
.btn_step (btn_step)
);
//"cpu_clk" means cpu core clk
//"sys_clk" means system clk
//"wb" means write-back stage in pipeline
//"rf" means regfiles in cpu
//"w" in "wen/wnum/wdata" means writing
logic cpu_clk;
logic sys_clk;
logic [31:0] debug_wb_pc;
logic [3:0] debug_wb_rf_wen;
logic [4:0] debug_wb_rf_wnum;
logic [31:0] debug_wb_rf_wdata;
logic [31:0] debug_wb1_pc;
logic [3:0] debug_wb1_rf_wen;
logic [4:0] debug_wb1_rf_wnum;
logic [31:0] debug_wb1_rf_wdata;
logic debug_wb_pc_A;
assign cpu_clk = soc_lite.cpu_clk;
assign sys_clk = soc_lite.sys_clk;
assign debug_wb_pc = soc_lite.debug_wb_pc;
assign debug_wb_rf_wen = soc_lite.debug_wb_rf_wen;
assign debug_wb_rf_wnum = soc_lite.debug_wb_rf_wnum;
assign debug_wb_rf_wdata = soc_lite.debug_wb_rf_wdata;
assign debug_wb1_pc = soc_lite.debug_wb1_pc;
assign debug_wb1_rf_wen = soc_lite.debug_wb1_rf_wen;
assign debug_wb1_rf_wnum = soc_lite.debug_wb1_rf_wnum;
assign debug_wb1_rf_wdata = soc_lite.debug_wb1_rf_wdata;
assign debug_wb_pc_A = soc_lite.debug_wb_pc_A;
// open the trace file;
integer trace_ref;
initial begin
trace_ref = $fopen(`TRACE_REF_FILE, "r");
end
//get reference result in falling edge
logic debug_end;
logic trace_cmp_flag;
logic [31:0] ref_wb_pc;
logic [4:0] ref_wb_rf_wnum;
logic [31:0] ref_wb_rf_wdata;
typedef struct packed {
logic trace_cmp_flag;
logic [31:0] ref_wb_pc;
logic [4:0] ref_wb_rf_wnum;
logic [31:0] ref_wb_rf_wdata;
} TRACE_INFO;
TRACE_INFO ref_trace[$];
initial begin
ref_trace.clear();
while (!$feof(
trace_ref
)) begin
$fscanf(trace_ref, "%h %h %h %h", trace_cmp_flag, ref_wb_pc, ref_wb_rf_wnum, ref_wb_rf_wdata);
ref_trace.push_back({trace_cmp_flag, ref_wb_pc, ref_wb_rf_wnum, ref_wb_rf_wdata});
end
end
//compare result in rsing edge
logic debug_wb_err;
logic dbg_0_rf_wen;
logic [31:0] dbg_0_pc;
logic [ 4:0] dbg_0_rf_wnum;
logic [31:0] dbg_0_rf_wdata;
logic dbg_1_rf_wen;
logic [31:0] dbg_1_pc;
logic [ 4:0] dbg_1_rf_wnum;
logic [31:0] dbg_1_rf_wdata;
always_ff @(posedge cpu_clk) begin
#2;
if (!resetn) begin
debug_wb_err <= 1'b0;
end else if (!debug_end && `CONFREG_OPEN_TRACE) begin
if (debug_wb_pc_A) begin
dbg_0_rf_wen <= debug_wb1_rf_wen;
dbg_0_pc <= debug_wb1_pc;
dbg_0_rf_wnum <= debug_wb1_rf_wnum;
dbg_0_rf_wdata <= debug_wb1_rf_wdata;
dbg_1_rf_wen <= debug_wb_rf_wen;
dbg_1_pc <= debug_wb_pc;
dbg_1_rf_wnum <= debug_wb_rf_wnum;
dbg_1_rf_wdata <= debug_wb_rf_wdata;
end else begin
dbg_1_rf_wen <= debug_wb1_rf_wen;
dbg_1_pc <= debug_wb1_pc;
dbg_1_rf_wnum <= debug_wb1_rf_wnum;
dbg_1_rf_wdata <= debug_wb1_rf_wdata;
dbg_0_rf_wen <= debug_wb_rf_wen;
dbg_0_pc <= debug_wb_pc;
dbg_0_rf_wnum <= debug_wb_rf_wnum;
dbg_0_rf_wdata <= debug_wb_rf_wdata;
end
if (|dbg_0_rf_wen && dbg_0_rf_wnum != 5'd0) begin
if ( (dbg_0_pc !== ref_trace[0].ref_wb_pc )
|| (dbg_0_rf_wnum !== ref_trace[0].ref_wb_rf_wnum )
|| (dbg_0_rf_wdata !== ref_trace[0].ref_wb_rf_wdata_v)
)
begin
$display("--------------------------------------------------------------");
$display("[%t] Error!!!", $time);
$display(" reference: PC = 0x%8h, wb_rf_wnum = 0x%2h, wb_rf_wdata = 0x%8h",
ref_trace[0].ref_wb_pc, ref_trace[0].ref_wb_rf_wnum,
ref_trace[0].ref_wb_rf_wdata_v);
$display(" mycpu : PC = 0x%8h, wb_rf_wnum = 0x%2h, wb_rf_wdata = 0x%8h", dbg_0_pc,
dbg_0_rf_wnum, dbg_0_rf_wdata);
$display("--------------------------------------------------------------");
debug_wb_err <= 1'b1;
#40;
$finish;
end else ref_trace.pop_front();
end else if (|dbg_1_rf_wen && dbg_1_rf_wnum != 5'd0) begin
if ( (dbg_1_pc !== ref_trace[0].ref_wb_pc )
|| (dbg_1_rf_wnum !== ref_trace[0].ref_wb_rf_wnum )
|| (dbg_1_rf_wdata !== ref_trace[0].ref_wb_rf_wdata_v)
)
begin
$display("--------------------------------------------------------------");
$display("[%t] Error!!!", $time);
$display(" reference: PC = 0x%8h, wb_rf_wnum = 0x%2h, wb_rf_wdata = 0x%8h",
ref_trace[0].ref_wb_pc, ref_trace[0].ref_wb_rf_wnum,
ref_trace[0].ref_wb_rf_wdata_v);
$display(" mycpu : PC = 0x%8h, wb_rf_wnum = 0x%2h, wb_rf_wdata = 0x%8h", dbg_1_pc,
dbg_1_rf_wnum, dbg_1_rf_wdata);
$display("--------------------------------------------------------------");
debug_wb_err <= 1'b1;
#40;
$finish;
end else ref_trace.pop_front();
end
end
end
//monitor numeric display
logic [ 7:0] err_count;
logic [31:0] confreg_num_reg = `CONFREG_NUM_REG;
logic [31:0] confreg_num_reg_r;
always_ff @(posedge sys_clk) begin
confreg_num_reg_r <= confreg_num_reg;
if (!resetn) begin
err_count <= 8'd0;
end else if (confreg_num_reg_r != confreg_num_reg && `CONFREG_NUM_MONITOR) begin
if (confreg_num_reg[7:0] != confreg_num_reg_r[7:0] + 1'b1) begin
$display("--------------------------------------------------------------");
$display("[%t] Error(%d)!!! Occurred in number 8'd%02d Functional Test Point!", $time,
err_count, confreg_num_reg[31:24]);
$display("--------------------------------------------------------------");
err_count <= err_count + 1'b1;
end else if (confreg_num_reg[31:24] != confreg_num_reg_r[31:24] + 1'b1) begin
$display("--------------------------------------------------------------");
$display("[%t] Error(%d)!!! Unknown, Functional Test Point numbers are unequal!", $time,
err_count);
$display("--------------------------------------------------------------");
$display("==============================================================");
err_count <= err_count + 1'b1;
end else begin
$display("----[%t] Number 8'd%02d Functional Test Point PASS!!!", $time,
confreg_num_reg[31:24]);
end
end
end
//monitor test
initial begin
$timeformat(-9, 0, " ns", 10);
while (!resetn) #5;
$display("==============================================================");
$display("Test begin!");
#10000;
while (`CONFREG_NUM_MONITOR) begin
#10000;
$display(" [%t] Test is running, dbg_0_pc = 0x%8h, dbg_1_pc = 0x%8h", $time, dbg_0_pc,
dbg_1_pc);
end
end
//模拟串口打印
logic uart_display;
logic [7:0] uart_data;
assign uart_display = `CONFREG_UART_DISPLAY;
assign uart_data = `CONFREG_UART_DATA;
always_ff @(posedge sys_clk) begin
if (uart_display) begin
if (uart_data == 8'hff) begin
; //$finish;
end else begin
$write("%c", uart_data);
end
end
end
//test end
logic global_err = debug_wb_err || (err_count != 8'd0);
logic test_end = (dbg_0_pc == `END_PC) || (dbg_1_pc == `END_PC) || (uart_display && uart_data == 8'hff);
always_ff @(posedge cpu_clk) begin
if (!resetn) begin
debug_end <= 1'b0;
end else if (test_end && !debug_end) begin
debug_end <= 1'b1;
$display("==============================================================");
$display("Test end!");
#40;
$fclose(trace_ref);
if (global_err) begin
$display("Fail!!!Total %d errors!", err_count);
end else begin
$display("----PASS!!!");
end
$finish;
end
end
endmodule

View File

@ -3,7 +3,7 @@
module Controller (
input word_t inst,
input logic eq,
input logic lt,
input logic ltz,
output Ctrl_t ctrl,
output word_t imm,
output logic [4:0] sa
@ -36,7 +36,7 @@ module Controller (
assign ctrl.PFCtrl.PCS = {
~inst[28] & (~inst[27] & ~inst[26] & ~inst[31] & ~inst[30] & ~inst[29] & inst[3] & ~inst[4] & ~inst[5] | inst[27] & ~inst[29] & ~inst[31]),
~inst[26] & (~inst[27] & inst[28] & ~inst[31] & ~inst[29] & eq | inst[27] & ~inst[29] & (~inst[28] | eq & lt)) | inst[26] & ~inst[29] & ~inst[31] & (~inst[27] & ~inst[30] & (~inst[28] & (~lt & inst[16] | lt & ~inst[16]) | inst[28] & ~eq) | inst[27] & (~inst[28] | ~eq | ~lt))
~inst[26] & (~inst[27] & inst[28] & ~inst[31] & ~inst[29] & eq | inst[27] & ~inst[29] & (~inst[28] | eq & ltz)) | inst[26] & ~inst[29] & ~inst[31] & (~inst[27] & ~inst[30] & (~inst[28] & (~ltz & inst[16] | ltz & ~inst[16]) | inst[28] & ~eq) | inst[27] & (~inst[28] | ~eq | ~ltz))
};
assign ctrl.PFCtrl.BJRJ = ~inst[26] & (~inst[27] & (~inst[28] & ~inst[30] & ~inst[31] & ~inst[29] & inst[3] & ~inst[4] & ~inst[5] & ~inst[2] | inst[28] & ~inst[31] & ~inst[29]) | inst[27] & ~inst[29]) | inst[26] & ~inst[29] & ~inst[31];
assign ctrl.PFCtrl.BJR = ~inst[26] & (~inst[28] & ~inst[30] & ~inst[29] & ~inst[31] & ~inst[27] & inst[3] & ~inst[4] & ~inst[5] & ~inst[2] | inst[28] & ~inst[29] & ~inst[31]) | inst[26] & ~inst[29] & ~inst[31] & (~inst[27] | inst[27] & inst[28]);
@ -55,19 +55,19 @@ module Controller (
assign ctrl.ECtrl.OP.f_ans = ~inst[31] & ~inst[26] & (~inst[28] & ~inst[27] & ~inst[29] & inst[5] & inst[2] & ~inst[0] & ~inst[1] | inst[28] & ~inst[27]);
assign ctrl.ECtrl.OP.f_xor = ~inst[31] & ~inst[26] & (~inst[28] & ~inst[27] & ~inst[29] & inst[5] & inst[2] & ~inst[0] & inst[1] | inst[28] & inst[27]);
assign ctrl.ECtrl.OP.f_or = ~inst[31] & (~inst[26] & ~inst[28] & ~inst[27] & ~inst[29] & inst[5] & inst[2] & inst[0] | inst[26] & inst[29] & inst[28] & ~inst[27]);
assign ctrl.ECtrl.OP.alt = ~inst[31] & (~inst[26] & (~inst[27] & ~inst[29] & inst[1] & (~inst[5] & inst[0] | inst[5]) | inst[27]) | inst[26] & inst[27] & inst[29] & ~inst[28]);
// TODO: Redesign
assign ctrl.ECtrl.SA = 2'b11 & (~inst[31] & ~inst[30] & ~inst[29] & ~inst[28] & ~inst[27] & ~inst[26] & ~inst[5] & ~inst[4] & ~inst[3] & ~inst[2])
| 2'b10 & (~inst[30] & (~inst[29] & (~inst[26] & ~inst[28] & ~inst[27] & ((~inst[1] & (~inst[4] & ~inst[3] & inst[2] | inst[4] & inst[3]) | inst[1] & (~inst[4] & inst[2] | inst[3])) | inst[5]) | inst[31]) | inst[29] & (~inst[28] | ~inst[27] | ~inst[26])))
| 2'b01 & (~inst[31] & ~inst[30] & ~inst[29] & (((~inst[5] & (~inst[1] & (~inst[4] & inst[3] | inst[4] & ~inst[3]) | inst[1] & ~inst[3] & inst[4]) | inst[27]) | inst[28]) | inst[26]))
| 2'b00 & (inst[29] & inst[28] & inst[27] & inst[26] | inst[30]);
assign ctrl.ECtrl.SB = 2'b10 & (~inst[29] & ~inst[31] & ~inst[26] & ~inst[30] & ~inst[28] & ~inst[27] & ((~inst[1] & (~inst[0] & (~inst[3] & ~inst[4] | inst[3] & inst[4]) | inst[0] & inst[4] & inst[3]) | inst[1] & (~inst[4] | inst[4] & inst[3])) | inst[5]))
| 2'b01 & (~inst[29] & ~inst[31] & (~inst[30] & ((~inst[5] & (~inst[1] & (~inst[0] & (~inst[3] & inst[4] | inst[3] & ~inst[4]) | inst[0] & (~inst[4] | ~inst[3])) | inst[1] & inst[4] & ~inst[3]) | inst[27]) | inst[28]) | inst[26]))
| 2'b00 & (inst[30] & ~inst[26] | inst[31] | inst[29]);
assign ctrl.ECtrl.OP.alt = ~inst[31] & (~inst[26] & (~inst[29] & inst[1] & (inst[0] | inst[5]) | inst[27]) | inst[26] & inst[27] & inst[29] & ~inst[28]);
assign ctrl.ECtrl.SA = {
((~inst[26] & ~inst[28] & (~inst[27] & ((~inst[2] & inst[3] & inst[4] | inst[2] & ~inst[3]) | inst[5]) | inst[30]) | inst[31]) | inst[29]),
~inst[30] & ((~inst[29] & (inst[3] | inst[2] | inst[4] | inst[5] | inst[27] | inst[28] | inst[26]) | inst[29] & (~inst[28] | ~inst[27] | ~inst[26])) | inst[31])
};
assign ctrl.ECtrl.SB = {
((inst[30] | inst[31]) | inst[29]),
(~inst[5] & (~inst[1] & (~inst[0] & (~inst[3] & inst[4] | inst[3] & ~inst[4]) | inst[0] & (~inst[4] | ~inst[3])) | inst[1] & inst[4] & ~inst[3]) | inst[27] | inst[31] | inst[28] | inst[30] | inst[29] | inst[26])
};
assign ctrl.MCtrl0.HW = ~inst[26] & ~inst[29] & ~inst[30] & ~inst[28] & ~inst[27] & inst[4] & (~inst[3] & ~inst[1] & inst[0] | inst[3]);
assign ctrl.MCtrl0.LW = ~inst[26] & ~inst[29] & ~inst[30] & ~inst[28] & ~inst[27] & inst[4] & (~inst[3] & inst[1] & inst[0] | inst[3]);
assign ctrl.MCtrl0.HW = ~inst[26] & ~inst[29] & ~inst[30] & ~inst[28] & ~inst[27] & inst[4] & (~inst[1] & inst[0] | inst[3]);
assign ctrl.MCtrl0.LW = ~inst[26] & ~inst[29] & ~inst[30] & ~inst[28] & ~inst[27] & inst[4] & (inst[1] & inst[0] | inst[3]);
assign ctrl.MCtrl0.HLS = {~inst[3], inst[1:0]};
assign ctrl.MCtrl0.C0D = inst[15:11];
assign ctrl.MCtrl0.C0W = inst[30] & inst[23];
@ -81,6 +81,6 @@ module Controller (
assign ctrl.MCtrl1.MX = ~inst[28];
assign ctrl.MCtrl1.SZ = inst[27:26];
assign ctrl.WCtrl.RW = (ctrl.RD != 5'b00000) & ~inst[30] & (~inst[29] & (~inst[31] & ~inst[28] & (~inst[27] & (~inst[26] & (~inst[3] & (~inst[4] | inst[4] & ~inst[0]) | inst[3] & (~inst[5] & ~inst[4] & ~inst[2] & inst[0] | inst[5])) | inst[26] & inst[20]) | inst[27] & inst[26]) | inst[31]) | inst[29] & ~inst[31]) | inst[30] & ~inst[25] & ~inst[23];
assign ctrl.WCtrl.RW = (ctrl.RD != 5'b00000) & ~inst[30] & (~inst[29] & (~inst[31] & ~inst[28] & (~inst[27] & (~inst[26] & (~inst[3] & (~inst[4] | inst[4] & ~inst[0]) | inst[3] & (~inst[4] & ~inst[2] & inst[0] | inst[5])) | inst[26] & inst[20]) | inst[27] & inst[26]) | inst[31]) | inst[29] & ~inst[31]) | inst[30] & ~inst[25] & ~inst[23];
endmodule

View File

@ -48,15 +48,51 @@ module Datapath (
word_t IQ_IB_inst;
word_t IQ_IB_pc;
logic [ 3:0] IQ_valids;
// Decode
logic D_go;
logic D_en0f;
logic D_IA_readygo;
logic D_IA_go;
logic D_IB_readygo;
logic D_IB_go;
logic D_I0_go;
logic D_I1_go;
logic D_IA_FS_M_I0;
logic D_IA_FS_M_I1;
logic D_IA_FS_W_I0;
logic D_IA_FS_W_I1;
word_t D_IA_ForwardS;
logic D_IA_FT_M_I0;
logic D_IA_FT_M_I1;
logic D_IA_FT_W_I0;
logic D_IA_FT_W_I1;
word_t D_IA_ForwardT;
logic D_IB_FS_M_I0;
logic D_IB_FS_M_I1;
logic D_IB_FS_W_I0;
logic D_IB_FS_W_I1;
word_t D_IB_ForwardS;
logic D_IB_FT_M_I0;
logic D_IB_FT_M_I1;
logic D_IB_FT_W_I0;
logic D_IB_FT_W_I1;
word_t D_IB_ForwardT;
logic D_IA_valid;
logic D_IB_valid;
logic D_IA_iv;
logic D_IB_iv;
logic D_IA_DataHazard;
logic D_IB_DataHazard;
// Execute
logic E_go;
logic E_I0_go;
@ -147,12 +183,13 @@ module Datapath (
D.IA.PCS,
PF_pc0
);
prio_mux4 #(32) PF_pc_mux (
prio_mux5 #(32) PF_pc_mux (
PF_pc0,
PF_pcp8,
C0_EPC,
`PCEXC,
`PCRST,
{rst, C0_exception.ExcValid, C0_exception.ERET},
{rst, C0_exception.ExcValid, C0_exception.ERET, ~D_IA_valid},
PF.pc
);
@ -173,7 +210,7 @@ module Datapath (
F.pc
);
// assign F.en = fetch_i.data_ok;
assign F.en = ~IQ_valids[3] | (~IQ_valids[2] & (F.pc[2] | PF.pc[2] | D_en0f) | IQ_valids[2] & (~IQ_valids[1] & (~D_en0f & PF.pc[2] & F.pc[2] | D_en0f & (D.en1 | F.pc[2] | PF.pc[2])) | IQ_valids[1] & D_en0f & (~PF.pc[2] & F.pc[2] & D.en1 & ~IQ_valids[0] | PF.pc[2] & (~F.pc[2] & D.en1 & ~IQ_valids[0] | F.pc[2] & (~IQ_valids[0] | D.en1)))));
//---------------------------------------------------------------------------//
// Instr Queue //
@ -189,7 +226,7 @@ module Datapath (
.vinB(fetch_i.data_ok & ~F.pc[2]),
.inB (fetch_i.rdata1),
.pinB({F.pc[31:3], 1'b1, F.pc[1:0]}),
.pinB({F.pc[31:3], 3'b100}),
.enA (D.en0),
.voutA(IQ_IA_valid),
@ -201,7 +238,7 @@ module Datapath (
.outB (IQ_IB_inst),
.poutB(IQ_IB_pc),
.valids()
.valids(IQ_valids)
);
//---------------------------------------------------------------------------//
@ -251,16 +288,20 @@ module Datapath (
// D.Decode
Controller D_IA_ctrl (
D.IA_inst,
D.IA,
D.IA_imm,
D.IA_sa
.inst(D.IA_inst),
.eq (D_IA_ForwardS == D_IA_ForwardT),
.ltz (D_IA_ForwardS[31]),
.ctrl(D.IA),
.imm (D.IA_imm),
.sa (D.IA_sa)
);
Controller D_IB_ctrl (
D.IB_inst,
D.IB,
D.IB_imm,
D.IB_sa
.inst(D.IB_inst),
.eq (D_IB_ForwardS == D_IB_ForwardT),
.ltz (D_IB_ForwardS[31]),
.ctrl(D.IB),
.imm (D.IB_imm),
.sa (D.IB_sa)
);
// D.Exc
@ -284,19 +325,237 @@ module Datapath (
assign D.IB_Delay = D.IA.PFCtrl.BJRJ;
// D.Dispatch
assign D_IA_DataHazard = E.I0.RW & D.IA.RS == E.I0.RD & D.IA.SA == RS & E.I0.RS0 != ALUOut
| E.I1.RW & D.IA.RS == E.I1.RD & D.IA.SA == RS & E.I1.MR
| E.I0.RW & D.IA.RT == E.I0.RD & D.IA.SB == RT & E.I0.RS0 != ALUOut
| E.I1.RW & D.IA.RT == E.I1.RD & D.IA.SB == RT & E.I1.MR
| E.I0.RW & D.IA.RS == E.I0.RD & D.IA.BJR
| E.I1.RW & D.IA.RS == E.I1.RD & D.IA.BJR
| E.I0.RW & D.IA.RT == E.I0.RD & D.IA.BE
| E.I1.RW & D.IA.RT == E.I1.RD & D.IA.BE
| M.I0.RW & D.IA.RS == M.I0.RD & D.IA.BJR & M.I0.RS0 != ALUOut
| M.I1.RW & D.IA.RS == M.I1.RD & D.IA.BJR & M.I1.MR
| M.I0.RW & D.IA.RT == M.I0.RD & D.IA.BE & M.I0.RS0 != ALUOut
| M.I1.RW & D.IA.RT == M.I1.RD & D.IA.BE & M.I1.MR;
assign D_IB_DataHazard = E.I0.RW & D.IB.RS == E.I0.RD & D.IB.SA == RS & E.I0.RS0 != ALUOut
| E.I1.RW & D.IB.RS == E.I1.RD & D.IB.SA == RS & E.I1.MR
| E.I0.RW & D.IB.RT == E.I0.RD & D.IB.SB == RT & E.I0.RS0 != ALUOut
| E.I1.RW & D.IB.RT == E.I1.RD & D.IB.SB == RT & E.I1.MR
| D.IA.RW & D.IB.RS == D.IA.RD & D.IB.SA == RS
| D.IA.RW & D.IB.RT == D.IA.RD & D.IB.SB == RT
| D.IA.RW & D.IB.RS == D.IA.RD & (D.IB.HW | D.IB.LW) & D.IB.HLS == HLRS & D.IA.MR
| D.IA.RW & D.IB.RT == D.IA.RD & D.IB.C0W & D.IA.MR;
assign D.A = (D.IA.DP0 & D.IA.DP1 | D.IA_ExcValid) ? D.IB.DP0 : D.IA.DP1;
// D.BJRJ
assign D_IA_readygo = ~D_IA_DataHazard;
assign D_IB_readygo = ~D_IB_DataHazard & ~D.IB.BJRJ & (D.A ? D.IB.DP0 : D.IB.DP1);
assign D_en0f = ~D_IA_valid | (D_IA_readygo | D.IA_ExcValid) & E.en;
assign D.en0 = ~D_IA_valid | D_go & E.en;
assign D.en1 = ~D_IB_valid | D.IA_ExcValid | D.IB_ExcValid | D_IB_readygo;
assign D_go = fetch_i.req & fetch_i.addr_ok & D_IA_readygo | D.IA_ExcValid;
assign D_IA_go = D_IA_valid & ~D.IA_ExcValid;
assign D_IB_go = D_IB_valid & ~D.IB_ExcValid & D_IB_readygo & ~D.IA_ExcValid;
assign D_I0_go = D.A ? D_IB_go : D_IA_go;
assign D.I0.pc = D.A ? D.IB_pc : D.IA_pc;
assign D.I0.ExcValid = D.A ? D.IB_ExcValid : D.IA_ExcValid;
assign D.I0.ERET = D.A ? D.IB_ERET : D.IA_ERET;
assign D.I0.ExcCode = D.A ? D.IB_ExcCode : D.IA_ExcCode;
assign D.I0.Delay = D.A ? D.IB_Delay : D.IA_Delay;
assign D.I0.OFA = D.A ? D.IB.OFA : D.IA.OFA;
assign D.I0.RS = D.A ? D.IB.RS : D.IA.RS;
assign D.I0.RT = D.A ? D.IB.RT : D.IA.RT;
assign D.I0.S = D.A ? D_IB_ForwardS : D_IA_ForwardS;
assign D.I0.T = D.A ? D_IB_ForwardT : D_IA_ForwardT;
assign D.I0.imm = D.A ? D.IB_imm : D.IA_imm;
assign D.I0.sa = D.A ? D.IB_sa : D.IA_sa;
assign D.I0.ECtrl = D.A ? D.IB.ECtrl : D.IA.ECtrl;
assign D.I0.MCtrl = D.A ? D.IB.MCtrl : D.IA.MCtrl;
assign D.I0.RD = D.A ? D.IB.RD : D.IA.RD;
assign D.I0.WCtrl = D.A ? D.IB.WCtrl : D.IA.WCtrl;
assign D_I1_go = D.A ? D_IA_go : D_IB_go;
assign D.I1.pc = D.A ? D.IA_pc : D.IB_pc;
assign D.I1.ExcValid = D.A ? D.IA_ExcValid : D.IB_ExcValid;
assign D.I1.ERET = D.A ? D.IA_ERET : D.IB_ERET;
assign D.I1.ExcCode = D.A ? D.IA_ExcCode : D.IB_ExcCode;
assign D.I1.Delay = D.A ? D.IA_Delay : D.IB_Delay;
assign D.I1.OFA = D.A ? D.IA.OFA : D.IB.OFA;
assign D.I1.RS = D.A ? D.IA.RS : D.IB.RS;
assign D.I1.RT = D.A ? D.IA.RT : D.IB.RT;
assign D.I1.S = D.A ? D.IA_ForwardS : D.IB_ForwardS;
assign D.I1.T = D.A ? D.IA_ForwardT : D.IB_ForwardT;
assign D.I1.imm = D.A ? D.IA_imm : D.IB_imm;
assign D.I1.sa = D.A ? D.IA_sa : D.IB_sa;
assign D.I1.ECtrl = D.A ? D.IA.ECtrl : D.IB.ECtrl;
assign D.I1.MCtrl = D.A ? D.IA.MCtrl : D.IB.MCtrl;
assign D.I1.RD = D.A ? D.IA.RD : D.IB.RD;
assign D.I1.WCtrl = D.A ? D.IA.WCtrl : D.IB.WCtrl;
// D.Forwarding
assign D_IA_FS_M_I0 = M.I0.WCtrl.RW & D.IA.RS == M.I0.RD;
assign D_IA_FS_M_I1 = M.I1.WCtrl.RW & D.IA.RS == M.I1.RD;
assign D_IA_FS_W_I0 = W.I0.WCtrl.RW & D.IA.RS == W.I0.RD;
assign D_IA_FS_W_I1 = W.I1.WCtrl.RW & D.IA.RS == W.I1.RD;
mux3 #(32) D_IA_ForwardS_mux (
D.IA_S,
(~D_IA_FS_W_I0 | D_IA_FS_W_I1 & W.A) ? W.I1.RDataW : W.I0.RDataW,
(~D_IA_FS_M_I0 | D_IA_FS_M_I1 & M.A) ? M.I1.ALUOut : M.I0.ALUOut,
{D_IA_FS_M_I0 | D_IA_FS_M_I1, D_IA_FS_W_I0 | D_IA_FS_W_I1},
D_IA_ForwardS
);
assign D_IA_FT_M_I0 = M.I0.WCtrl.RW & D.IA.RT == M.I0.RD;
assign D_IA_FT_M_I1 = M.I1.WCtrl.RW & D.IA.RT == M.I1.RD;
assign D_IA_FT_W_I0 = W.I0.WCtrl.RW & D.IA.RT == W.I0.RD;
assign D_IA_FT_W_I1 = W.I1.WCtrl.RW & D.IA.RT == W.I1.RD;
mux3 #(32) D_IA_ForwardT_mux (
D.IA_T,
(~D_IA_FT_W_I0 | D_IA_FT_W_I1 & W.A) ? W.I1.RDataW : W.I0.RDataW,
(~D_IA_FT_M_I0 | D_IA_FT_M_I1 & M.A) ? M.I1.ALUOut : M.I0.ALUOut,
{D_IA_FT_M_I0 | D_IA_FT_M_I1, D_IA_FT_W_I0 | D_IA_FT_W_I1},
D_IA_ForwardT
);
assign D_IB_FS_M_I0 = M.I0.WCtrl.RW & D.IB.RS == M.I0.RD;
assign D_IB_FS_M_I1 = M.I1.WCtrl.RW & D.IB.RS == M.I1.RD;
assign D_IB_FS_W_I0 = W.I0.WCtrl.RW & D.IB.RS == W.I0.RD;
assign D_IB_FS_W_I1 = W.I1.WCtrl.RW & D.IB.RS == W.I1.RD;
mux3 #(32) D_IB_ForwardS_mux (
D.IB_S,
(~D_IB_FS_W_I0 | D_IB_FS_W_I1 & W.A) ? W.I1.RDataW : W.I0.RDataW,
(~D_IB_FS_M_I0 | D_IB_FS_M_I1 & M.A) ? M.I1.ALUOut : M.I0.ALUOut,
{D_IB_FS_M_I0 | D_IB_FS_M_I1, D_IB_FS_W_I0 | D_IB_FS_W_I1},
D_IB_ForwardS
);
assign D_IB_FT_M_I0 = M.I0.WCtrl.RW & D.IB.RT == M.I0.RD;
assign D_IB_FT_M_I1 = M.I1.WCtrl.RW & D.IB.RT == M.I1.RD;
assign D_IB_FT_W_I0 = W.I0.WCtrl.RW & D.IB.RT == W.I0.RD;
assign D_IB_FT_W_I1 = W.I1.WCtrl.RW & D.IB.RT == W.I1.RD;
mux3 #(32) D_IB_ForwardT_mux (
D.IB_T,
(~D_IB_FT_W_I0 | D_IB_FT_W_I1 & W.A) ? W.I1.RDataW : W.I0.RDataW,
(~D_IB_FT_M_I0 | D_IB_FT_M_I1 & M.A) ? M.I1.ALUOut : M.I0.ALUOut,
{D_IB_FT_M_I0 | D_IB_FT_M_I1, D_IB_FT_W_I0 | D_IB_FT_W_I1},
D_IB_ForwardT
);
//---------------------------------------------------------------------------//
// Execute Stage //
//---------------------------------------------------------------------------//
// E.FF
ffen #(1) E_A_ff (
clk,
D.A,
E.en,
E.A
);
ffen #(32) E_I0_pc_ff (
clk,
D.I0.pc,
E.en,
E.I0.pc
);
ffenrc #(1 + 1 + 5 + 32 + 1 + 1) E_I0_Exc_ff (
clk,
rst,
{D.I0.ExcValid, D.I0.ERET, D.I0.ExcCode, D.I0.BadVAddr, D.I0.Delay, D.I0.OFA},
E.en,
~D_go,
{E.I0.ExcValid, E.I0.ERET, E.I0.ExcCode, E.I0.BadVAddr, E.I0.Delay, E.I0.OFA}
);
ffen #(5 + 5 + 32 + 32) E_I0_ST_ff (
clk,
{D.I0.RS, D.I0.RT, D.I0.S, D.I0.T},
E.en,
{E.I0.RS, E.I0.RT, E.I0.S, E.I0.T}
);
ffen #(32 + 5) E_I0_IS_ff (
clk,
{D.I0.imm, D.I0.sa},
E.en,
{E.I0.imm, D.I0.sa}
);
ffenrc #(10) E_I0_ECtrl_ff (
clk,
rst,
D.I0.ECtrl,
E.en,
~D_go | ~D_I0_go,
E.I0.ECtrl
);
ffenrc #(10) E_I0_MCtrl_ff (
clk,
rst,
D.I0.MCtrl,
E.en,
~D_go | ~D_I0_go,
E.I0.MCtrl
);
ffenrc #(5 + 1) E_I0_WCtrl_ff (
clk,
rst,
{D.I0.RD, D.I0.WCtrl},
E.en,
~D_go | ~D_I0_go,
{E.I0.RD, E.I0.WCtrl}
);
ffen #(32) E_I1_pc_ff (
clk,
D.I1.pc,
E.en,
E.I1.pc
);
ffenrc #(1 + 1 + 5 + 32 + 1 + 1) E_I1_Exc_ff (
clk,
rst,
{D.I1.ExcValid, D.I1.ERET, D.I1.ExcCode, D.I1.BadVAddr, D.I1.Delay, D.I1.OFA},
E.en,
~D_go,
{E.I1.ExcValid, E.I1.ERET, E.I1.ExcCode, E.I1.BadVAddr, E.I1.Delay, E.I1.OFA}
);
ffen #(5 + 5 + 32 + 32) E_I1_ST_ff (
clk,
{D.I1.RS, D.I1.RT, D.I1.S, D.I1.T},
E.en,
{E.I1.RS, E.I1.RT, E.I1.S, E.I1.T}
);
ffen #(32 + 5) E_I1_IS_ff (
clk,
{D.I1.imm, D.I1.sa},
E.en,
{E.I1.imm, D.I1.sa}
);
ffenrc #(10) E_I1_ECtrl_ff (
clk,
rst,
D.I1.ECtrl,
E.en,
~D_go | ~D_I1_go,
E.I1.ECtrl
);
ffenrc #(10) E_I1_MCtrl_ff (
clk,
rst,
D.I1.MCtrl,
E.en,
~D_go | ~D_I1_go,
E.I1.MCtrl
);
ffenrc #(5 + 1) E_I1_WCtrl_ff (
clk,
rst,
{D.I1.RD, D.I1.WCtrl},
E.en,
~D_go | ~D_I1_go,
{E.I1.RD, E.I1.WCtrl}
);
// E.Exc
assign E_I0_NowExcValid = E_I0_Overflow & E.I0.OFA;
@ -311,24 +570,23 @@ module Datapath (
assign E_I0_go = ~E_I0_NowExcValid & (~E.A | ~E_I1_NowExcValid);
assign E_I1_go = ~E_I1_NowExcValid & (E.A | ~E_I0_NowExcValid);
// TODO: SA SB 顺序
// E.I0.ALU
mux4 #(32) E_I0_A_mux (
32'd0,
E.I0.pc,
{27'b0, E.I0.sa},
E.I0.pc,
32'd0,
E_I0_ForwardS,
E.I0.ECtrl.SA,
E_I0_A
);
mux3 #(32) E_I0_B_mux (
E_I0_ForwardT,
32'd8,
E.I0.imm,
E_I0_ForwardT,
E.I0.ECtrl.SB,
E_I0_B
);
ALU E_I0_ (
ALU E_I0_ALU (
E_I0_A,
E_I0_B,
E.I0.ECtrl.OP,
@ -346,21 +604,21 @@ module Datapath (
// E.I1.ALU
mux4 #(32) E_I1_A_mux (
32'd0,
E.I1.pc,
{27'b0, E.I1.sa},
E.I1.pc,
32'd0,
E_I1_ForwardS,
E.I1.ECtrl.SA,
E_I1_A
);
mux3 #(32) E_I1_B_mux (
E_I1_ForwardT,
32'd8,
E.I1.imm,
E_I1_ForwardT,
E.I1.ECtrl.SB,
E_I1_B
);
ALU E_I1_alu (
ALU E_I1_ALU (
E_I1_A,
E_I1_B,
E.I1.ECtrl.OP,
@ -385,49 +643,49 @@ module Datapath (
// E.Forwarding
assign E_I0_FS_M_I0 = M.I0.WCtrl.RW & E.I0.RS == M.I0.RD;
assign E_I0_FS_M_I1 = M.I1.WCtrl.RW & E.I0.RS == M.I1.RD & ~M.I1.MCtrl.MR;
assign E_I0_FS_M_I1 = M.I1.WCtrl.RW & E.I0.RS == M.I1.RD;
assign E_I0_FS_W_I0 = W.I0.WCtrl.RW & E.I0.RS == W.I0.RD;
assign E_I0_FS_W_I1 = W.I1.WCtrl.RW & E.I0.RS == W.I1.RD;
mux3 #(32) E_I0_ForwardS_mux (
E.I0.S,
(~E_I0_FS_W_I0 | E_I0_FS_W_I1 & W.A) ? W.I1.RDataW : W.I0.RDataW,
(~E_I0_FS_M_I0 | E_I0_FS_M_I1 & M.A) ? M.I1.ALUOut : M.I0.RDataW,
(~E_I0_FS_M_I0 | E_I0_FS_M_I1 & M.A) ? M.I1.ALUOut : M.I0.ALUOut,
{E_I0_FS_M_I0 | E_I0_FS_M_I1, E_I0_FS_W_I0 | E_I0_FS_W_I1},
E_I0_ForwardS
);
assign E_I0_FT_M_I0 = M.I0.WCtrl.RW & E.I0.RT == M.I0.RD;
assign E_I0_FT_M_I1 = M.I1.WCtrl.RW & E.I0.RT == M.I1.RD & ~M.I1.MCtrl.MR;
assign E_I0_FT_M_I1 = M.I1.WCtrl.RW & E.I0.RT == M.I1.RD;
assign E_I0_FT_W_I0 = W.I0.WCtrl.RW & E.I0.RT == W.I0.RD;
assign E_I0_FT_W_I1 = W.I1.WCtrl.RW & E.I0.RT == W.I1.RD;
mux3 #(32) E_I0_ForwardT_mux (
E.I0.T,
(~E_I0_FT_W_I0 | E_I0_FT_W_I1 & W.A) ? W.I1.RDataW : W.I0.RDataW,
(~E_I0_FT_M_I0 | E_I0_FT_M_I1 & M.A) ? M.I1.ALUOut : M.I0.RDataW,
(~E_I0_FT_M_I0 | E_I0_FT_M_I1 & M.A) ? M.I1.ALUOut : M.I0.ALUOut,
{E_I0_FT_M_I0 | E_I0_FT_M_I1, E_I0_FT_W_I0 | E_I0_FT_W_I1},
E_I0_ForwardT
);
assign E_I1_FS_M_I0 = M.I0.WCtrl.RW & E.I1.RS == M.I0.RD;
assign E_I1_FS_M_I1 = M.I1.WCtrl.RW & E.I1.RS == M.I1.RD & ~M.I1.MCtrl.MR;
assign E_I1_FS_M_I1 = M.I1.WCtrl.RW & E.I1.RS == M.I1.RD;
assign E_I1_FS_W_I0 = W.I0.WCtrl.RW & E.I1.RS == W.I0.RD;
assign E_I1_FS_W_I1 = W.I1.WCtrl.RW & E.I1.RS == W.I1.RD;
mux3 #(32) E_I1_ForwardS_mux (
E.I1.S,
(~E_I1_FS_W_I0 | E_I1_FS_W_I1 & W.A) ? W.I1.RDataW : W.I0.RDataW,
(~E_I1_FS_M_I0 | E_I1_FS_M_I1 & M.A) ? M.I1.ALUOut : M.I0.RDataW,
(~E_I1_FS_M_I0 | E_I1_FS_M_I1 & M.A) ? M.I1.ALUOut : M.I0.ALUOut,
{E_I1_FS_M_I0 | E_I1_FS_M_I1, E_I1_FS_W_I0 | E_I1_FS_W_I1},
E_I1_ForwardS
);
assign E_I1_FT_M_I0 = M.I0.WCtrl.RW & E.I1.RT == M.I0.RD;
assign E_I1_FT_M_I1 = M.I1.WCtrl.RW & E.I1.RT == M.I1.RD & ~M.I1.MCtrl.MR;
assign E_I1_FT_M_I1 = M.I1.WCtrl.RW & E.I1.RT == M.I1.RD;
assign E_I1_FT_W_I0 = W.I0.WCtrl.RW & E.I1.RT == W.I0.RD;
assign E_I1_FT_W_I1 = W.I1.WCtrl.RW & E.I1.RT == W.I1.RD;
mux3 #(32) E_I1_ForwardT_mux (
E.I1.T,
(~E_I1_FT_W_I0 | E_I1_FT_W_I1 & W.A) ? W.I1.RDataW : W.I0.RDataW,
(~E_I1_FT_M_I0 | E_I1_FT_M_I1 & M.A) ? M.I1.ALUOut : M.I0.RDataW,
(~E_I1_FT_M_I0 | E_I1_FT_M_I1 & M.A) ? M.I1.ALUOut : M.I0.ALUOut,
{E_I1_FT_M_I0 | E_I1_FT_M_I1, E_I1_FT_W_I0 | E_I1_FT_W_I1},
E_I1_ForwardT
);
@ -440,7 +698,7 @@ module Datapath (
ffen #(1) M_A_ff (
clk,
E.A,
E.en,
M.en,
M.A
);
ffen #(32) M_I0_pc_ff (
@ -459,7 +717,7 @@ module Datapath (
);
ffen #(5 + 5 + 32 + 32) M_I0_ST_ff (
clk,
{E.I0.RS, E.I0.RT, E.I0.S, E.I0.T},
{E.I0.RS, E.I0.RT, E_I0_ForwardS, E_I0_ForwardT},
M.en,
{M.I0.RS, M.I0.RT, M.I0.S, M.I0.T}
);
@ -521,7 +779,7 @@ module Datapath (
);
ffen #(5 + 32) M_I1_T_ff (
clk,
{E.I1.RT, E.I1.T},
{E.I1.RT, E_I1_ForwardT},
M.en,
{M.I1.RT, M.I1.T}
);
@ -557,9 +815,9 @@ module Datapath (
// M.I0.HILOC0
mux4 #(32) M_I0_RDataW_mux (
M.I0.ALUOut,
HI,
LO,
HI,
M.I0.ALUOut,
C0_rdata,
M.I0.MCtrl.RS0,
M.I0.RDataW
@ -642,7 +900,7 @@ module Datapath (
assign M_go = ~M.I1.MCtrl.MR | mem_i.data_ok;
// M.Forwarding
assign M_I0_FS_M_I1 = M.A & M.I1.WCtrl.RW & M.I0.RS == M.I1.RD & ~M.I1.MCtrl.MR;
assign M_I0_FS_M_I1 = M.A & M.I1.WCtrl.RW & M.I0.RS == M.I1.RD;
assign M_I0_FS_W_I0 = W.I0.WCtrl.RW & M.I0.RS == W.I0.RD;
assign M_I0_FS_W_I1 = W.I1.WCtrl.RW & M.I0.RS == W.I1.RD;
mux3 #(32) M_I0_ForwardS_mux (
@ -653,7 +911,7 @@ module Datapath (
M_I0_ForwardS
);
assign M_I0_FT_M_I1 = M.A & M.I1.WCtrl.RW & M.I0.RT == M.I1.RD & ~M.I1.MCtrl.MR;
assign M_I0_FT_M_I1 = M.A & M.I1.WCtrl.RW & M.I0.RT == M.I1.RD;
assign M_I0_FT_W_I0 = W.I0.WCtrl.RW & M.I0.RT == W.I0.RD;
assign M_I0_FT_W_I1 = W.I1.WCtrl.RW & M.I0.RT == W.I1.RD;
mux3 #(32) M_I0_ForwardT_mux (
@ -670,7 +928,7 @@ module Datapath (
mux3 #(32) M_I1_ForwardT_mux (
M.I1.T,
(~M_I1_FT_W_I0 | M_I1_FT_W_I1 & W.A) ? W.I1.RDataW : W.I0.RDataW,
M.I0.RDataW,
M.I0.ALUOut,
{M_I1_FT_M_I0, M_I1_FT_W_I0 | M_I1_FT_W_I1},
M_I1_ForwardT
);

View File

@ -29,11 +29,12 @@ module InstrQueue (
word_t dp1, dp2, dp3, dp4, qp1, qp2, qp3, qp4;
logic [5:0] judge;
assign judge = {qv4, qv3, qv2, qv1, enA, enB};
assign valids = {qv4, qv3, qv2, qv1};
// assign valids = {qv4, qv3, qv2, qv1};
assign valids = {qv1, qv2, qv3, qv4};
assign en1 = ~judge[2] | judge[1];
assign en2 = ~judge[3] | judge[1];
assign en3 = (~judge[3] & ~judge[1] & judge[2] | judge[3] & (~judge[1] & ~judge[4] | judge[1] & (~judge[4] & ~judge[0] | judge[4])));
assign en4 = (~judge[4] & judge[3] & ~judge[1] | judge[4] & (~judge[1] & ~judge[5] | judge[1] & (~judge[5] & ~judge[0] | judge[5])));
assign en3 = (~judge[3] & judge[2] & ~judge[1] & ~judge[0] | judge[3] & (~judge[1] & ~judge[4] & ~judge[0] | judge[1] & (~judge[0] | judge[4])));
assign en4 = judge[3] & (~judge[0] & (~judge[5] & (~judge[1] | judge[4]) | judge[5] & judge[1]) | judge[0] & judge[5] & judge[1]);
assign {outA, outB, poutA, poutB} = {qi1, qi2, qp1, qp2};
assign voutA = judge[2] & ~rst;

View File

@ -1,82 +1,82 @@
`include "sram.svh"
// `include "sram.svh"
module Issue(
input clk, rst,
sramro_i.master fetch_i);
// module Issue(
// input clk, rst,
// sramro_i.master fetch_i);
wire logic validF, goF1, goF2;
wire logic enD, validD, goD;
// wire logic validF, goF1, goF2;
// wire logic enD, validD, goD;
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
// //----------------------------------------------------------------------------//
// //----------------------------------------------------------------------------//
// pre-fetch
// assign pcp8F = {pcF[31:3], 3'b000} + 8;
// assign pcbF = pcF + {{14{instrD[15]}}, instrD[15:0], 2'b0};
// assign pcjF = {pcF[31:28], instrD[25:0], 2'b0};
// assign pcjrF = datasD;
logic [31:0] pcp4F, pcp8F, pcF, nextpcF;
logic [31:0] pcb1F, pcj1F, pcjr1F;
logic [31:0] pcb2F, pcj2F, pcjr2F;
logic [31:0] pcbF, pcjF, pcjrF;
logic [31:0] EPCF;
logic enF;
logic [31:0] instrD;
logic jsrcD;
logic [2:0] pcsrcD;
mux2#(96) pcj_mux({pcb1F, pcj1F, pcjr1F}, {pcb2F, pcj2F, pcjr2F}, jsrcD, {pcbF, pcjF, pcjrF});
mux6#(32) nextpc_mux(pcp4F, pcp8F, EPCF, pcbF, pcjF, pcjrF, pcsrcD, nextpcF);
// // pre-fetch
// // assign pcp8F = {pcF[31:3], 3'b000} + 8;
// // assign pcbF = pcF + {{14{instrD[15]}}, instrD[15:0], 2'b0};
// // assign pcjF = {pcF[31:28], instrD[25:0], 2'b0};
// // assign pcjrF = datasD;
// logic [31:0] pcp4F, pcp8F, pcF, nextpcF;
// logic [31:0] pcb1F, pcj1F, pcjr1F;
// logic [31:0] pcb2F, pcj2F, pcjr2F;
// logic [31:0] pcbF, pcjF, pcjrF;
// logic [31:0] EPCF;
// logic enF;
// logic [31:0] instrD;
// logic jsrcD;
// logic [2:0] pcsrcD;
// mux2#(96) pcj_mux({pcb1F, pcj1F, pcjr1F}, {pcb2F, pcj2F, pcjr2F}, jsrcD, {pcbF, pcjF, pcjrF});
// // mux6#(32) nextpc_mux(pcp4F, pcp8F, EPCF, pcbF, pcjF, pcjrF, pcsrcD, nextpcF);
assign fetch_i.req = enF;
assign fetch_i.addr = nextpcF;
// assign fetch_i.req = enF;
// assign fetch_i.addr = nextpcF;
// fetch stage logic
ffenr#(1) valid_ffF(clk, rst, 1'b1, enF, validF);
pcenr pc_reg(clk, rst, nextpcF, enF, pcF);
// // fetch stage logic
// ffenr#(1) valid_ffF(clk, rst, 1'b1, enF, validF);
// pcenr pc_reg(clk, rst, nextpcF, enF, pcF);
assign enF = fetch_i.data_ok;
assign goF1 = validF & enF;
assign goF2 = validF & enF;
// assign enF = fetch_i.data_ok;
// assign goF1 = validF & enF;
// assign goF2 = validF & enF;
HandShake HS_iq_in1(), HS_iq_in2();
HandShake HS_iq_out1(), HS_iq_out2();
logic [31:0] instr_toD1, instr_toD2, pc_toD1, pc_toD2;
logic iq_clear = 1'b0;
// TODO: if allowin == 0?
assign HS_iq_in1.readygo = goF1;
assign HS_iq_in2.readygo = goF2;
InstrQueue InstrQueue (
.clk(clk),
.rst(rst),
.HandShake_in1(HS_iq_in1),
.in1(fetch_i.rdata0),
.pin1(pcF),
.HandShake_in2(HS_iq_in2),
.in2(fetch_i.rdata1),
.pin2(pcF + 4),
.HandShake_out1(HS_iq_out1),
.out1(instr_toD1),
.pout1(pc_toD1),
.HandShake_out2(HS_iq_out2),
.out2(instr_toD2),
.pout2(pc_toD2),
.clear(iq_clear) //flush, will ignore the current input, need to keep the input instr!
);
// HandShake HS_iq_in1(), HS_iq_in2();
// HandShake HS_iq_out1(), HS_iq_out2();
// logic [31:0] instr_toD1, instr_toD2, pc_toD1, pc_toD2;
// logic iq_clear = 1'b0;
// // TODO: if allowin == 0?
// assign HS_iq_in1.readygo = goF1;
// assign HS_iq_in2.readygo = goF2;
// InstrQueue InstrQueue (
// .clk(clk),
// .rst(rst),
// .HandShake_in1(HS_iq_in1),
// .in1(fetch_i.rdata0),
// .pin1(pcF),
// .HandShake_in2(HS_iq_in2),
// .in2(fetch_i.rdata1),
// .pin2(pcF + 4),
// .HandShake_out1(HS_iq_out1),
// .out1(instr_toD1),
// .pout1(pc_toD1),
// .HandShake_out2(HS_iq_out2),
// .out2(instr_toD2),
// .pout2(pc_toD2),
// .clear(iq_clear) //flush, will ignore the current input, need to keep the input instr!
// );
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
// //----------------------------------------------------------------------------//
// //----------------------------------------------------------------------------//
ffenr#(1) valid_ffD(clk, rst, goF1, enD, validD);
ffen#(32) instr_ffD(clk, fetch_i.rdata0, enD, instrD);
// ffenr#(1) valid_ffD(clk, rst, goF1, enD, validD);
// ffen#(32) instr_ffD(clk, fetch_i.rdata0, enD, instrD);
// controller
// controller c(instrD, pcsrcD, rsD, rtD, rdD, immD);
// // controller
// // controller c(instrD, pcsrcD, rsD, rtD, rdD, immD);
// register file (operates in decode and writeback)
// RF rf(clk, rst, rsD, rtD, datasD, datatD, rdW, datawW, regwriteW);
// // register file (operates in decode and writeback)
// // RF rf(clk, rst, rsD, rtD, datasD, datatD, rdW, datawW, regwriteW);
assign enD = fetch_i.addr_ok;
// assign goD = validD & enD;
assign goD = validD;
// assign enD = fetch_i.addr_ok;
// // assign goD = validD & enD;
// assign goD = validD;
endmodule
// endmodule

View File

@ -140,6 +140,22 @@ module prio_mux4 #(
endmodule
module prio_mux5 #(
parameter WIDTH = 8
) (
input logic [WIDTH-1:0] d0,
input logic [WIDTH-1:0] d1,
input logic [WIDTH-1:0] d2,
input logic [WIDTH-1:0] d3,
input logic [WIDTH-1:0] d4,
input logic [ 3:0] s,
output logic [WIDTH-1:0] q
);
assign q = s[3] ? d4 : s[2] ? d3 : s[1] ? d2 : s[0] ? d1 : d0;
endmodule
module extender #(
parameter OWIDTH = 8,
parameter IWIDTH = 8

View File

@ -2,7 +2,7 @@ module mycpu_top (
input wire [5:0] ext_int, //high active
input wire aclk,
input wire aresetn, //low active
input wire aresetn, //low active
output wire [ 3:0] arid,
output wire [31:0] araddr,
@ -49,7 +49,14 @@ module mycpu_top (
output wire [31:0] debug_wb_pc,
output wire [ 3:0] debug_wb_rf_wen,
output wire [ 4:0] debug_wb_rf_wnum,
output wire [31:0] debug_wb_rf_wdata
output wire [31:0] debug_wb_rf_wdata,
output wire [31:0] debug_wb1_pc,
output wire [ 3:0] debug_wb1_rf_wen,
output wire [ 4:0] debug_wb1_rf_wnum,
output wire [31:0] debug_wb1_rf_wdata,
output wire debug_wb_pc_A
);
endmodule

View File

@ -46,22 +46,22 @@ typedef enum logic [1:0] {
} PCS_t;
typedef enum logic [1:0] {
ZERO = 2'b00,
SA = 2'b11,
RS = 2'b10,
PC = 2'b01
SA = 2'b00,
PC = 2'b01,
ZERO = 2'b10,
RS = 2'b11
} SA_t;
typedef enum logic [1:0] {
RT = 2'b00,
EIGHT = 2'b01,
RT = 2'b10,
IMM = 2'b00
IMM = 2'b11
} SB_t;
typedef enum logic [1:0] {
ALUOut = 2'b10,
HI = 2'b01,
LO = 2'b00,
HI = 2'b01,
ALUOut = 2'b10,
C0 = 2'b11
} RS0_t;
@ -144,6 +144,8 @@ typedef struct packed {
logic en0, en1;
Ctrl_t IA, IB;
logic A;
word_t IA_pc;
word_t IA_inst;
logic IA_ExcValid;
@ -165,6 +167,56 @@ typedef struct packed {
word_t IB_T;
word_t IB_imm;
logic [4:0] IB_sa;
struct packed {
word_t pc;
logic ExcValid;
logic ERET;
logic [4:0] ExcCode;
logic Delay;
logic OFA;
logic [4:0] RS;
logic [4:0] RT;
word_t S;
word_t T;
word_t imm;
logic [4:0] sa;
ECtrl_t ECtrl;
MCtrl0_t MCtrl;
logic [4:0] RD;
WCtrl_t WCtrl;
} I0;
struct packed {
word_t pc;
logic ExcValid;
logic ERET;
logic [4:0] ExcCode;
logic Delay;
logic OFA;
logic [4:0] RS;
logic [4:0] RT;
word_t S;
word_t T;
word_t imm;
logic [4:0] sa;
ECtrl_t ECtrl;
MCtrl1_t MCtrl;
logic [4:0] RD;
WCtrl_t WCtrl;
} I1;
} D_t;
typedef struct packed {

View File

@ -14,6 +14,16 @@ SA
'PC': 2'b01
'0' : 2'b00
SA
{'SA': '~[30] & ~[29] & ~[31] & ~[26] & ~[28] & ~[27] & ~[5] & (~[1] & ~[4] & ~[3] & ~[2] | [1] & ~[3] & ~[4] & ~[2])', 'RS': '~[30] & (~[29] & (~[31] & ~[26] & ~[28] & ~[27] & (~[5] & (~[1] & (~[4] & ~[3] & [2] | [4] & [3]) | [1] & (~[3] & ~[4] & [2] | [3])) | [5]) | [31]) | [29] & (~[28] | [28] & (~[27] | [27] & ~[26])))', 'PC': '~[30] & ~[29] & ~[31] & (~[26] & (~[28] & (~[27] & ~[5] & (~[1] & (~[4] & [3] | [4] & ~[3]) | [1] & ~[3] & [4]) | [27]) | [28]) | [26])', '0': '(~[30] & [29] & [28] & [27] & [26] | [30])'}
1
{'0': '~[29] & ~[31] & (~[26] & (~[28] & ~[30] & (~[27] & ~[5] & (~[2] & (~[3] | [3] & ~[4]) | [2] & [3]) | [27]) | [28]) | [26])', '1': '(~[29] & (~[31] & ~[26] & ~[28] & (~[30] & ~[27] & (~[5] & (~[2] & [3] & [4] | [2] & ~[3]) | [5]) | [30]) | [31]) | [29])'}
0
{'0': '(~[30] & ~[31] & (~[29] & ~[26] & ~[28] & ~[27] & ~[5] & ~[4] & ~[2] & ~[3] | [29] & [28] & [27] & [26]) | [30])', '1': '~[30] & (~[31] & (~[29] & (~[26] & (~[28] & (~[27] & (~[5] & (~[4] & (~[2] & [3] | [2]) | [4]) | [5]) | [27]) | [28]) | [26]) | [29] & (~[28] | [28] & (~[27] | [27] & ~[26]))) | [31])'}
{((~inst[26] & ~inst[28] & (~inst[27] & ((~inst[2] & inst[3] & inst[4] | inst[2] & ~inst[3]) | inst[5]) | inst[30]) | inst[31]) | inst[29]),~inst[30] & ((~inst[29] & (inst[3] | inst[2] | inst[4] | inst[5] | inst[27] | inst[28] | inst[26]) | inst[29] & (~inst[28] | ~inst[27] | ~inst[26])) | inst[31])}
SB
'RT': '~inst[29] & ~inst[31] & ~inst[26] & ~inst[30] & ~inst[28] & ~inst[27] & (~inst[5] & (~inst[1] & (~inst[0] & (~inst[3] & ~inst[4] | inst[3] & inst[4]) | inst[0] & inst[4] & inst[3]) | inst[1] & (~inst[4] | inst[4] & inst[3])) | inst[5])'
@ -27,6 +37,14 @@ RT: 10
8: 01
IMM:00
SB
{'RT': '~[29] & ~[31] & ~[26] & ~[30] & ~[28] & ~[27] & (~[5] & (~[1] & (~[0] & (~[3] & ~[4] | [3] & [4]) | [0] & [4] & [3]) | [1] & (~[4] | [4] & [3])) | [5])', '8': '~[29] & ~[31] & (~[26] & ~[30] & (~[28] & (~[27] & ~[5] & (~[1] & (~[0] & (~[3] & [4] | [3] & ~[4]) | [0] & (~[4] | [4] & ~[3])) | [1] & [4] & ~[3]) | [27]) | [28]) | [26])', 'IMM': '(~[29] & (~[31] & ~[26] & [30] | [31]) | [29])'}
1
{'0': '~[26] & ~[29] & ~[30] & ~[28] & ~[31] & ~[27] & (~[5] & (~[1] & (~[0] & (~[3] & ~[4] | [3] & [4]) | [0] & [4] & [3]) | [1] & (~[4] | [4] & [3])) | [5])', '1': '(~[26] & (~[29] & (~[30] & (~[28] & (~[31] & (~[27] & ~[5] & (~[1] & (~[0] & (~[3] & [4] | [3] & ~[4]) | [0] & (~[4] | [4] & ~[3])) | [1] & [4] & ~[3]) | [27]) | [31]) | [28]) | [30]) | [29]) | [26])'}
0
{'0': '~[29] & ~[31] & ~[30]', '1': '(~[29] & (~[31] & [30] | [31]) | [29])'}
{(~inst[5] & (~inst[1] & (~inst[0] & (~inst[3] & inst[4] | inst[3] & ~inst[4]) | inst[0] & (~inst[4] | ~inst[3])) | inst[1] & inst[4] & ~inst[3]) | inst[27] | inst[31] | inst[28] | inst[30] | inst[29] | inst[26]),((inst[30] | inst[31]) | inst[29])}
OP
assign ctrl.ECtrl.OP.f_sr = ~inst[31] & ~inst[29] & ~inst[28] & ~inst[27] & ~inst[26] & ~inst[5] & ~inst[3] & (~inst[2] | inst[1]);