From ebcd281f4b077803b0242d144e9813f41d13fafb Mon Sep 17 00:00:00 2001 From: Paul Pan Date: Wed, 28 Jul 2021 16:39:10 +0800 Subject: [PATCH] datapath Co-authored-by: cxy004 Co-authored-by: Hooo1941 --- .../2021/soc_axi_func/rtl/soc_axi_lite_top2.v | 751 ++++++++++++++++++ resources/2021/soc_axi_func/testbench/tb2.sv | 285 +++++++ src/Core/Controller.sv | 28 +- src/Core/Datapath.sv | 338 +++++++- src/Core/InstrQueue.sv | 7 +- src/Core/Issue.sv | 136 ++-- src/Gadgets.sv | 16 + src/MyCPU.sv | 11 +- src/include/defines.svh | 68 +- tools/out2.txt | 18 + 10 files changed, 1523 insertions(+), 135 deletions(-) create mode 100644 resources/2021/soc_axi_func/rtl/soc_axi_lite_top2.v create mode 100644 resources/2021/soc_axi_func/testbench/tb2.sv diff --git a/resources/2021/soc_axi_func/rtl/soc_axi_lite_top2.v b/resources/2021/soc_axi_func/rtl/soc_axi_lite_top2.v new file mode 100644 index 0000000..5ca36a1 --- /dev/null +++ b/resources/2021/soc_axi_func/rtl/soc_axi_lite_top2.v @@ -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 + diff --git a/resources/2021/soc_axi_func/testbench/tb2.sv b/resources/2021/soc_axi_func/testbench/tb2.sv new file mode 100644 index 0000000..b984e06 --- /dev/null +++ b/resources/2021/soc_axi_func/testbench/tb2.sv @@ -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 diff --git a/src/Core/Controller.sv b/src/Core/Controller.sv index 0b70b61..875d762 100644 --- a/src/Core/Controller.sv +++ b/src/Core/Controller.sv @@ -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 diff --git a/src/Core/Datapath.sv b/src/Core/Datapath.sv index 8d041bb..e425b14 100644 --- a/src/Core/Datapath.sv +++ b/src/Core/Datapath.sv @@ -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 ); diff --git a/src/Core/InstrQueue.sv b/src/Core/InstrQueue.sv index f992255..ff844d1 100644 --- a/src/Core/InstrQueue.sv +++ b/src/Core/InstrQueue.sv @@ -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; diff --git a/src/Core/Issue.sv b/src/Core/Issue.sv index d834a77..8bd1bdb 100644 --- a/src/Core/Issue.sv +++ b/src/Core/Issue.sv @@ -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 diff --git a/src/Gadgets.sv b/src/Gadgets.sv index ca22470..463a055 100644 --- a/src/Gadgets.sv +++ b/src/Gadgets.sv @@ -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 diff --git a/src/MyCPU.sv b/src/MyCPU.sv index 3bd5c4a..1406734 100644 --- a/src/MyCPU.sv +++ b/src/MyCPU.sv @@ -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 diff --git a/src/include/defines.svh b/src/include/defines.svh index 6b3a785..09288ff 100644 --- a/src/include/defines.svh +++ b/src/include/defines.svh @@ -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 { diff --git a/tools/out2.txt b/tools/out2.txt index 4f50583..a939441 100644 --- a/tools/out2.txt +++ b/tools/out2.txt @@ -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]);