Compare commits

...

3 Commits

Author SHA1 Message Date
Laraib Khan 4b949f86f7
Delete RELEASE-NOTE.md 2021-04-09 09:21:54 +05:00
komaljaved-lm b40e643c68 updated makefile with lec 2021-04-05 17:09:33 +05:00
komaljaved-lm 31c8526ffe Initialized Quasar 1.0 branch 2021-03-31 18:32:05 +05:00
568 changed files with 36024 additions and 73236 deletions

View File

@ -1,6 +1,6 @@
# Quasar RISC-V Core 2.0 from Lampro Mellon
# Quasar RISC-V Core 1.0 from Lampro Mellon
This repository contains the Quasar Core design in CHISEL.
This repository contains the SweRV-EL2 Core written in CHISEL named "Quasar".
## License
@ -40,22 +40,18 @@ Quasar is a Chiselified version of EL2 SweRV RISC-V Core.
├── generated_rtl # Quasar wrapper
├── testbench
│ ├── asm # Example assembly files
│ ├── hex # Canned demo hex files
│ └── tests # Example tests
│ └── hex # Canned demo hex files
├── tools # Scripts/Makefiles
├── tracer_logs # generated log files
└── verif
├── LEC
├── formality_work
└── formality_log # LEC log files
└── setup_files # user_match files
├── LEC
└── sim # Simulation log/dump files
## Dependencies
- Verilator **(4.102 or later)** must be installed on the system if running with verilator.
- Verilator **(4.030 or later)** must be installed on the system if running with verilator.
- Vcs must be installed on the system if running with vcs.
- RISCV tool chain (based on gcc version 8.3 or higher) must be
- RISCV tool chain (based on gcc version 7.3 or higher) must be
installed so that it can be used to prepare RISCV binaries to run.
- Sbt **(1.3.13 or later)** must be installed on the system.
@ -67,7 +63,7 @@ installed so that it can be used to prepare RISCV binaries to run.
4. Run make with $RV_ROOT/tools/Makefile
## Release Notes for this version
Please see [release-notes](release-notes.md) for changes and bug fixes in this version of Quasar.
Please see [release notes](release-notes.md) for changes and bug fixes in this version of Quasar.
### Configurations
@ -99,8 +95,7 @@ $RV_ROOT/design/snapshots/default
├── pd_defines.vh # `defines for physical design
├── perl_configs.pl # Perl %configs hash for scripting
├── pic_map_auto.h # PIC memory map based on configure size
├── whisper.json # JSON file for swerv-iss
└── link.ld # default linker control file
└── whisper.json # JSON file for swerv-iss
```
#### 1. Generate scala parameter
```
@ -141,9 +136,9 @@ Snapshots are placed in `$BUILD_PATH` directory.
#### 3. Run sbt
```
make -f $RV_ROOT/tools/Makefile sbt_
make -f $RV_ROOT/tools/Makefile sbt
```
This command will generate the Quasar wrapper in system verilog of Quasar chisel, in the `generated_rtl` directory and runs the `reset_script.py`
This command will generate the Quasar wrapper in system verilog in the `generated_rtl` directory and runs the `reset_script.py`
* In the reset_script we do a post verilog-generation changes, these changes are as follows:
* Replace `posedge reset` with `negedge reset`
@ -162,7 +157,7 @@ The simulation produces output on the screen like:
VerilatorTB: Start of sim
----------------------------------
Hello World from QUASAR @LMDC !!
Hello World from Quasar @LM !!
----------------------------------
TEST_PASSED
@ -185,7 +180,21 @@ You can re-execute simulation using:
```
make -f $RV_ROOT/tools/Makefile verilator
```
#### 5. Default for VCS/Verilotor
The simulation run/build command has following generic form:
```
make -f $RV_ROOT/tools/Makefile [<simulator>] [debug=1] [snapshot=mybuild] [target=<target>] [TEST=<test>] [TEST_DIR=<path_to_test_dir>]
```
where:
```
<simulator> - can be 'verilator' (by default) , 'vcs' - Synopsys VCS. if not provided, 'make' cleans work directory, builds verilator executable and runs a test.
debug=1 - allows VCD generation for verilator and VCS and SHM waves for irun option.
<target> - predefined CPU configurations 'default' ( by default), 'default_ahb', 'typical_pd', 'high_perf'.
TEST - allows to run a C (<test>.c) or assembly (<test>.s) test, hello_world is run by default.
TEST_DIR - alternative to test source directory testbench/asm or testbench/tests.
<snapshot> - run and build executable model of custom CPU configuration, remember to provide 'snapshot' argument for runs on custom configurations.
CONF_PARAMS - allows to provide -set options to quasar.conf script to alter predefined targets parameters.
```
#### Default for VCS/Verilotor
If you want to run default configuration on verilator use the following command
```
make -f $RV_ROOT/tools/Makefile
@ -194,21 +203,6 @@ For VCS use
```
make -f $RV_ROOT/tools/Makefile vcs_all
```
The simulation run/build command has following generic form:
```
make -f $RV_ROOT/tools/Makefile [<simulator>] [debug=1] [snapshot=mybuild] [target=<target>] [TEST=<test>] [TEST_DIR=<path_to_test_dir>]
```
where:
```
<simulator> - can be 'verilator' (by default) , 'vcs' - Synopsys VCS, 'riviera'- Aldec Riviera-PRO. If not provided, 'make' cleans work directory, builds verilator executable and runs a test.
debug=1 - allows VCD generation for verilator and VCS and SHM waves for irun option.
<target> - predefined CPU configurations 'default' ( by default), 'default_ahb', 'typical_pd', 'high_perf'.
TEST - allows to run a C (<test>.c) or assembly (<test>.s) test, hello_world is run by default.
TEST_DIR - alternative to test source directory testbench/asm or testbench/tests.
<snapshot> - run and build executable model of custom CPU configuration, remember to provide 'snapshot' argument for runs on custom configurations.
CONF_PARAMS - allows to provide -set options to quasar.conf script to alter predefined targets parameters.
```
Example:
```
make -f $RV_ROOT/tools/Makefile verilator TEST=cmark
@ -220,6 +214,7 @@ If you want to compile a test only, you can run:
```
make -f $RV_ROOT/tools/Makefile program.hex TEST=<test> [TEST_DIR=/path/to/dir]
```
The Makefile uses `snapshot/<target>/link.ld` file, generated by quasar.conf script by default to build test executable. User can provide test specific linker file in form `<test_name>.ld` to build the test executable, in the same directory with the test source.
User also can create a test specific makefile in form `<test_name>.makefile`, containing building instructions how to create `program.hex` file used by simulation. The private makefile should be in the same directory as the test source. See examples in `testbench/asm` directory.
@ -234,27 +229,15 @@ Note: You may need to delete `program.hex` file from work directory, when run a
The `$RV_ROOT/testbench/asm` directory contains following tests ready to simulate:
```
hello_world - default test program to run, prints Hello World message to screen and console.log
hello_world - default tes to run, prints Hello World message to screen and console.log
hello_world_dccm - the same as above, but takes the string from preloaded DCCM.
hello_world_iccm - the same as hello_world, but loads the test code to ICCM via LSU to DMA bridge and then executes it from there. Runs on QUASAR with AXI4 buses only.
hello_world_iccm - the same as hello_world, but loads the test code to ICCM via LSU to DMA bridge and then executes
it from there. Runs on QUASAR with AXI4 buses only.
cmark - coremark benchmark running with code and data in external memories
cmark_dccm - the same as above, running data and stack from DCCM (faster)
cmark_iccm - the same as above with preloaded code to ICCM.
dhry - Run dhrystone. (Scale by 1757 to get DMIPS/MHZ)
cmark_iccm - the same as above with preloaded code to ICCM.
```
The `$RV_ROOT/testbench/hex` directory contains precompiled hex files of the tests, ready for simulation in case RISCV SW tools are not installed.
#### 6. Logical Equivalence Checking of Quasar
If you want to perform LEC on quasar, use the following command
```
make -f $RV_ROOT/tools/Makefile lec
```
This command will call the LEC Makefile to clone Quasar along with the SweRV-EL2 and run `sbt` for chisel-generated RTL. Then, this will take file for user-match the ports, blockbox pins, latches, flops and perform the LEC of Quasar.
Following log files are created in `$RV_ROOT/verif/LEC/formality_work/formality_log` :
`fm_shell_command.log` gives the detail of instructions
`formality.log` gives the detail of undriven nets
**Note**: The testbench has a simple synthesizable bridge that allows you to load the ICCM via load/store instructions. This is only supported for AXI4 builds.

View File

@ -41,4 +41,3 @@ high_perf | Large BTB/BHT, AXI4 interface
`quasar.config` may be edited to add additional target configurations, or new configurations may be created via the command line `-set` or `-unset` options.
**Run `$RV_ROOT/configs/quasar.config -h` for options and settable parameters.**

File diff suppressed because it is too large Load Diff

View File

@ -30,9 +30,6 @@ version := "3.3.0"
scalaVersion := "2.12.10"
// Making the main-class
mainClass in (Compile, run) := Some("wrapper")
crossScalaVersions := Seq("2.12.10", "2.11.12")
resolvers ++= Seq(

View File

@ -1 +0,0 @@
sbt.internal.DslEntry

View File

@ -1,3 +1,3 @@
[debug] "not up to date. inChanged = true, force = false
[debug] Updating ProjectRef(uri("file:/home/users/scratch/komal.javed.data/Quasar/quasar2/design/project/"), "design-build")...
[debug] Done updating ProjectRef(uri("file:/home/users/scratch/komal.javed.data/Quasar/quasar2/design/project/"), "design-build")
[debug] Updating ProjectRef(uri("file:/home/users/scratch/komal.javed.data/Quasar/quasar1_final/design/project/"), "design-build")...
[debug] Done updating ProjectRef(uri("file:/home/users/scratch/komal.javed.data/Quasar/quasar1_final/design/project/"), "design-build")

View File

@ -1 +1 @@
["sbt.Task[scala.collection.Seq[java.nio.file.Path]]",["/home/users/scratch/komal.javed.data/Quasar/k_se_quasar/design/project/target/streams/compile/compileOutputs/_global/streams/inc_compile_2.12.zip"]]
["sbt.Task[scala.collection.Seq[java.nio.file.Path]]",["/home/users/scratch/komal.javed.data/Quasar/quasar1_final/design/project/target/streams/compile/compileOutputs/_global/streams/inc_compile_2.12.zip"]]

View File

@ -1 +1 @@
[debug] Full compilation, no sources in previous analysis.
[debug] Full compilation, no sources in previous analysis.

View File

@ -1,2 +1,2 @@
[debug] Copy resource mappings:
[debug]
[debug] Copy resource mappings: 
[debug]  

View File

@ -1 +1 @@
/home/users/scratch/komal.javed.data/Quasar/k_se_quasar/design/project/target/scala-2.12/sbt-1.0/classes
/home/users/scratch/komal.javed.data/Quasar/quasar1_final/design/project/target/scala-2.12/sbt-1.0/classes

View File

@ -1 +1 @@
/home/users/scratch/komal.javed.data/Quasar/k_se_quasar/design/project/target/scala-2.12/sbt-1.0/classes
/home/users/scratch/komal.javed.data/Quasar/quasar1_final/design/project/target/scala-2.12/sbt-1.0/classes

View File

@ -1 +1 @@
/home/users/scratch/komal.javed.data/Quasar/k_se_quasar/design/project/target/scala-2.12/sbt-1.0/classes
/home/users/scratch/komal.javed.data/Quasar/quasar1_final/design/project/target/scala-2.12/sbt-1.0/classes

View File

@ -1 +1 @@
/home/users/scratch/komal.javed.data/Quasar/k_se_quasar/design/project/target/scala-2.12/sbt-1.0/classes
/home/users/scratch/komal.javed.data/Quasar/quasar1_final/design/project/target/scala-2.12/sbt-1.0/classes

View File

@ -1 +1 @@
/home/users/scratch/komal.javed.data/Quasar/k_se_quasar/design/project/target/scala-2.12/sbt-1.0/classes
/home/users/scratch/komal.javed.data/Quasar/quasar1_final/design/project/target/scala-2.12/sbt-1.0/classes

View File

@ -6,16 +6,15 @@ infile = root+"/design/quasar_wrapper.v"
outfile = root+"/design/quasar_wrapper.sv"
delete_list1 = ["if (dbg_dm_rst_l)"]
delete_list2 = ["if (_T_597)"]
delete_list2 = ["if (rst_temp)"]
delete_list3 = ["if (io_dbg_rst_l)"]
delete_list4 = ["if (reset)"]
delete_list5 = ["posedge reset"]
delete_list6 = ["posedge dbg_dm_rst_l"]
delete_list7 = ["posedge _T_597"]
delete_list7 = ["posedge rst_temp"]
delete_list8 = ["posedge io_dbg_rst_l"]
delete_list9 = ["if (rst_not)"]
delete_list10 = ["posedge rst_not"]
delete_list11 = ["rvclkhdr"]
fin = open(infile)
fout = open(outfile, "w+")
@ -24,7 +23,7 @@ for line in fin:
line = line.replace(word, "if (~dbg_dm_rst_l)")
for word in delete_list2:
line = line.replace(word, "if (~_T_597)")
line = line.replace(word, "if (~rst_temp)")
for word in delete_list3:
line = line.replace(word, "if (~io_dbg_rst_l)")
@ -39,7 +38,7 @@ for line in fin:
line = line.replace(word, "negedge dbg_dm_rst_l")
for word in delete_list7:
line = line.replace(word, "negedge _T_597")
line = line.replace(word, "negedge rst_temp")
for word in delete_list8:
line = line.replace(word, "negedge io_dbg_rst_l")
@ -49,10 +48,6 @@ for line in fin:
for word in delete_list10:
line = line.replace(word, "negedge rst_not")
for word in delete_list11:
line = line.replace(word, "rvclkhdr_ch")
fout.write(line)
fin.close()
fout.close()

View File

@ -1,410 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Peter Gustavsson <peter.gustavsson@qamcom.se>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//********************************************************************************
// $Id$
//
// Function: AXI lite to Wishbone non pipelined bridge
// Comments: Assumes single accesses to a 32bit register on an 64bit aligned address
//
//********************************************************************************
`default_nettype none
module axi2wb
#(parameter AW = 12,
parameter IW = 0)
(
input wire i_clk,
input wire i_rst,
// Wishbone master
output reg [AW-1:2] o_wb_adr,
output reg [31:0] o_wb_dat,
output reg [3:0] o_wb_sel,
output reg o_wb_we,
output reg o_wb_cyc,
output reg o_wb_stb,
input wire [31:0] i_wb_rdt,
input wire i_wb_ack,
input wire i_wb_err,
// AXI slave
// AXI adress write channel
input wire [AW-1:0] i_awaddr,
input wire [IW-1:0] i_awid,
input wire i_awvalid,
output reg o_awready,
//AXI adress read channel
input wire [AW-1:0] i_araddr,
input wire [IW-1:0] i_arid,
input wire i_arvalid,
output reg o_arready,
//AXI write channel
input wire [63:0] i_wdata,
input wire [7:0] i_wstrb,
input wire i_wvalid,
output reg o_wready,
//AXI response channel
output reg [IW-1:0] o_bid,
output wire [1:0] o_bresp,
output reg o_bvalid,
input wire i_bready,
//AXI read channel
output reg [63:0] o_rdata,
output reg [IW-1:0] o_rid,
output wire [1:0] o_rresp,
output wire o_rlast,
output reg o_rvalid,
input wire i_rready
);
assign o_bresp = 2'b00;
assign o_rresp = 2'b00;
assign o_rlast = 1'b1;
reg hi_32b_w;
reg arbiter;
reg [31:0] wb_rdt_low;
parameter STATESIZE = 4;
parameter [STATESIZE-1:0]
IDLE = 4'd0,
AWACK = 4'd1,
WBWACK= 4'd2,
WBRACK1 = 4'd3,
WBR2 = 4'd4,
WBRACK2 = 4'd5,
BAXI = 4'd6,
RRAXI = 4'd7;
reg [STATESIZE-1:0] cs;
// formal helper registers
reg aw_req;
reg w_req;
reg ar_req;
initial o_rvalid = 1'b0;
initial o_bvalid = 1'b0;
initial o_wb_stb = 1'b0;
initial o_wb_cyc = 1'b0;
initial o_wb_we = 1'b0;
initial cs = 4'd0;
initial aw_req = 1'b0;
initial w_req = 1'b0;
initial ar_req = 1'b0;
always @(posedge i_clk) begin
if (i_rst) begin
o_awready <= 1'b0;
o_wready <= 1'b0;
o_arready <= 1'b0;
o_rvalid <= 1'b0;
o_bvalid <= 1'b0;
o_wb_adr <= {AW-2{1'b0}};
o_wb_cyc <= 1'b0;
o_wb_stb <= 1'b0;
o_wb_sel <= 4'd0;
o_wb_we <= 1'b0;
arbiter <= 1'b1;
wb_rdt_low <= 32'hDEADBEEF;
cs <= IDLE;
aw_req <= 1'b0;
w_req <= 1'b0;
ar_req <= 1'b0;
o_bid <= {IW{1'b0}};
o_rid <= {IW{1'b0}};
end
else begin
if (i_awvalid & o_awready)
o_bid <= i_awid;
if (i_arvalid & o_arready)
o_rid <= i_arid;
o_awready <= 1'b0;
o_wready <= 1'b0;
o_arready <= 1'b0;
if (i_awvalid && o_awready)
aw_req <= 1'b1;
else if (i_bready && o_bvalid)
aw_req <= 1'b0;
if (i_wvalid && o_wready)
w_req <= 1'b1;
else if (i_bready && o_bvalid)
w_req <= 1'b0;
if (i_arvalid && o_arready)
ar_req <= 1'b1;
else if (i_rready && o_rvalid)
ar_req <= 1'b0;
case (cs)
IDLE : begin
arbiter <= 1'b1;
if (i_awvalid && arbiter) begin
o_wb_adr[AW-1:3] <= i_awaddr[AW-1:3];
o_awready <= 1'b1;
arbiter <= 1'b0;
if (i_wvalid) begin
hi_32b_w = (i_wstrb[3:0] == 4'h0) ? 1'b1 : 1'b0;
o_wb_adr[2] <= hi_32b_w;
o_wb_cyc <= 1'b1;
o_wb_stb <= 1'b1;
o_wb_sel <= hi_32b_w ? i_wstrb[7:4] : i_wstrb[3:0];
o_wb_dat <= hi_32b_w ? i_wdata[63:32] : i_wdata[31:0];
o_wb_we <= 1'b1;
o_wready <= 1'b1;
cs <= WBWACK;
end
else begin
cs <= AWACK;
end
end
else if (i_arvalid) begin
o_wb_adr[AW-1:2] <= i_araddr[AW-1:2];
o_wb_sel <= 4'hF;
o_wb_cyc <= 1'b1;
o_wb_stb <= 1'b1;
o_arready <= 1'b1;
cs <= WBRACK1;
end
end
AWACK : begin
if (i_wvalid) begin
hi_32b_w = (i_wstrb[3:0] == 4'h0) ? 1'b1 : 1'b0;
o_wb_adr[2] <= hi_32b_w;
o_wb_cyc <= 1'b1;
o_wb_stb <= 1'b1;
o_wb_sel <= hi_32b_w ? i_wstrb[7:4] : i_wstrb[3:0];
o_wb_dat <= hi_32b_w ? i_wdata[63:32] : i_wdata[31:0];
o_wb_we <= 1'b1;
o_wready <= 1'b1;
cs <= WBWACK;
end
end
WBWACK : begin
if ( i_wb_err || i_wb_ack ) begin
o_wb_cyc <= 1'b0;
o_wb_stb <= 1'b0;
o_wb_sel <= 4'h0;
o_wb_we <= 1'b0;
o_bvalid <= 1'b1;
cs <= BAXI;
end
end
WBRACK1 : begin
if ( i_wb_err || i_wb_ack) begin
o_wb_cyc <= 1'b0;
o_wb_stb <= 1'b0;
o_wb_sel <= 4'h0;
wb_rdt_low <= i_wb_rdt;
cs <= WBR2;
end
end
WBR2 : begin
o_wb_adr[2] <= 1'b1;
o_wb_sel <= 4'hF;
o_wb_cyc <= 1'b1;
o_wb_stb <= 1'b1;
cs <= WBRACK2;
end
WBRACK2 : begin
if ( i_wb_err || i_wb_ack) begin
o_wb_cyc <= 1'b0;
o_wb_stb <= 1'b0;
o_wb_sel <= 4'h0;
o_rvalid <= 1'b1;
o_rdata <= {i_wb_rdt, wb_rdt_low};
cs <= RRAXI;
end
end
BAXI : begin
o_bvalid <= 1'b1;
if (i_bready) begin
o_bvalid <= 1'b0;
cs <= IDLE;
end
end
RRAXI : begin
o_rvalid <= 1'b1;
if (i_rready) begin
o_rvalid <= 1'b0;
cs <= IDLE;
end
end
default : begin
o_awready <= 1'b0;
o_wready <= 1'b0;
o_arready <= 1'b0;
o_rvalid <= 1'b0;
o_bvalid <= 1'b0;
o_wb_adr <= {AW-2{1'b0}};
o_wb_cyc <= 1'b0;
o_wb_stb <= 1'b0;
o_wb_sel <= 4'd0;
o_wb_we <= 1'b0;
arbiter <= 1'b1;
cs <= IDLE;
end
endcase
end
end
`ifdef FORMAL
localparam F_LGDEPTH = 4;
wire [(F_LGDEPTH-1):0] faxi_awr_outstanding,
faxi_wr_outstanding,
faxi_rd_outstanding;
faxil_slave
#(
.C_AXI_DATA_WIDTH(64),
.C_AXI_ADDR_WIDTH(AW),
.F_OPT_BRESP (1'b1),
.F_OPT_RRESP (1'b1),
.F_AXI_MAXWAIT (16),
.F_AXI_MAXDELAY (4),
.F_AXI_MAXRSTALL (1),
.F_LGDEPTH(F_LGDEPTH))
faxil_slave
(
.i_clk(i_clk),
.i_axi_reset_n(~i_rst),
//
.i_axi_awaddr(i_awaddr),
.i_axi_awcache(4'h0),
.i_axi_awprot(3'd0),
.i_axi_awvalid(i_awvalid),
.i_axi_awready(o_awready),
//
.i_axi_wdata(i_wdata),
.i_axi_wstrb(i_wstrb),
.i_axi_wvalid(i_wvalid),
.i_axi_wready(o_wready),
//
.i_axi_bresp(2'd0),
.i_axi_bvalid(o_bvalid),
.i_axi_bready(i_bready),
//
.i_axi_araddr(i_araddr),
.i_axi_arprot(3'd0),
.i_axi_arcache(4'h0),
.i_axi_arvalid(i_arvalid),
.i_axi_arready(o_arready),
//
.i_axi_rdata(o_rdata),
.i_axi_rresp(2'd0),
.i_axi_rvalid(o_rvalid),
.i_axi_rready(i_rready),
//
.f_axi_rd_outstanding(faxi_rd_outstanding),
.f_axi_wr_outstanding(faxi_wr_outstanding),
.f_axi_awr_outstanding(faxi_awr_outstanding));
always @(*) begin
assert(faxi_awr_outstanding <= 1);
assert(faxi_wr_outstanding <= 1);
assert(faxi_rd_outstanding <= 1);
case (cs)
IDLE : begin
assert(!o_wb_we);
assert(!o_wb_stb);
assert(!o_wb_cyc);
assert(!aw_req);
assert(!ar_req);
assert(!w_req);
assert(faxi_awr_outstanding == 0);
assert(faxi_wr_outstanding == 0);
assert(faxi_rd_outstanding == 0);
end
AWACK : begin
assert(!o_wb_we);
assert(!o_wb_stb);
assert(!o_wb_cyc);
assert(faxi_awr_outstanding == (aw_req ? 1:0));
assert(faxi_wr_outstanding == 0);
assert(faxi_rd_outstanding == 0);
end
WBWACK : begin
assert(faxi_awr_outstanding == (aw_req ? 1:0));
assert(faxi_wr_outstanding == (w_req ? 1:0));
assert(faxi_rd_outstanding == 0);
end
WBRACK : begin
assert(faxi_awr_outstanding == 0);
assert(faxi_wr_outstanding == 0);
assert(faxi_rd_outstanding == (ar_req ? 1:0));
end
BAXI : begin
assert(faxi_rd_outstanding == 0);
end
RRAXI : begin
assert(faxi_awr_outstanding == 0);
assert(faxi_wr_outstanding == 0);
end
default:
assert(0);
endcase // case (cs)
end
fwbc_master
#(.AW (AW-2),
.DW (32),
.F_MAX_DELAY (4),
.OPT_BUS_ABORT (0))
fwbc_master
(.i_clk (i_clk),
.i_reset (i_rst),
.i_wb_addr (o_wb_adr),
.i_wb_data (o_wb_dat),
.i_wb_sel (o_wb_sel),
.i_wb_we (o_wb_we),
.i_wb_cyc (o_wb_cyc),
.i_wb_stb (o_wb_stb),
.i_wb_cti (3'd0),
.i_wb_bte (2'd0),
.i_wb_idata (i_wb_rdt),
.i_wb_ack (i_wb_ack),
.i_wb_err (i_wb_err),
.i_wb_rty (1'b0));
`endif
endmodule
`default_nettype wire

View File

@ -1,5 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2020 Western Digital Corporation or its affiliates.
// Copyright 2020 Western Digital Corporation or it's affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -14,8 +14,6 @@
// limitations under the License.
// all flops call the rvdff flop
`define RV_FPGA_OPTIMIZE 1
`define RV_PHYSICAL 1
module rvdff #( parameter WIDTH=1, SHORT=0 )
@ -31,7 +29,7 @@ if (SHORT == 1) begin
assign dout = din;
end
else begin
`ifdef RV_CLOCKGATE
`ifdef CLOCKGATE
always @(posedge tb_top.clk) begin
#0 $strobe("CG: %0t %m din %x dout %x clk %b width %d",$time,din,dout,clk,WIDTH);
end
@ -87,85 +85,7 @@ else begin
end
endmodule
// _fpga versions
module rvdff_fpga #( parameter WIDTH=1, SHORT=0 )
(
input logic [WIDTH-1:0] din,
input logic clk,
input logic clken,
input logic rawclk,
input logic rst_l,
output logic [WIDTH-1:0] dout
);
if (SHORT == 1) begin
assign dout = din;
end
else begin
`ifdef RV_FPGA_OPTIMIZE
rvdffs #(WIDTH) dffs (.clk(rawclk), .en(clken), .*);
`else
rvdff #(WIDTH) dff (.*);
`endif
end
endmodule
// rvdff with 2:1 input mux to flop din iff sel==1
module rvdffs_fpga #( parameter WIDTH=1, SHORT=0 )
(
input logic [WIDTH-1:0] din,
input logic en,
input logic clk,
input logic clken,
input logic rawclk,
input logic rst_l,
output logic [WIDTH-1:0] dout
);
if (SHORT == 1) begin : genblock
assign dout = din;
end
else begin : genblock
`ifdef RV_FPGA_OPTIMIZE
rvdffs #(WIDTH) dffs (.clk(rawclk), .en(clken & en), .*);
`else
rvdffs #(WIDTH) dffs (.*);
`endif
end
endmodule
// rvdff with en and clear
module rvdffsc_fpga #( parameter WIDTH=1, SHORT=0 )
(
input logic [WIDTH-1:0] din,
input logic en,
input logic clear,
input logic clk,
input logic clken,
input logic rawclk,
input logic rst_l,
output logic [WIDTH-1:0] dout
);
logic [WIDTH-1:0] din_new;
if (SHORT == 1) begin
assign dout = din;
end
else begin
`ifdef RV_FPGA_OPTIMIZE
rvdffs #(WIDTH) dffs (.clk(rawclk), .din(din[WIDTH-1:0] & {WIDTH{~clear}}),.en((en | clear) & clken), .*);
`else
rvdffsc #(WIDTH) dffsc (.*);
`endif
end
endmodule
module rvdffe #( parameter WIDTH=1, SHORT=0, OVERRIDE=0 )
module rvdffe #( parameter WIDTH=1, SHORT=0 )
(
input logic [WIDTH-1:0] din,
input logic en,
@ -184,8 +104,8 @@ if (SHORT == 1) begin : genblock
end
else begin : genblock
`ifndef RV_PHYSICAL
if (WIDTH >= 8 || OVERRIDE==1) begin: genblock
`ifndef PHYSICAL
if (WIDTH >= 8) begin: genblock
`endif
`ifdef RV_FPGA_OPTIMIZE
@ -195,226 +115,15 @@ else begin : genblock
rvdff #(WIDTH) dff (.*, .clk(l1clk));
`endif
`ifndef RV_PHYSICAL
`ifndef PHYSICAL
end
else
$error("%m: rvdffe must be WIDTH >= 8");
$error(" rvdffe width must be >= 8");
`endif
end // else: !if(SHORT == 1)
endmodule // rvdffe
module rvdffpcie #( parameter WIDTH=31 )
(
input logic [WIDTH-1:0] din,
input logic clk,
input logic rst_l,
input logic en,
input logic scan_mode,
output logic [WIDTH-1:0] dout
);
`ifndef RV_PHYSICAL
if (WIDTH == 31) begin: genblock
`endif
`ifdef RV_FPGA_OPTIMIZE
rvdffs #(WIDTH) dff ( .* );
`else
rvdfflie #(.WIDTH(WIDTH), .LEFT(19)) dff (.*);
`endif
`ifndef RV_PHYSICAL
end
else
$error("%m: rvdffpcie width must be 31");
`endif
endmodule
// format: { LEFT, EXTRA }
// LEFT # of bits will be done with rvdffie, all else EXTRA with rvdffe
module rvdfflie #( parameter WIDTH=16, LEFT=8 )
(
input logic [WIDTH-1:0] din,
input logic clk,
input logic rst_l,
input logic en,
input logic scan_mode,
output logic [WIDTH-1:0] dout
);
localparam EXTRA = WIDTH-LEFT;
localparam LMSB = WIDTH-1;
localparam LLSB = LMSB-LEFT+1;
localparam XMSB = LLSB-1;
localparam XLSB = LLSB-EXTRA;
`ifndef RV_PHYSICAL
if (WIDTH >= 16 && LEFT >= 8 && EXTRA >= 8) begin: genblock
`endif
`ifdef RV_FPGA_OPTIMIZE
rvdffs #(WIDTH) dff ( .* );
`else
rvdffiee #(LEFT) dff_left (.*, .din(din[LMSB:LLSB]), .dout(dout[LMSB:LLSB]));
rvdffe #(EXTRA) dff_extra (.*, .din(din[XMSB:XLSB]), .dout(dout[XMSB:XLSB]));
`endif
`ifndef RV_PHYSICAL
end
else
$error("%m: rvdfflie musb be WIDTH >= 16 && LEFT >= 8 && EXTRA >= 8");
`endif
endmodule
// special power flop for predict packet
// format: { LEFT, RIGHT==31 }
// LEFT # of bits will be done with rvdffe; RIGHT is enabled by LEFT[LSB] & en
module rvdffppe #( parameter WIDTH=32 )
(
input logic [WIDTH-1:0] din,
input logic clk,
input logic rst_l,
input logic en,
input logic scan_mode,
output logic [WIDTH-1:0] dout
);
localparam RIGHT = 31;
localparam LEFT = WIDTH - RIGHT;
localparam LMSB = WIDTH-1;
localparam LLSB = LMSB-LEFT+1;
localparam RMSB = LLSB-1;
localparam RLSB = LLSB-RIGHT;
`ifndef RV_PHYSICAL
if (WIDTH>=32 && LEFT>=8 && RIGHT>=8) begin: genblock
`endif
`ifdef RV_FPGA_OPTIMIZE
rvdffs #(WIDTH) dff ( .* );
`else
rvdffe #(LEFT) dff_left (.*, .din(din[LMSB:LLSB]), .dout(dout[LMSB:LLSB]));
rvdffe #(RIGHT) dff_right (.*, .din(din[RMSB:RLSB]), .dout(dout[RMSB:RLSB]), .en(en & din[LLSB])); // qualify with pret
`endif
`ifndef RV_PHYSICAL
end
else
$error("%m: must be WIDTH>=32 && LEFT>=8 && RIGHT>=8");
`endif
endmodule
module rvdffie #( parameter WIDTH=1, OVERRIDE=0 )
(
input logic [WIDTH-1:0] din,
input logic clk,
input logic rst_l,
input logic scan_mode,
output logic [WIDTH-1:0] dout
);
logic l1clk;
logic en;
`ifndef RV_PHYSICAL
if (WIDTH >= 8 || OVERRIDE==1) begin: genblock
`endif
assign en = |(din ^ dout);
`ifdef RV_FPGA_OPTIMIZE
rvdffs #(WIDTH) dff ( .* );
`else
rvclkhdr clkhdr ( .* );
rvdff #(WIDTH) dff (.*, .clk(l1clk));
`endif
`ifndef RV_PHYSICAL
end
else
$error("%m: rvdffie must be WIDTH >= 8");
`endif
endmodule
// ie flop but it has an .en input
module rvdffiee #( parameter WIDTH=1, OVERRIDE=0 )
(
input logic [WIDTH-1:0] din,
input logic clk,
input logic rst_l,
input logic scan_mode,
input logic en,
output logic [WIDTH-1:0] dout
);
logic l1clk;
logic final_en;
`ifndef RV_PHYSICAL
if (WIDTH >= 8 || OVERRIDE==1) begin: genblock
`endif
assign final_en = (|(din ^ dout)) & en;
`ifdef RV_FPGA_OPTIMIZE
rvdffs #(WIDTH) dff ( .*, .en(final_en) );
`else
rvdffe #(WIDTH) dff (.*, .en(final_en));
`endif
`ifndef RV_PHYSICAL
end
else
$error("%m: rvdffie width must be >= 8");
`endif
endmodule
module rvsyncss #(parameter WIDTH = 251)
(
input logic clk,
@ -430,23 +139,6 @@ module rvsyncss #(parameter WIDTH = 251)
endmodule // rvsyncss
module rvsyncss_fpga #(parameter WIDTH = 251)
(
input logic gw_clk,
input logic rawclk,
input logic clken,
input logic rst_l,
input logic [WIDTH-1:0] din,
output logic [WIDTH-1:0] dout
);
logic [WIDTH-1:0] din_ff1;
rvdff_fpga #(WIDTH) sync_ff1 (.*, .clk(gw_clk), .rawclk(rawclk), .clken(clken), .din (din[WIDTH-1:0]), .dout(din_ff1[WIDTH-1:0]));
rvdff_fpga #(WIDTH) sync_ff2 (.*, .clk(gw_clk), .rawclk(rawclk), .clken(clken), .din (din_ff1[WIDTH-1:0]), .dout(dout[WIDTH-1:0]));
endmodule // rvsyncss
module rvlsadder
(
input logic [31:0] rs1,
@ -751,7 +443,7 @@ module rvecc_decode_64 (
endmodule // rvecc_decode_64
module TEC_RV_ICG
module gated_flop
(
input logic SE, EN, CK,
output Q
@ -776,24 +468,5 @@ module TEC_RV_ICG
endmodule
module rvoclkhdr
(
input logic en,
input logic clk,
input logic scan_mode,
output logic l1clk
);
logic SE;
assign SE = 0;
`ifdef RV_FPGA_OPTIMIZE
assign l1clk = clk;
`else
TEC_RV_ICG clkhdr ( .*, .EN(en), .CK(clk), .Q(l1clk));
`endif
endmodule

View File

@ -1,66 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//********************************************************************************
// $Id$
//
// Function: Basic RAM model with separate read/write ports and byte-wise write enable
// Comments:
//
//********************************************************************************
module dpram64
#(parameter SIZE=0,
parameter mem_clear = 0,
parameter memfile = "")
(input wire clk,
input wire [7:0] we,
input wire [63:0] din,
input wire [$clog2(SIZE)-1:0] waddr,
input wire [$clog2(SIZE)-1:0] raddr,
output reg [63:0] dout);
localparam AW = $clog2(SIZE);
reg [63:0] mem [0:SIZE/8-1] /* verilator public */;
integer i;
wire [AW-4:0] wadd = waddr[AW-1:3];
always @(posedge clk) begin
if (we[0]) mem[wadd][ 7: 0] <= din[ 7: 0];
if (we[1]) mem[wadd][15: 8] <= din[15: 8];
if (we[2]) mem[wadd][23:16] <= din[23:16];
if (we[3]) mem[wadd][31:24] <= din[31:24];
if (we[4]) mem[wadd][39:32] <= din[39:32];
if (we[5]) mem[wadd][47:40] <= din[47:40];
if (we[6]) mem[wadd][55:48] <= din[55:48];
if (we[7]) mem[wadd][63:56] <= din[63:56];
dout <= mem[raddr[AW-1:3]];
end
generate
initial begin
if (mem_clear)
for (i=0;i<SIZE;i=i+1)
mem[i] = 64'd0;
if(|memfile) begin
$display("Preloading %m from %s", memfile);
$readmemh(memfile, mem);
end
end
endgenerate
endmodule

View File

@ -1,126 +0,0 @@
/////////////////////////////////////////////////////////////////////
//// ////
//// FIFO 4 entries deep ////
//// ////
//// Authors: Rudolf Usselmann, Richard Herveille ////
//// rudi@asics.ws richard@asics.ws ////
//// ////
//// ////
//// Download from: http://www.opencores.org/projects/sasc ////
//// http://www.opencores.org/projects/simple_spi ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000-2002 Rudolf Usselmann, Richard Herveille ////
//// www.asics.ws ////
//// rudi@asics.ws, richard@asics.ws ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
// CVS Log
//
// $Id: fifo4.v,v 1.1.1.1 2002-12-22 16:07:14 rherveille Exp $
//
// $Date: 2002-12-22 16:07:14 $
// $Revision: 1.1.1.1 $
// $Author: rherveille $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
//
// 4 entry deep fast fifo
module fifo4(clk, rst, clr, din, we, dout, re, full, empty);
parameter dw = 8;
input clk, rst;
input clr;
input [dw:1] din;
input we;
output [dw:1] dout;
input re;
output full, empty;
////////////////////////////////////////////////////////////////////
//
// Local Wires
//
reg [dw:1] mem[0:3];
reg [1:0] wp;
reg [1:0] rp;
wire [1:0] wp_p1;
wire [1:0] wp_p2;
wire [1:0] rp_p1;
wire full, empty;
reg gb;
////////////////////////////////////////////////////////////////////
//
// Misc Logic
//
always @(posedge clk or negedge rst)
if(!rst) wp <= 2'h0;
else
if(clr) wp <= 2'h0;
else
if(we) wp <= wp_p1;
assign wp_p1 = wp + 2'h1;
assign wp_p2 = wp + 2'h2;
always @(posedge clk or negedge rst)
if(!rst) rp <= 2'h0;
else
if(clr) rp <= 2'h0;
else
if(re) rp <= rp_p1;
assign rp_p1 = rp + 2'h1;
// Fifo Output
assign dout = mem[ rp ];
// Fifo Input
always @(posedge clk)
if(we) mem[ wp ] <= din;
// Status
assign empty = (wp == rp) & !gb;
assign full = (wp == rp) & gb;
// Guard Bit ...
always @(posedge clk)
if(!rst) gb <= 1'b0;
else
if(clr) gb <= 1'b0;
else
if((wp_p1 == rp) & we) gb <= 1'b1;
else
if(re) gb <= 1'b0;
endmodule

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
//********************************************************************************
// SPDX-License-Identifier: Apache-2.0
// Copyright 2020 Western Digital Corporation or its affiliates.
// Copyright 2020 Western Digital Corporation or it's affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -20,38 +20,29 @@
//********************************************************************************
module ifu_iccm_mem
//`include "parameter.sv"
#(
parameter ICCM_BITS,
parameter ICCM_BANK_INDEX_LO,
parameter ICCM_INDEX_BITS,
parameter ICCM_BANK_HI,
parameter ICCM_NUM_BANKS,
// parameter ICCM_ENABLE= 'b1,
parameter ICCM_BANK_BITS
)
parameter ICCM_BANK_BITS )(
input logic clk,
input logic rst_l,
input logic clk_override,
(
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
input logic rst_l, // reset, active low
input logic clk_override, // Override non-functional clock gating
input logic iccm_wren, // ICCM write enable
input logic iccm_rden, // ICCM read enable
input logic [ICCM_BITS-1:1] iccm_rw_addr, // ICCM read/write address
input logic iccm_wren,
input logic iccm_rden,
input logic [ICCM_BITS-1:1] iccm_rw_addr,
input logic iccm_buf_correct_ecc, // ICCM is doing a single bit error correct cycle
input logic iccm_correction_state, // ICCM under a correction - This is needed to guard replacements when hit
input logic [2:0] iccm_wr_size, // ICCM write size
input logic [77:0] iccm_wr_data, // ICCM write data
input logic iccm_correction_state, // We are under a correction - This is needed to guard replacements when hit
input logic [2:0] iccm_wr_size,
input logic [77:0] iccm_wr_data,
input iccm_ext_in_pkt_t [ICCM_NUM_BANKS-1:0] iccm_ext_in_pkt, // External packet
output logic [63:0] iccm_rd_data, // ICCM read data
output logic [77:0] iccm_rd_data_ecc, // ICCM read ecc
input logic scan_mode // Scan mode control
output logic [63:0] iccm_rd_data,
output logic [77:0] iccm_rd_data_ecc,
input logic scan_mode
);
@ -84,32 +75,15 @@ module ifu_iccm_mem
logic redundant_data1_en;
logic r0_addr_en, r1_addr_en;
// Testing persistent flip
// logic [3:0] not_iccm_bank_dout;
// logic [15:3] ecc_insert_flip_in, ecc_insert_flip;
// logic flip_en, flip_match, flip_match_q;
//
// assign flip_in = (iccm_rw_addr[3:2] != 2'b00); // dont flip when bank0 - this is to make some progress in DMA streaming cases
// assign flip_en = iccm_rden;
//
// rvdffs #(1) flipmatch (.*,
// .clk(clk),
// .din(flip_in),
// .en(flip_en),
// .dout(flip_match_q));
//
// end of testing flip
assign addr_incr[1:0] = (iccm_wr_size[1:0] == 2'b11) ? 2'b10: 2'b01;
assign addr_bank_inc[ICCM_BITS-1 : 1] = iccm_rw_addr[ICCM_BITS-1 : 1] + addr_incr[1:0];
for (genvar i=0; i<ICCM_NUM_BANKS/2; i++) begin: mem_bank_data
for (genvar i=0; i<32'(ICCM_NUM_BANKS)/2; i++) begin: mem_bank_data
assign iccm_bank_wr_data_vec[(2*i)] = iccm_wr_data[38:0];
assign iccm_bank_wr_data_vec[(2*i)+1] = iccm_wr_data[77:39];
end
for (genvar i=0; i<ICCM_NUM_BANKS; i++) begin: mem_bank
for (genvar i=0; i<32'(ICCM_NUM_BANKS); i++) begin: mem_bank
assign wren_bank[i] = iccm_wren & ((iccm_rw_addr[ICCM_BANK_HI:2] == i) | (addr_bank_inc[ICCM_BANK_HI:2] == i));
assign iccm_bank_wr_data[i] = iccm_bank_wr_data_vec[i];
assign rden_bank[i] = iccm_rden & ( (iccm_rw_addr[ICCM_BANK_HI:2] == i) | (addr_bank_inc[ICCM_BANK_HI:2] == i));
@ -127,18 +101,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]),
.ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[i][38:0]),
.ROP ( ),
// These are used by SoC
.TEST1(iccm_ext_in_pkt[i].TEST1),
.RME(iccm_ext_in_pkt[i].RME),
.RM(iccm_ext_in_pkt[i].RM),
.LS(iccm_ext_in_pkt[i].LS),
.DS(iccm_ext_in_pkt[i].DS),
.SD(iccm_ext_in_pkt[i].SD) ,
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
.BC1(iccm_ext_in_pkt[i].BC1),
.BC2(iccm_ext_in_pkt[i].BC2)
.Q(iccm_bank_dout[i][38:0])
);
`else
@ -151,18 +114,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]),
.ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[i][38:0]),
.ROP ( ),
// These are used by SoC
.TEST1(iccm_ext_in_pkt[i].TEST1),
.RME(iccm_ext_in_pkt[i].RME),
.RM(iccm_ext_in_pkt[i].RM),
.LS(iccm_ext_in_pkt[i].LS),
.DS(iccm_ext_in_pkt[i].DS),
.SD(iccm_ext_in_pkt[i].SD) ,
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
.BC1(iccm_ext_in_pkt[i].BC1),
.BC2(iccm_ext_in_pkt[i].BC2)
.Q(iccm_bank_dout[i][38:0])
);
end // block: iccm
@ -175,18 +127,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]),
.ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[i][38:0]),
.ROP ( ),
// These are used by SoC
.TEST1(iccm_ext_in_pkt[i].TEST1),
.RME(iccm_ext_in_pkt[i].RME),
.RM(iccm_ext_in_pkt[i].RM),
.LS(iccm_ext_in_pkt[i].LS),
.DS(iccm_ext_in_pkt[i].DS),
.SD(iccm_ext_in_pkt[i].SD) ,
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
.BC1(iccm_ext_in_pkt[i].BC1),
.BC2(iccm_ext_in_pkt[i].BC2)
.Q(iccm_bank_dout[i][38:0])
);
end // block: iccm
@ -199,18 +140,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]),
.ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[i][38:0]),
.ROP ( ),
// These are used by SoC
.TEST1(iccm_ext_in_pkt[i].TEST1),
.RME(iccm_ext_in_pkt[i].RME),
.RM(iccm_ext_in_pkt[i].RM),
.LS(iccm_ext_in_pkt[i].LS),
.DS(iccm_ext_in_pkt[i].DS),
.SD(iccm_ext_in_pkt[i].SD) ,
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
.BC1(iccm_ext_in_pkt[i].BC1),
.BC2(iccm_ext_in_pkt[i].BC2)
.Q(iccm_bank_dout[i][38:0])
);
end // block: iccm
@ -222,18 +152,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]),
.ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[i][38:0]),
.ROP ( ),
// These are used by SoC
.TEST1(iccm_ext_in_pkt[i].TEST1),
.RME(iccm_ext_in_pkt[i].RME),
.RM(iccm_ext_in_pkt[i].RM),
.LS(iccm_ext_in_pkt[i].LS),
.DS(iccm_ext_in_pkt[i].DS),
.SD(iccm_ext_in_pkt[i].SD) ,
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
.BC1(iccm_ext_in_pkt[i].BC1),
.BC2(iccm_ext_in_pkt[i].BC2)
.Q(iccm_bank_dout[i][38:0])
);
end // block: iccm
@ -245,18 +164,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]),
.ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[i][38:0]),
.ROP ( ),
// These are used by SoC
.TEST1(iccm_ext_in_pkt[i].TEST1),
.RME(iccm_ext_in_pkt[i].RME),
.RM(iccm_ext_in_pkt[i].RM),
.LS(iccm_ext_in_pkt[i].LS),
.DS(iccm_ext_in_pkt[i].DS),
.SD(iccm_ext_in_pkt[i].SD) ,
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
.BC1(iccm_ext_in_pkt[i].BC1),
.BC2(iccm_ext_in_pkt[i].BC2)
.Q(iccm_bank_dout[i][38:0])
);
end // block: iccm
@ -268,18 +176,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]),
.ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[i][38:0]),
.ROP ( ),
// These are used by SoC
.TEST1(iccm_ext_in_pkt[i].TEST1),
.RME(iccm_ext_in_pkt[i].RME),
.RM(iccm_ext_in_pkt[i].RM),
.LS(iccm_ext_in_pkt[i].LS),
.DS(iccm_ext_in_pkt[i].DS),
.SD(iccm_ext_in_pkt[i].SD) ,
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
.BC1(iccm_ext_in_pkt[i].BC1),
.BC2(iccm_ext_in_pkt[i].BC2)
.Q(iccm_bank_dout[i][38:0])
);
end // block: iccm
@ -291,18 +188,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]),
.ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[i][38:0]),
.ROP ( ),
// These are used by SoC
.TEST1(iccm_ext_in_pkt[i].TEST1),
.RME(iccm_ext_in_pkt[i].RME),
.RM(iccm_ext_in_pkt[i].RM),
.LS(iccm_ext_in_pkt[i].LS),
.DS(iccm_ext_in_pkt[i].DS),
.SD(iccm_ext_in_pkt[i].SD) ,
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
.BC1(iccm_ext_in_pkt[i].BC1),
.BC2(iccm_ext_in_pkt[i].BC2)
.Q(iccm_bank_dout[i][38:0])
);
end // block: iccm
@ -314,18 +200,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]),
.ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[i][38:0]),
.ROP ( ),
// These are used by SoC
.TEST1(iccm_ext_in_pkt[i].TEST1),
.RME(iccm_ext_in_pkt[i].RME),
.RM(iccm_ext_in_pkt[i].RM),
.LS(iccm_ext_in_pkt[i].LS),
.DS(iccm_ext_in_pkt[i].DS),
.SD(iccm_ext_in_pkt[i].SD) ,
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
.BC1(iccm_ext_in_pkt[i].BC1),
.BC2(iccm_ext_in_pkt[i].BC2)
.Q(iccm_bank_dout[i][38:0])
);
end // block: iccm
@ -337,18 +212,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]),
.ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[i][38:0]),
.ROP ( ),
// These are used by SoC
.TEST1(iccm_ext_in_pkt[i].TEST1),
.RME(iccm_ext_in_pkt[i].RME),
.RM(iccm_ext_in_pkt[i].RM),
.LS(iccm_ext_in_pkt[i].LS),
.DS(iccm_ext_in_pkt[i].DS),
.SD(iccm_ext_in_pkt[i].SD) ,
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
.BC1(iccm_ext_in_pkt[i].BC1),
.BC2(iccm_ext_in_pkt[i].BC2)
.Q(iccm_bank_dout[i][38:0])
);
end // block: iccm
@ -360,18 +224,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]),
.ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[i][38:0]),
.ROP ( ),
// These are used by SoC
.TEST1(iccm_ext_in_pkt[i].TEST1),
.RME(iccm_ext_in_pkt[i].RME),
.RM(iccm_ext_in_pkt[i].RM),
.LS(iccm_ext_in_pkt[i].LS),
.DS(iccm_ext_in_pkt[i].DS),
.SD(iccm_ext_in_pkt[i].SD) ,
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
.BC1(iccm_ext_in_pkt[i].BC1),
.BC2(iccm_ext_in_pkt[i].BC2)
.Q(iccm_bank_dout[i][38:0])
);
end // block: iccm
@ -385,20 +238,21 @@ module ifu_iccm_mem
((addr_bank_inc[ICCM_BITS-1:2]== redundant_address[0][ICCM_BITS-1:2]) & (addr_bank_inc[3:2] == i))));
rvdff #(1) selred0 (.*,
.clk(active_clk),
.clk(clk),
.din(sel_red0[i]),
.dout(sel_red0_q[i]));
rvdff #(1) selred1 (.*,
.clk(active_clk),
.clk(clk),
.din(sel_red1[i]),
.dout(sel_red1_q[i]));
// muxing out the memory data with the redundant data if the address matches
assign iccm_bank_dout_fn[i][38:0] = ({39{sel_red1_q[i]}} & redundant_data[1][38:0]) |
({39{sel_red0_q[i]}} & redundant_data[0][38:0]) |
({39{~sel_red0_q[i] & ~sel_red1_q[i]}} & iccm_bank_dout[i][38:0]);
assign iccm_bank_dout_fn[i][38:0] = ({39{sel_red1_q[i]}} & redundant_data[1][38:0]) |
({39{sel_red0_q[i]}} & redundant_data[0][38:0]) |
({39{~sel_red0_q[i] & ~sel_red1_q[i]}} & iccm_bank_dout[i][38:0]);
end : mem_bank
// This section does the redundancy for tolerating single bit errors
@ -410,31 +264,31 @@ module ifu_iccm_mem
assign redundant_lru_in = iccm_buf_correct_ecc ? ~redundant_lru : (|sel_red0[ICCM_NUM_BANKS-1:0]) ? 1'b1 : 1'b0;
rvdffs #() red_lru (.*, // LRU flop for the redundant replacements
.clk(active_clk),
.clk(clk),
.en(redundant_lru_en),
.din(redundant_lru_in),
.dout(redundant_lru));
rvdffs #(ICCM_BITS-2) r0_address (.*, // Redundant Row 0 address
.clk(active_clk),
.clk(clk),
.en(r0_addr_en),
.din(iccm_rw_addr[ICCM_BITS-1:2]),
.dout(redundant_address[0][ICCM_BITS-1:2]));
rvdffs #(ICCM_BITS-2) r1_address (.*, // Redundant Row 0 address
.clk(active_clk),
.clk(clk),
.en(r1_addr_en),
.din(iccm_rw_addr[ICCM_BITS-1:2]),
.dout(redundant_address[1][ICCM_BITS-1:2]));
rvdffs #(1) r0_valid (.*,
.clk(active_clk), // Redundant Row 0 Valid
.clk(clk), // Redundant Row 0 Valid
.en(r0_addr_en),
.din(1'b1),
.dout(redundant_valid[0]));
rvdffs #(1) r1_valid (.*, // Redundant Row 1 Valid
.clk(active_clk),
.clk(clk),
.en(r1_addr_en),
.din(1'b1),
.dout(redundant_valid[1]));
@ -451,7 +305,7 @@ module ifu_iccm_mem
assign redundant_data0_in[38:0] = (((iccm_rw_addr[2] == redundant_address[0][2]) & iccm_rw_addr[2]) | (redundant_address[0][2] & (iccm_wr_size[1:0] == 2'b11))) ? iccm_wr_data[77:39] : iccm_wr_data[38:0];
rvdffs #(39) r0_data (.*, // Redundant Row 1 data
.clk(active_clk),
.clk(clk),
.en(redundant_data0_en),
.din(redundant_data0_in[38:0]),
.dout(redundant_data[0][38:0]));
@ -462,18 +316,18 @@ module ifu_iccm_mem
assign redundant_data1_in[38:0] = (((iccm_rw_addr[2] == redundant_address[1][2]) & iccm_rw_addr[2]) | (redundant_address[1][2] & (iccm_wr_size[1:0] == 2'b11))) ? iccm_wr_data[77:39] : iccm_wr_data[38:0];
rvdffs #(39) r1_data (.*, // Redundant Row 1 data
.clk(active_clk),
.clk(clk),
.en(redundant_data1_en),
.din(redundant_data1_in[38:0]),
.dout(redundant_data[1][38:0]));
rvdffs #(ICCM_BANK_HI) rd_addr_lo_ff (.*, .clk(active_clk), .din(iccm_rw_addr [ICCM_BANK_HI:1]), .dout(iccm_rd_addr_lo_q[ICCM_BANK_HI:1]), .en(1'b1)); // bit 0 of address is always 0
rvdffs #(ICCM_BANK_BITS) rd_addr_hi_ff (.*, .clk(active_clk), .din(addr_bank_inc[ICCM_BANK_HI:2]), .dout(iccm_rd_addr_hi_q[ICCM_BANK_HI:2]), .en(1'b1));
rvdffs #(ICCM_BANK_HI) rd_addr_lo_ff (.*, .din(iccm_rw_addr [ICCM_BANK_HI:1]), .dout(iccm_rd_addr_lo_q[ICCM_BANK_HI:1]), .en(1'b1)); // bit 0 of address is always 0
rvdffs #(ICCM_BANK_BITS) rd_addr_hi_ff (.*, .din(addr_bank_inc[ICCM_BANK_HI:2]), .dout(iccm_rd_addr_hi_q[ICCM_BANK_HI:2]), .en(1'b1));
assign iccm_rd_data_pre[63:0] = {iccm_bank_dout_fn[iccm_rd_addr_hi_q][31:0], iccm_bank_dout_fn[iccm_rd_addr_lo_q[ICCM_BANK_HI:2]][31:0]};
assign iccm_data[63:0] = 64'({16'b0, (iccm_rd_data_pre[63:0] >> (16*iccm_rd_addr_lo_q[1]))});
assign iccm_rd_data[63:0] = {iccm_data[63:0]};
assign iccm_rd_data_ecc[77:0] = {iccm_bank_dout_fn[iccm_rd_addr_hi_q][38:0], iccm_bank_dout_fn[iccm_rd_addr_lo_q[ICCM_BANK_HI:2]][38:0]};
endmodule // ifu_iccm_mem
endmodule // el2_ifu_iccm_mem

View File

@ -1,5 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2020 Western Digital Corporation or its affiliates.
// Copyright 2020 Western Digital Corporation or it's affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -27,37 +27,17 @@
// //********************************************************************************
`define LOCAL_DCCM_RAM_TEST_PORTS .TEST1(dccm_ext_in_pkt[i].TEST1), \
.RME(dccm_ext_in_pkt[i].RME), \
.RM(dccm_ext_in_pkt[i].RM), \
.LS(dccm_ext_in_pkt[i].LS), \
.DS(dccm_ext_in_pkt[i].DS), \
.SD(dccm_ext_in_pkt[i].SD), \
.TEST_RNM(dccm_ext_in_pkt[i].TEST_RNM), \
.BC1(dccm_ext_in_pkt[i].BC1), \
.BC2(dccm_ext_in_pkt[i].BC2), \
module lsu_dccm_mem
//`include "parameter.sv"
#(
parameter DCCM_BYTE_WIDTH,
parameter DCCM_BITS,
parameter DCCM_NUM_BANKS,
parameter DCCM_ENABLE= 'b1,
parameter DCCM_BANK_BITS,
parameter DCCM_SIZE,
parameter DCCM_FDATA_WIDTH,
parameter DCCM_WIDTH_BITS
)
(
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
input logic rst_l, // reset, active low
input logic clk_override, // Override non-functional clock gating
parameter DCCM_FDATA_WIDTH )(
input logic clk, // clock
input logic rst_l,
input logic clk_override, // clock override
input logic dccm_wren, // write enable
input logic dccm_rden, // read enable
@ -67,8 +47,7 @@ module lsu_dccm_mem
input logic [DCCM_BITS-1:0] dccm_rd_addr_hi, // read address for the upper bank in case of a misaligned access
input logic [DCCM_FDATA_WIDTH-1:0] dccm_wr_data_lo, // write data
input logic [DCCM_FDATA_WIDTH-1:0] dccm_wr_data_hi, // write data
input dccm_ext_in_pkt_t [DCCM_NUM_BANKS-1:0] dccm_ext_in_pkt, // the dccm packet from the soc
output logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // read data from the lo bank
output logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // read data from the hi bank
@ -76,7 +55,7 @@ module lsu_dccm_mem
);
//localparam DCCM_WIDTH_BITS = $clog2(DCCM_BYTE_WIDTH);
localparam DCCM_WIDTH_BITS = $clog2(DCCM_BYTE_WIDTH);
localparam DCCM_INDEX_BITS = (DCCM_BITS - DCCM_BANK_BITS - DCCM_WIDTH_BITS);
localparam DCCM_INDEX_DEPTH = ((DCCM_SIZE)*1024)/((DCCM_BYTE_WIDTH)*(DCCM_NUM_BANKS)); // Depth of memory bank
@ -102,9 +81,10 @@ module lsu_dccm_mem
assign dccm_rd_data_lo[DCCM_FDATA_WIDTH-1:0] = dccm_bank_dout[dccm_rd_addr_lo_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]][DCCM_FDATA_WIDTH-1:0];
assign dccm_rd_data_hi[DCCM_FDATA_WIDTH-1:0] = dccm_bank_dout[dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]][DCCM_FDATA_WIDTH-1:0];
// Generate even/odd address
// 8 Banks, 16KB each (2048 x 72)
for (genvar i=0; i<DCCM_NUM_BANKS; i++) begin: mem_bank
for (genvar i=0; i<32'(DCCM_NUM_BANKS); i++) begin: mem_bank
assign wren_bank[i] = dccm_wren & ((dccm_wr_addr_hi[2+:DCCM_BANK_BITS] == i) | (dccm_wr_addr_lo[2+:DCCM_BANK_BITS] == i));
assign rden_bank[i] = dccm_rden & ((dccm_rd_addr_hi[2+:DCCM_BANK_BITS] == i) | (dccm_rd_addr_lo[2+:DCCM_BANK_BITS] == i));
assign addr_bank[i][(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = wren_bank[i] ? (((dccm_wr_addr_hi[2+:DCCM_BANK_BITS] == i) & wr_unaligned) ?
@ -121,8 +101,7 @@ module lsu_dccm_mem
// end clock gating section
`ifdef VERILATOR
el2_ram #(DCCM_INDEX_DEPTH,39) ram (
el2_ram #(DCCM_INDEX_DEPTH,39) ram (
// Primary ports
.ME(dccm_clken[i]),
.CLK(clk),
@ -130,13 +109,10 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
`else
`else
if (DCCM_INDEX_DEPTH == 32768) begin : dccm
ram_32768x39 dccm_bank (
// Primary ports
@ -146,10 +122,7 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
.*
);
end
else if (DCCM_INDEX_DEPTH == 16384) begin : dccm
@ -161,9 +134,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
@ -176,9 +146,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
@ -191,9 +158,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
@ -206,9 +170,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
@ -221,9 +182,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
@ -236,9 +194,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
@ -251,9 +206,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
@ -266,37 +218,18 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
else if (DCCM_INDEX_DEPTH == 128) begin : dccm
ram_128x39 dccm_bank (
// Primary ports
.ME(dccm_clken[i]),
.CLK(clk),
.WE(wren_bank[i]),
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
`endif
`endif // VERILATOR
end : mem_bank
// Flops
rvdff #(DCCM_BANK_BITS) rd_addr_lo_ff (.*, .din(dccm_rd_addr_lo[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_lo_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .clk(active_clk));
rvdff #(DCCM_BANK_BITS) rd_addr_hi_ff (.*, .din(dccm_rd_addr_hi[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .clk(active_clk));
rvdffs #(DCCM_BANK_BITS) rd_addr_lo_ff (.*, .din(dccm_rd_addr_lo[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_lo_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .en(1'b1));
rvdffs #(DCCM_BANK_BITS) rd_addr_hi_ff (.*, .din(dccm_rd_addr_hi[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .en(1'b1));
`undef LOCAL_DCCM_RAM_TEST_PORTS
`undef EL2_LOCAL_DCCM_RAM_TEST_PORTS
endmodule // lsu_dccm_mem
endmodule // el2_lsu_dccm_mem

View File

@ -1,71 +1,5 @@
//********************************************************************************
// SPDX-License-Identifier: Apache-2.0
// Copyright 2020 Western Digital Corporation or its affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//********************************************************************************
typedef struct packed {
logic TEST1;
logic RME;
logic [3:0] RM;
logic LS;
logic DS;
logic SD;
logic TEST_RNM;
logic BC1;
logic BC2;
} iccm_ext_in_pkt_t;
typedef struct packed {
logic TEST1;
logic RME;
logic [3:0] RM;
logic LS;
logic DS;
logic SD;
logic TEST_RNM;
logic BC1;
logic BC2;
} dccm_ext_in_pkt_t;
typedef struct packed {
logic TEST1;
logic RME;
logic [3:0] RM;
logic LS;
logic DS;
logic SD;
logic TEST_RNM;
logic BC1;
logic BC2;
} ic_data_ext_in_pkt_t;
typedef struct packed {
logic TEST1;
logic RME;
logic [3:0] RM;
logic LS;
logic DS;
logic SD;
logic TEST_RNM;
logic BC1;
logic BC2;
} ic_tag_ext_in_pkt_t;
module mem#(
module mem #(
parameter ICACHE_BEAT_BITS,
parameter ICCM_BITS,
parameter ICACHE_NUM_WAYS,
@ -95,17 +29,7 @@ module mem#(
parameter DCCM_SIZE,
parameter DCCM_FDATA_WIDTH,
parameter ICACHE_TAG_INDEX_LO,
parameter ICACHE_DATA_DEPTH,
parameter DCCM_WIDTH_BITS,
parameter ICACHE_NUM_BYPASS,
parameter ICACHE_TAG_NUM_BYPASS,
parameter ICACHE_TAG_NUM_BYPASS_WIDTH,
parameter ICACHE_TAG_BYPASS_ENABLE,
parameter ICACHE_NUM_BYPASS_WIDTH,
parameter ICACHE_BYPASS_ENABLE,
parameter ICACHE_LN_SZ
)
parameter ICACHE_DATA_DEPTH)
(
input logic clk,
input logic rst_l,
@ -128,89 +52,10 @@ module mem#(
output logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi,
//`ifdef DCCM_ENABLE
//input dccm_ext_in_pkt_t [DCCM_NUM_BANKS-1:0] dccm_ext_in_pkt,
input logic dccm_ext_in_pkt_TEST1_0,
input logic dccm_ext_in_pkt_RME_0,
input logic [3:0] dccm_ext_in_pkt_RM_0,
input logic dccm_ext_in_pkt_LS_0,
input logic dccm_ext_in_pkt_DS_0,
input logic dccm_ext_in_pkt_SD_0,
input logic dccm_ext_in_pkt_TEST_RNM_0,
input logic dccm_ext_in_pkt_BC1_0,
input logic dccm_ext_in_pkt_BC2_0,
input logic dccm_ext_in_pkt_TEST1_1,
input logic dccm_ext_in_pkt_RME_1,
input logic [3:0] dccm_ext_in_pkt_RM_1,
input logic dccm_ext_in_pkt_LS_1,
input logic dccm_ext_in_pkt_DS_1,
input logic dccm_ext_in_pkt_SD_1,
input logic dccm_ext_in_pkt_TEST_RNM_1,
input logic dccm_ext_in_pkt_BC1_1,
input logic dccm_ext_in_pkt_BC2_1,
input logic dccm_ext_in_pkt_TEST1_2,
input logic dccm_ext_in_pkt_RME_2,
input logic [3:0] dccm_ext_in_pkt_RM_2,
input logic dccm_ext_in_pkt_LS_2,
input logic dccm_ext_in_pkt_DS_2,
input logic dccm_ext_in_pkt_SD_2,
input logic dccm_ext_in_pkt_TEST_RNM_2,
input logic dccm_ext_in_pkt_BC1_2,
input logic dccm_ext_in_pkt_BC2_2,
input logic dccm_ext_in_pkt_TEST1_3,
input logic dccm_ext_in_pkt_RME_3,
input logic [3:0] dccm_ext_in_pkt_RM_3,
input logic dccm_ext_in_pkt_LS_3,
input logic dccm_ext_in_pkt_DS_3,
input logic dccm_ext_in_pkt_SD_3,
input logic dccm_ext_in_pkt_TEST_RNM_3,
input logic dccm_ext_in_pkt_BC1_3,
input logic dccm_ext_in_pkt_BC2_3,
//`endif
//ICCM ports
input logic iccm_ext_in_pkt_TEST1_0,
input logic iccm_ext_in_pkt_RME_0,
input logic [3:0] iccm_ext_in_pkt_RM_0,
input logic iccm_ext_in_pkt_LS_0,
input logic iccm_ext_in_pkt_DS_0,
input logic iccm_ext_in_pkt_SD_0,
input logic iccm_ext_in_pkt_TEST_RNM_0,
input logic iccm_ext_in_pkt_BC1_0,
input logic iccm_ext_in_pkt_BC2_0,
input logic iccm_ext_in_pkt_TEST1_1,
input logic iccm_ext_in_pkt_RME_1,
input logic [3:0] iccm_ext_in_pkt_RM_1,
input logic iccm_ext_in_pkt_LS_1,
input logic iccm_ext_in_pkt_DS_1,
input logic iccm_ext_in_pkt_SD_1,
input logic iccm_ext_in_pkt_TEST_RNM_1,
input logic iccm_ext_in_pkt_BC1_1,
input logic iccm_ext_in_pkt_BC2_1,
input logic iccm_ext_in_pkt_TEST1_2,
input logic iccm_ext_in_pkt_RME_2,
input logic [3:0] iccm_ext_in_pkt_RM_2,
input logic iccm_ext_in_pkt_LS_2,
input logic iccm_ext_in_pkt_DS_2,
input logic iccm_ext_in_pkt_SD_2,
input logic iccm_ext_in_pkt_TEST_RNM_2,
input logic iccm_ext_in_pkt_BC1_2,
input logic iccm_ext_in_pkt_BC2_2,
input logic iccm_ext_in_pkt_TEST1_3,
input logic iccm_ext_in_pkt_RME_3,
input logic [3:0] iccm_ext_in_pkt_RM_3,
input logic iccm_ext_in_pkt_LS_3,
input logic iccm_ext_in_pkt_DS_3,
input logic iccm_ext_in_pkt_SD_3,
input logic iccm_ext_in_pkt_TEST_RNM_3,
input logic iccm_ext_in_pkt_BC1_3,
input logic iccm_ext_in_pkt_BC2_3,
input logic [ICCM_BITS-1:1] iccm_rw_addr,
input logic iccm_buf_correct_ecc, // ICCM is doing a single bit error correct cycle
@ -231,71 +76,10 @@ module mem#(
input logic ic_rd_en,
input logic [63:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
input logic ic_sel_premux_data, // Premux data sel
// input ic_data_ext_in_pkt_t [ICACHE_NUM_WAYS-1:0][ICACHE_BANKS_WAY-1:0] ic_data_ext_in_pkt,
input logic ic_tag_ext_in_pkt_TEST1_0,
input logic ic_tag_ext_in_pkt_RME_0,
input logic [3:0] ic_tag_ext_in_pkt_RM_0,
input logic ic_tag_ext_in_pkt_LS_0,
input logic ic_tag_ext_in_pkt_DS_0,
input logic ic_tag_ext_in_pkt_SD_0,
input logic ic_tag_ext_in_pkt_TEST_RNM_0,
input logic ic_tag_ext_in_pkt_BC1_0,
input logic ic_tag_ext_in_pkt_BC2_0,
input logic ic_tag_ext_in_pkt_TEST1_1,
input logic ic_tag_ext_in_pkt_RME_1,
input logic [3:0] ic_tag_ext_in_pkt_RM_1,
input logic ic_tag_ext_in_pkt_LS_1,
input logic ic_tag_ext_in_pkt_DS_1,
input logic ic_tag_ext_in_pkt_SD_1,
input logic ic_tag_ext_in_pkt_TEST_RNM_1,
input logic ic_tag_ext_in_pkt_BC1_1,
input logic ic_tag_ext_in_pkt_BC2_1,
input logic ic_data_ext_in_pkt_0_TEST1_0,
input logic ic_data_ext_in_pkt_0_RME_0,
input logic [3:0] ic_data_ext_in_pkt_0_RM_0,
input logic ic_data_ext_in_pkt_0_LS_0,
input logic ic_data_ext_in_pkt_0_DS_0,
input logic ic_data_ext_in_pkt_0_SD_0,
input logic ic_data_ext_in_pkt_0_TEST_RNM_0,
input logic ic_data_ext_in_pkt_0_BC1_0,
input logic ic_data_ext_in_pkt_0_BC2_0,
input logic ic_data_ext_in_pkt_0_TEST1_1,
input logic ic_data_ext_in_pkt_0_RME_1,
input logic [3:0] ic_data_ext_in_pkt_0_RM_1,
input logic ic_data_ext_in_pkt_0_LS_1,
input logic ic_data_ext_in_pkt_0_DS_1,
input logic ic_data_ext_in_pkt_0_SD_1,
input logic ic_data_ext_in_pkt_0_TEST_RNM_1,
input logic ic_data_ext_in_pkt_0_BC1_1,
input logic ic_data_ext_in_pkt_0_BC2_1,
input logic ic_data_ext_in_pkt_1_TEST1_0,
input logic ic_data_ext_in_pkt_1_RME_0,
input logic [3:0] ic_data_ext_in_pkt_1_RM_0,
input logic ic_data_ext_in_pkt_1_LS_0,
input logic ic_data_ext_in_pkt_1_DS_0,
input logic ic_data_ext_in_pkt_1_SD_0,
input logic ic_data_ext_in_pkt_1_TEST_RNM_0,
input logic ic_data_ext_in_pkt_1_BC1_0,
input logic ic_data_ext_in_pkt_1_BC2_0,
input logic ic_data_ext_in_pkt_1_TEST1_1,
input logic ic_data_ext_in_pkt_1_RME_1,
input logic [3:0] ic_data_ext_in_pkt_1_RM_1,
input logic ic_data_ext_in_pkt_1_LS_1,
input logic ic_data_ext_in_pkt_1_DS_1,
input logic ic_data_ext_in_pkt_1_SD_1,
input logic ic_data_ext_in_pkt_1_TEST_RNM_1,
input logic ic_data_ext_in_pkt_1_BC1_1,
input logic ic_data_ext_in_pkt_1_BC2_1,
// input logic [ICACHE_BANKS_WAY-1:0][70:0] ic_wr_data, // Data to fill to the Icache. With ECC
input logic [70:0] ic_wr_data_0, // Data to fill to the Icache. With ECC
input logic [70:0] ic_wr_data_1, // Data to fill to the Icache. With ECC
input logic [70:0] ic_debug_wr_data, // Debug wr cache.
input logic [70:0] ic_wr_data_0, // Data to fill to the Icache. With ECC
input logic [70:0] ic_wr_data_1,
input logic [70:0] ic_debug_wr_data, // Debug wr cache.
output logic [70:0] ic_debug_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
input logic [ICACHE_INDEX_HI:3] ic_debug_addr, // Read/Write addresss to the Icache.
input logic ic_debug_rd_en, // Icache debug rd
@ -317,160 +101,9 @@ module mem#(
);
iccm_ext_in_pkt_t [ICCM_NUM_BANKS-1:0] iccm_ext_in_pkt;
dccm_ext_in_pkt_t [DCCM_NUM_BANKS-1:0] dccm_ext_in_pkt;
ic_data_ext_in_pkt_t [ICACHE_NUM_WAYS-1:0][ICACHE_BANKS_WAY-1:0] ic_data_ext_in_pkt;
ic_tag_ext_in_pkt_t [ICACHE_NUM_WAYS-1:0] ic_tag_ext_in_pkt;
assign dccm_ext_in_pkt[0].TEST1 = dccm_ext_in_pkt_TEST1_0;
assign dccm_ext_in_pkt[0].RME = dccm_ext_in_pkt_RME_0;
assign dccm_ext_in_pkt[0].RM = dccm_ext_in_pkt_RM_0[3:0];
assign dccm_ext_in_pkt[0].LS = dccm_ext_in_pkt_LS_0;
assign dccm_ext_in_pkt[0].DS = dccm_ext_in_pkt_DS_0;
assign dccm_ext_in_pkt[0].SD = dccm_ext_in_pkt_SD_0;
assign dccm_ext_in_pkt[0].TEST_RNM = dccm_ext_in_pkt_TEST_RNM_0;
assign dccm_ext_in_pkt[0].BC1 = dccm_ext_in_pkt_BC1_0;
assign dccm_ext_in_pkt[0].BC2 = dccm_ext_in_pkt_BC2_0;
assign dccm_ext_in_pkt[1].TEST1 = dccm_ext_in_pkt_TEST1_1;
assign dccm_ext_in_pkt[1].RME = dccm_ext_in_pkt_RME_1;
assign dccm_ext_in_pkt[1].RM = dccm_ext_in_pkt_RM_1[3:0];
assign dccm_ext_in_pkt[1].LS = dccm_ext_in_pkt_LS_1;
assign dccm_ext_in_pkt[1].DS = dccm_ext_in_pkt_DS_1;
assign dccm_ext_in_pkt[1].SD = dccm_ext_in_pkt_SD_1;
assign dccm_ext_in_pkt[1].TEST_RNM = dccm_ext_in_pkt_TEST_RNM_1;
assign dccm_ext_in_pkt[1].BC1 = dccm_ext_in_pkt_BC1_1;
assign dccm_ext_in_pkt[1].BC2 = dccm_ext_in_pkt_BC2_1;
assign dccm_ext_in_pkt[2].TEST1 = dccm_ext_in_pkt_TEST1_2;
assign dccm_ext_in_pkt[2].RME = dccm_ext_in_pkt_RME_2;
assign dccm_ext_in_pkt[2].RM = dccm_ext_in_pkt_RM_2[3:0];
assign dccm_ext_in_pkt[2].LS = dccm_ext_in_pkt_LS_2;
assign dccm_ext_in_pkt[2].DS = dccm_ext_in_pkt_DS_2;
assign dccm_ext_in_pkt[2].SD = dccm_ext_in_pkt_SD_2;
assign dccm_ext_in_pkt[2].TEST_RNM = dccm_ext_in_pkt_TEST_RNM_2;
assign dccm_ext_in_pkt[2].BC1 = dccm_ext_in_pkt_BC1_2;
assign dccm_ext_in_pkt[2].BC2 = dccm_ext_in_pkt_BC2_2;
assign dccm_ext_in_pkt[3].TEST1 = dccm_ext_in_pkt_TEST1_3;
assign dccm_ext_in_pkt[3].RME = dccm_ext_in_pkt_RME_3;
assign dccm_ext_in_pkt[3].RM = dccm_ext_in_pkt_RM_3[3:0];
assign dccm_ext_in_pkt[3].LS = dccm_ext_in_pkt_LS_3;
assign dccm_ext_in_pkt[3].DS = dccm_ext_in_pkt_DS_3;
assign dccm_ext_in_pkt[3].SD = dccm_ext_in_pkt_SD_3;
assign dccm_ext_in_pkt[3].TEST_RNM = dccm_ext_in_pkt_TEST_RNM_3;
assign dccm_ext_in_pkt[3].BC1 = dccm_ext_in_pkt_BC1_3;
assign dccm_ext_in_pkt[3].BC2 = dccm_ext_in_pkt_BC2_3;
assign iccm_ext_in_pkt[0].TEST1 = iccm_ext_in_pkt_TEST1_0;
assign iccm_ext_in_pkt[0].RME = iccm_ext_in_pkt_RME_0;
assign iccm_ext_in_pkt[0].RM = iccm_ext_in_pkt_RM_0[3:0];
assign iccm_ext_in_pkt[0].LS = iccm_ext_in_pkt_LS_0;
assign iccm_ext_in_pkt[0].DS = iccm_ext_in_pkt_DS_0;
assign iccm_ext_in_pkt[0].SD = iccm_ext_in_pkt_SD_0;
assign iccm_ext_in_pkt[0].TEST_RNM = iccm_ext_in_pkt_TEST_RNM_0;
assign iccm_ext_in_pkt[0].BC1 = iccm_ext_in_pkt_BC1_0;
assign iccm_ext_in_pkt[0].BC2 = iccm_ext_in_pkt_BC2_0;
assign iccm_ext_in_pkt[1].TEST1 = iccm_ext_in_pkt_TEST1_1;
assign iccm_ext_in_pkt[1].RME = iccm_ext_in_pkt_RME_1;
assign iccm_ext_in_pkt[1].RM = iccm_ext_in_pkt_RM_1[3:0];
assign iccm_ext_in_pkt[1].LS = iccm_ext_in_pkt_LS_1;
assign iccm_ext_in_pkt[1].DS = iccm_ext_in_pkt_DS_1;
assign iccm_ext_in_pkt[1].SD = iccm_ext_in_pkt_SD_1;
assign iccm_ext_in_pkt[1].TEST_RNM = iccm_ext_in_pkt_TEST_RNM_1;
assign iccm_ext_in_pkt[1].BC1 = iccm_ext_in_pkt_BC1_1;
assign iccm_ext_in_pkt[1].BC2 = iccm_ext_in_pkt_BC2_1;
assign iccm_ext_in_pkt[2].TEST1 = iccm_ext_in_pkt_TEST1_2;
assign iccm_ext_in_pkt[2].RME = iccm_ext_in_pkt_RME_2;
assign iccm_ext_in_pkt[2].RM = iccm_ext_in_pkt_RM_2[3:0];
assign iccm_ext_in_pkt[2].LS = iccm_ext_in_pkt_LS_2;
assign iccm_ext_in_pkt[2].DS = iccm_ext_in_pkt_DS_2;
assign iccm_ext_in_pkt[2].SD = iccm_ext_in_pkt_SD_2;
assign iccm_ext_in_pkt[2].TEST_RNM = iccm_ext_in_pkt_TEST_RNM_2;
assign iccm_ext_in_pkt[2].BC1 = iccm_ext_in_pkt_BC1_2;
assign iccm_ext_in_pkt[2].BC2 = iccm_ext_in_pkt_BC2_2;
assign iccm_ext_in_pkt[3].TEST1 = iccm_ext_in_pkt_TEST1_3;
assign iccm_ext_in_pkt[3].RME = iccm_ext_in_pkt_RME_3;
assign iccm_ext_in_pkt[3].RM = iccm_ext_in_pkt_RM_3[3:0];
assign iccm_ext_in_pkt[3].LS = iccm_ext_in_pkt_LS_3;
assign iccm_ext_in_pkt[3].DS = iccm_ext_in_pkt_DS_3;
assign iccm_ext_in_pkt[3].SD = iccm_ext_in_pkt_SD_3;
assign iccm_ext_in_pkt[3].TEST_RNM = iccm_ext_in_pkt_TEST_RNM_3;
assign iccm_ext_in_pkt[3].BC1 = iccm_ext_in_pkt_BC1_3;
assign iccm_ext_in_pkt[3].BC2 = iccm_ext_in_pkt_BC2_3;
assign ic_tag_ext_in_pkt[0].TEST1 = ic_tag_ext_in_pkt_TEST1_0;
assign ic_tag_ext_in_pkt[0].RME = ic_tag_ext_in_pkt_RME_0;
assign ic_tag_ext_in_pkt[0].RM = ic_tag_ext_in_pkt_RM_0[3:0];
assign ic_tag_ext_in_pkt[0].LS = ic_tag_ext_in_pkt_LS_0;
assign ic_tag_ext_in_pkt[0].DS = ic_tag_ext_in_pkt_DS_0;
assign ic_tag_ext_in_pkt[0].SD = ic_tag_ext_in_pkt_SD_0;
assign ic_tag_ext_in_pkt[0].TEST_RNM = ic_tag_ext_in_pkt_TEST_RNM_0;
assign ic_tag_ext_in_pkt[0].BC1 = ic_tag_ext_in_pkt_BC1_0;
assign ic_tag_ext_in_pkt[0].BC2 = ic_tag_ext_in_pkt_BC2_0;
assign ic_tag_ext_in_pkt[1].TEST1 = ic_tag_ext_in_pkt_TEST1_1;
assign ic_tag_ext_in_pkt[1].RME = ic_tag_ext_in_pkt_RME_1;
assign ic_tag_ext_in_pkt[1].RM = ic_tag_ext_in_pkt_RM_1[3:0];
assign ic_tag_ext_in_pkt[1].LS = ic_tag_ext_in_pkt_LS_1;
assign ic_tag_ext_in_pkt[1].DS = ic_tag_ext_in_pkt_DS_1;
assign ic_tag_ext_in_pkt[1].SD = ic_tag_ext_in_pkt_SD_1;
assign ic_tag_ext_in_pkt[1].TEST_RNM = ic_tag_ext_in_pkt_TEST_RNM_1;
assign ic_tag_ext_in_pkt[1].BC1 = ic_tag_ext_in_pkt_BC1_1;
assign ic_tag_ext_in_pkt[1].BC2 = ic_tag_ext_in_pkt_BC2_1;
// PKT connection
assign ic_data_ext_in_pkt[0][0].TEST1 = ic_data_ext_in_pkt_0_TEST1_0;
assign ic_data_ext_in_pkt[0][0].RME = ic_data_ext_in_pkt_0_RME_0;
assign ic_data_ext_in_pkt[0][0].RM = ic_data_ext_in_pkt_0_RM_0[3:0];
assign ic_data_ext_in_pkt[0][0].LS = ic_data_ext_in_pkt_0_LS_0;
assign ic_data_ext_in_pkt[0][0].DS = ic_data_ext_in_pkt_0_DS_0;
assign ic_data_ext_in_pkt[0][0].SD = ic_data_ext_in_pkt_0_SD_0;
assign ic_data_ext_in_pkt[0][0].TEST_RNM = ic_data_ext_in_pkt_0_TEST_RNM_0;
assign ic_data_ext_in_pkt[0][0].BC1 = ic_data_ext_in_pkt_0_BC1_0;
assign ic_data_ext_in_pkt[0][0].BC2 = ic_data_ext_in_pkt_0_BC2_0;
assign ic_data_ext_in_pkt[0][1].TEST1 = ic_data_ext_in_pkt_1_TEST1_1;
assign ic_data_ext_in_pkt[0][1].RME = ic_data_ext_in_pkt_1_RME_1;
assign ic_data_ext_in_pkt[0][1].RM = ic_data_ext_in_pkt_1_RM_1[3:0];
assign ic_data_ext_in_pkt[0][1].LS = ic_data_ext_in_pkt_1_LS_1;
assign ic_data_ext_in_pkt[0][1].DS = ic_data_ext_in_pkt_1_DS_1;
assign ic_data_ext_in_pkt[0][1].SD = ic_data_ext_in_pkt_1_SD_1;
assign ic_data_ext_in_pkt[0][1].TEST_RNM = ic_data_ext_in_pkt_1_TEST_RNM_1;
assign ic_data_ext_in_pkt[0][1].BC1 = ic_data_ext_in_pkt_1_BC1_1;
assign ic_data_ext_in_pkt[0][1].BC2 = ic_data_ext_in_pkt_1_BC2_1;
assign ic_data_ext_in_pkt[1][0].TEST1 = ic_data_ext_in_pkt_1_TEST1_0;
assign ic_data_ext_in_pkt[1][0].RME = ic_data_ext_in_pkt_1_RME_0;
assign ic_data_ext_in_pkt[1][0].RM = ic_data_ext_in_pkt_1_RM_0[3:0];
assign ic_data_ext_in_pkt[1][0].LS = ic_data_ext_in_pkt_1_LS_0;
assign ic_data_ext_in_pkt[1][0].DS = ic_data_ext_in_pkt_1_DS_0;
assign ic_data_ext_in_pkt[1][0].SD = ic_data_ext_in_pkt_1_SD_0;
assign ic_data_ext_in_pkt[1][0].TEST_RNM = ic_data_ext_in_pkt_1_TEST_RNM_0;
assign ic_data_ext_in_pkt[1][0].BC1 = ic_data_ext_in_pkt_1_BC1_0;
assign ic_data_ext_in_pkt[1][0].BC2 = ic_data_ext_in_pkt_1_BC2_0;
assign ic_data_ext_in_pkt[1][1].TEST1 = ic_data_ext_in_pkt_1_TEST1_1;
assign ic_data_ext_in_pkt[1][1].RME = ic_data_ext_in_pkt_1_RME_1;
assign ic_data_ext_in_pkt[1][1].RM = ic_data_ext_in_pkt_1_RM_1[3:0];
assign ic_data_ext_in_pkt[1][1].LS = ic_data_ext_in_pkt_1_LS_1;
assign ic_data_ext_in_pkt[1][1].DS = ic_data_ext_in_pkt_1_DS_1;
assign ic_data_ext_in_pkt[1][1].SD = ic_data_ext_in_pkt_1_SD_1;
assign ic_data_ext_in_pkt[1][1].TEST_RNM = ic_data_ext_in_pkt_1_TEST_RNM_1;
assign ic_data_ext_in_pkt[1][1].BC1 = ic_data_ext_in_pkt_1_BC1_1;
assign ic_data_ext_in_pkt[1][1].BC2 = ic_data_ext_in_pkt_1_BC2_1;
wire active_clk;
rvoclkhdr active_cg ( .en(1'b1), .l1clk(active_clk), .* );
logic [ICACHE_BANKS_WAY-1:0][70:0] ic_wr_data;
assign ic_wr_data [0] = ic_wr_data_0;
assign ic_wr_data [1] = ic_wr_data_1;
// DCCM Instantiation
if (DCCM_ENABLE == 1) begin: Gen_dccm_enable
lsu_dccm_mem #(
@ -479,8 +112,7 @@ module mem#(
.DCCM_NUM_BANKS(DCCM_NUM_BANKS),
.DCCM_BANK_BITS(DCCM_BANK_BITS),
.DCCM_SIZE(DCCM_SIZE),
.DCCM_FDATA_WIDTH(DCCM_FDATA_WIDTH),
.DCCM_WIDTH_BITS(DCCM_WIDTH_BITS)) dccm (
.DCCM_FDATA_WIDTH(DCCM_FDATA_WIDTH)) dccm (
.clk_override(dccm_clk_override),
.*
);
@ -505,14 +137,7 @@ if ( ICACHE_ENABLE ) begin: icache
.ICACHE_TAG_DEPTH(ICACHE_TAG_DEPTH),
.ICACHE_WAYPACK(ICACHE_WAYPACK),
.ICACHE_TAG_INDEX_LO(ICACHE_TAG_INDEX_LO),
.ICACHE_DATA_DEPTH(ICACHE_DATA_DEPTH),
.ICACHE_TAG_NUM_BYPASS(ICACHE_TAG_NUM_BYPASS),
.ICACHE_TAG_NUM_BYPASS_WIDTH(ICACHE_TAG_NUM_BYPASS_WIDTH),
.ICACHE_TAG_BYPASS_ENABLE(ICACHE_TAG_BYPASS_ENABLE),
.ICACHE_NUM_BYPASS_WIDTH(ICACHE_NUM_BYPASS_WIDTH),
.ICACHE_BYPASS_ENABLE(ICACHE_BYPASS_ENABLE),
.ICACHE_NUM_BYPASS(ICACHE_NUM_BYPASS),
.ICACHE_LN_SZ(ICACHE_LN_SZ)) icm (
.ICACHE_DATA_DEPTH(ICACHE_DATA_DEPTH)) icm (
.clk_override(icm_clk_override),
.*
);
@ -527,13 +152,13 @@ end // else: !if( ICACHE_ENABLE )
if (ICCM_ENABLE) begin : iccm
ifu_iccm_mem #(
ifu_iccm_mem #(
.ICCM_BITS(ICCM_BITS),
.ICCM_BANK_INDEX_LO(ICCM_BANK_INDEX_LO),
.ICCM_INDEX_BITS(ICCM_INDEX_BITS),
.ICCM_BANK_HI(ICCM_BANK_HI),
.ICCM_NUM_BANKS(ICCM_NUM_BANKS),
.ICCM_BANK_BITS(ICCM_BANK_BITS)) iccm (.*,
.ICCM_BANK_BITS(ICCM_BANK_BITS)) iccm (.*,
.clk_override(icm_clk_override),
.iccm_rw_addr(iccm_rw_addr[ICCM_BITS-1:1]),
.iccm_rd_data(iccm_rd_data[63:0])
@ -546,4 +171,3 @@ end
endmodule

View File

@ -16,17 +16,7 @@
`define EL2_LOCAL_RAM_TEST_IO \
input logic WE, \
input logic ME, \
input logic CLK, \
input logic TEST1, \
input logic RME, \
input logic [3:0] RM, \
input logic LS, \
input logic DS, \
input logic SD, \
input logic TEST_RNM, \
input logic BC1, \
input logic BC2, \
output logic ROP
input logic CLK
`define EL2_RAM(depth, width) \
module ram_``depth``x``width( \
@ -36,22 +26,11 @@ module ram_``depth``x``width( \
`EL2_LOCAL_RAM_TEST_IO \
); \
reg [(width-1):0] ram_core [(depth-1):0]; \
`ifdef GTLSIM \
integer i; \
initial begin \
for (i=0; i<depth; i=i+1) \
ram_core[i] = '0; \
end \
`endif \
always @(posedge CLK) begin \
`ifdef GTLSIM \
if (ME && WE) ram_core[ADR] <= D; \
`else \
if (ME && WE) begin ram_core[ADR] <= D; Q <= 'x; end \
`endif \
\
always @(posedge CLK) begin \
if (ME && WE) ram_core[ADR] = D; \
if (ME && ~WE) Q <= ram_core[ADR]; \
end \
assign ROP = ME; \
\
endmodule
@ -63,22 +42,12 @@ module ram_be_``depth``x``width( \
`EL2_LOCAL_RAM_TEST_IO \
); \
reg [(width-1):0] ram_core [(depth-1):0]; \
`ifdef GTLSIM \
integer i; \
initial begin \
for (i=0; i<depth; i=i+1) \
ram_core[i] = '0; \
\
always @(posedge CLK) begin \
if (ME && WE) ram_core[ADR] = D & WEM | ~WEM & ram_core[ADR];\
if (ME && ~WE) Q <= ram_core[ADR]; \
end \
`endif \
always @(posedge CLK) begin \
`ifdef GTLSIM \
if (ME && WE) ram_core[ADR] <= D & WEM | ~WEM & ram_core[ADR]; \
`else \
if (ME && WE) begin ram_core[ADR] <= D & WEM | ~WEM & ram_core[ADR]; Q <= 'x; end \
`endif \
if (ME && ~WE) Q <= ram_core[ADR]; \
end \
assign ROP = ME; \
\
\
endmodule
@ -92,11 +61,7 @@ output logic [(width-1):0] Q,
reg [(width-1):0] ram_core [(depth-1):0];
always @(posedge CLK) begin
`ifdef GTLSIM
if (ME && WE) ram_core[ADR] <= D;
`else
if (ME && WE) begin ram_core[ADR] <= D; Q <= 'x; end
`endif
if (ME && WE) ram_core[ADR] = D;
if (ME && ~WE) Q <= ram_core[ADR];
end
endmodule
@ -207,7 +172,6 @@ endmodule
`EL2_RAM_BE(256, 52)
`EL2_RAM_BE(128, 52)
`EL2_RAM_BE(64, 52)
`EL2_RAM_BE(32, 52)
`EL2_RAM_BE(4096, 104)
`EL2_RAM_BE(2048, 104)
`EL2_RAM_BE(1024, 104)
@ -215,7 +179,6 @@ endmodule
`EL2_RAM_BE(256, 104)
`EL2_RAM_BE(128, 104)
`EL2_RAM_BE(64, 104)
`EL2_RAM_BE(32, 104)
`EL2_RAM_BE(4096, 44)
`EL2_RAM_BE(2048, 44)
`EL2_RAM_BE(1024, 44)
@ -223,7 +186,6 @@ endmodule
`EL2_RAM_BE(256, 44)
`EL2_RAM_BE(128, 44)
`EL2_RAM_BE(64, 44)
`EL2_RAM_BE(32, 44)
`EL2_RAM_BE(4096, 88)
`EL2_RAM_BE(2048, 88)
`EL2_RAM_BE(1024, 88)
@ -231,8 +193,6 @@ endmodule
`EL2_RAM_BE(256, 88)
`EL2_RAM_BE(128, 88)
`EL2_RAM_BE(64, 88)
`EL2_RAM_BE(32, 88)
`EL2_RAM(64, 39)
`undef EL2_RAM
@ -240,4 +200,3 @@ endmodule
`undef EL2_LOCAL_RAM_TEST_IO

View File

@ -62,4 +62,3 @@ module el2_btb_ghr_hash #(
endmodule

View File

@ -1,178 +0,0 @@
#(parameter AWIDTH = 7,
TAG = 1'h1,
BHT_ADDR_HI = 4'h9,
BHT_ADDR_LO = 2'h2,
BHT_ARRAY_DEPTH = 11'h100,
BHT_GHR_HASH_1 = 1'h0,
BHT_GHR_SIZE = 4'h8,
BHT_SIZE = 12'h200,
BTB_ADDR_HI = 5'h09,
BTB_ADDR_LO = 2'h2,
BTB_ARRAY_DEPTH = 9'h100,
BTB_BTAG_FOLD = 1'h0,
BTB_BTAG_SIZE = 4'h5,
BTB_FOLD2_INDEX_HASH = 1'h0,
BTB_INDEX1_HI = 5'h09,
BTB_INDEX1_LO = 5'h02,
BTB_INDEX2_HI = 5'h11,
BTB_INDEX2_LO = 5'h0A,
BTB_INDEX3_HI = 5'h19,
BTB_INDEX3_LO = 5'h12,
BTB_SIZE = 10'h200,
BUILD_AHB_LITE = 1'h0,
BUILD_AXI4 = 1'h1,
BUILD_AXI_NATIVE = 1'h1,
BUS_PRTY_DEFAULT = 2'h3,
DATA_ACCESS_ADDR0 = 32'h00000000,
DATA_ACCESS_ADDR1 = 32'h00000000,
DATA_ACCESS_ADDR2 = 32'h00000000,
DATA_ACCESS_ADDR3 = 32'h00000000,
DATA_ACCESS_ADDR4 = 32'h00000000,
DATA_ACCESS_ADDR5 = 32'h00000000,
DATA_ACCESS_ADDR6 = 32'h00000000,
DATA_ACCESS_ADDR7 = 32'h00000000,
DATA_ACCESS_ENABLE0 = 1'h0,
DATA_ACCESS_ENABLE1 = 1'h0,
DATA_ACCESS_ENABLE2 = 1'h0,
DATA_ACCESS_ENABLE3 = 1'h0,
DATA_ACCESS_ENABLE4 = 1'h0,
DATA_ACCESS_ENABLE5 = 1'h0,
DATA_ACCESS_ENABLE6 = 1'h0,
DATA_ACCESS_ENABLE7 = 1'h0,
DATA_ACCESS_MASK0 = 32'h0FFFFFFF,
DATA_ACCESS_MASK1 = 32'h0FFFFFFF,
DATA_ACCESS_MASK2 = 32'h0FFFFFFF,
DATA_ACCESS_MASK3 = 32'h0FFFFFFF,
DATA_ACCESS_MASK4 = 32'h0FFFFFFF,
DATA_ACCESS_MASK5 = 32'h0FFFFFFF,
DATA_ACCESS_MASK6 = 32'h0FFFFFFF,
DATA_ACCESS_MASK7 = 32'h0FFFFFFF,
DCCM_BANK_BITS = 3'h2,
DCCM_BITS = 5'h10,
DCCM_BYTE_WIDTH = 3'h4,
DCCM_DATA_WIDTH = 6'h20,
DCCM_ECC_WIDTH = 3'h7,
DCCM_ENABLE = 1'h1,
DCCM_FDATA_WIDTH = 6'h27,
//DCCM_INDEX_BITS = 4'hC,
DCCM_NUM_BANKS = 5'h04,
DCCM_REGION = 4'hF,
DCCM_SADR = 32'hF0040000,
DCCM_SIZE = 10'h040,
//DCCM_WIDTH_BITS = 2'h2,
DMA_BUF_DEPTH = 3'h5,
DMA_BUS_ID = 1'h1,
DMA_BUS_PRTY = 2'h2,
DMA_BUS_TAG = 4'h1,
FAST_INTERRUPT_REDIRECT = 1'h1,
ICACHE_2BANKS = 1'h1,
ICACHE_BANK_BITS = 3'h1,
ICACHE_BANK_HI = 3'h3,
ICACHE_BANK_LO = 2'h3,
ICACHE_BANK_WIDTH = 4'h8,
ICACHE_BANKS_WAY = 3'h2,
ICACHE_BEAT_ADDR_HI = 4'h5,
ICACHE_BEAT_BITS = 4'h3,
ICACHE_DATA_DEPTH = 14'h0200,
ICACHE_DATA_INDEX_LO = 3'h4,
ICACHE_DATA_WIDTH = 7'h40,
ICACHE_ECC = 1'h1,
ICACHE_ENABLE = 1'h1,
ICACHE_FDATA_WIDTH = 7'h47,
ICACHE_INDEX_HI = 5'h0C,
ICACHE_LN_SZ = 7'h40,
ICACHE_NUM_BEATS = 4'h8,
ICACHE_NUM_WAYS = 3'h2,
ICACHE_ONLY = 1'h0,
ICACHE_SCND_LAST = 4'h6,
ICACHE_SIZE = 9'h010,
ICACHE_STATUS_BITS = 3'h1,
ICACHE_TAG_DEPTH = 13'h0080,
ICACHE_TAG_INDEX_LO = 3'h6,
ICACHE_TAG_LO = 5'h0D,
ICACHE_WAYPACK = 1'h0,
ICCM_BANK_BITS = 3'h2,
ICCM_BANK_HI = 5'h03,
ICCM_BANK_INDEX_LO = 5'h04,
ICCM_BITS = 5'h10,
ICCM_ENABLE = 1'h1,
ICCM_ICACHE = 1'h1,
ICCM_INDEX_BITS = 4'hC,
ICCM_NUM_BANKS = 5'h04,
ICCM_ONLY = 1'h0,
ICCM_REGION = 4'hE,
ICCM_SADR = 32'hEE000000,
ICCM_SIZE = 10'h040,
IFU_BUS_ID = 1'h1,
IFU_BUS_PRTY = 2'h2,
IFU_BUS_TAG = 4'h3,
INST_ACCESS_ADDR0 = 32'h00000000,
INST_ACCESS_ADDR1 = 32'h00000000,
INST_ACCESS_ADDR2 = 32'h00000000,
INST_ACCESS_ADDR3 = 32'h00000000,
INST_ACCESS_ADDR4 = 32'h00000000,
INST_ACCESS_ADDR5 = 32'h00000000,
INST_ACCESS_ADDR6 = 32'h00000000,
INST_ACCESS_ADDR7 = 32'h00000000,
INST_ACCESS_ENABLE0 = 1'h0,
INST_ACCESS_ENABLE1 = 1'h0,
INST_ACCESS_ENABLE2 = 1'h0,
INST_ACCESS_ENABLE3 = 1'h0,
INST_ACCESS_ENABLE4 = 1'h0,
INST_ACCESS_ENABLE5 = 1'h0,
INST_ACCESS_ENABLE6 = 1'h0,
INST_ACCESS_ENABLE7 = 1'h0,
INST_ACCESS_MASK0 = 32'h0FFFFFFF,
INST_ACCESS_MASK1 = 32'h0FFFFFFF,
INST_ACCESS_MASK2 = 32'h0FFFFFFF,
INST_ACCESS_MASK3 = 32'h0FFFFFFF,
INST_ACCESS_MASK4 = 32'h0FFFFFFF,
INST_ACCESS_MASK5 = 32'h0FFFFFFF,
INST_ACCESS_MASK6 = 32'h0FFFFFFF,
INST_ACCESS_MASK7 = 32'h0FFFFFFF,
LOAD_TO_USE_PLUS1 = 1'h0,
LSU2DMA = 1'h0,
LSU_BUS_ID = 1'h1,
LSU_BUS_PRTY = 2'h2,
LSU_BUS_TAG = 4'h3,
LSU_NUM_NBLOAD = 5'h04,
LSU_NUM_NBLOAD_WIDTH = 3'h2,
LSU_SB_BITS = 5'h10,
LSU_STBUF_DEPTH = 4'h4,
NO_ICCM_NO_ICACHE = 1'h0,
PIC_2CYCLE = 1'h0,
PIC_BASE_ADDR = 32'hF00C0000,
PIC_BITS = 5'h0F,
PIC_INT_WORDS = 4'h1,
PIC_REGION = 4'hF,
PIC_SIZE = 9'h020,
PIC_TOTAL_INT = 8'h1F,
PIC_TOTAL_INT_PLUS1 = 9'h020,
RET_STACK_SIZE = 4'h8,
SB_BUS_ID = 1'h1,
SB_BUS_PRTY = 2'h2,
SB_BUS_TAG = 4'h1,
TIMER_LEGAL_EN = 1'h1,
RV_FPGA_OPTIMIZE = 5'h01,
DIV_NEW = 5'h01,
DIV_BIT = 7'h04,
BTB_ENABLE = 5'h01,
BTB_TOFFSET_SIZE = 9'h00C,
BTB_FULLYA = 5'h00,
BITMANIP_ZBA = 5'h00 ,
BITMANIP_ZBB = 5'h01 ,
BITMANIP_ZBC = 5'h00 ,
BITMANIP_ZBE = 5'h00 ,
BITMANIP_ZBF = 5'h00 ,
BITMANIP_ZBP = 5'h00 ,
BITMANIP_ZBR = 5'h00 ,
BITMANIP_ZBS = 5'h01 ,
ICACHE_BYPASS_ENABLE = 5'h01,
ICACHE_NUM_BYPASS = 8'h02,
ICACHE_NUM_BYPASS_WIDTH = 8'h02,
ICACHE_TAG_BYPASS_ENABLE = 5'h01,
ICACHE_TAG_NUM_BYPASS = 8'h02,
ICACHE_TAG_NUM_BYPASS_WIDTH = 8'h02
)

View File

@ -1,111 +0,0 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// raminfr.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// Inferrable Distributed RAM for FIFOs ////
//// ////
//// Known problems (limits): ////
//// None . ////
//// ////
//// To Do: ////
//// Nothing so far. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// ////
//// Created: 2002/07/22 ////
//// Last Updated: 2002/07/22 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
//Following is the Verilog code for a dual-port RAM with asynchronous read.
module raminfr
(clk, we, a, dpra, di, dpo);
parameter addr_width = 4;
parameter data_width = 8;
parameter depth = 16;
input clk;
input we;
input [addr_width-1:0] a;
input [addr_width-1:0] dpra;
input [data_width-1:0] di;
//output [data_width-1:0] spo;
output [data_width-1:0] dpo;
reg [data_width-1:0] ram [depth-1:0];
wire [data_width-1:0] dpo;
wire [data_width-1:0] di;
wire [addr_width-1:0] a;
wire [addr_width-1:0] dpra;
always @(posedge clk) begin
if (we)
ram[a] <= di;
end
// assign spo = ram[a];
assign dpo = ram[dpra];
endmodule

View File

@ -1,335 +0,0 @@
/////////////////////////////////////////////////////////////////////
//// ////
//// OpenCores MC68HC11E based SPI interface ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// www.asics.ws ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002 Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
// CVS Log
//
// $Id: simple_spi_top.v,v 1.5 2004-02-28 15:59:50 rherveille Exp $
//
// $Date: 2004-02-28 15:59:50 $
// $Revision: 1.5 $
// $Author: rherveille $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
// Revision 1.4 2003/08/01 11:41:54 rherveille
// Fixed some timing bugs.
//
// Revision 1.3 2003/01/09 16:47:59 rherveille
// Updated clkcnt size and decoding due to new SPR bit assignments.
//
// Revision 1.2 2003/01/07 13:29:52 rherveille
// Changed SPR bits coding.
//
// Revision 1.1.1.1 2002/12/22 16:07:15 rherveille
// Initial release
//
//
//
// Motorola MC68HC11E based SPI interface
//
// Currently only MASTER mode is supported
//
module simple_spi #(
parameter SS_WIDTH = 1
)(
// 8bit WISHBONE bus slave interface
input wire clk_i, // clock
input wire rst_i, // reset (synchronous active high)
input wire cyc_i, // cycle
input wire stb_i, // strobe
input wire [2:0] adr_i, // address
input wire we_i, // write enable
input wire [7:0] dat_i, // data input
output reg [7:0] dat_o, // data output
output reg ack_o, // normal bus termination
output reg inta_o, // interrupt output
// SPI port
output reg sck_o, // serial clock output
output [SS_WIDTH-1:0] ss_o, // slave select (active low)
output wire mosi_o, // MasterOut SlaveIN
input wire miso_i // MasterIn SlaveOut
);
//
// Module body
//
reg [7:0] spcr; // Serial Peripheral Control Register ('HC11 naming)
wire [7:0] spsr; // Serial Peripheral Status Register ('HC11 naming)
reg [7:0] sper; // Serial Peripheral Extension Register
reg [7:0] treg; // Transmit Register
reg [SS_WIDTH-1:0] ss_r; // Slave Select Register
// fifo signals
wire [7:0] rfdout;
reg wfre, rfwe;
wire rfre, rffull, rfempty;
wire [7:0] wfdout;
wire wfwe, wffull, wfempty;
// misc signals
wire tirq; // transfer interrupt (selected number of transfers done)
wire wfov; // write fifo overrun (writing while fifo full)
reg [1:0] state; // statemachine state
reg [2:0] bcnt;
//
// Wishbone interface
wire wb_acc = cyc_i & stb_i; // WISHBONE access
wire wb_wr = wb_acc & we_i; // WISHBONE write access
// dat_i
always @(posedge clk_i)
if (rst_i)
begin
spcr <= 8'h10; // set master bit
sper <= 8'h00;
ss_r <= 0;
end
else if (wb_wr)
begin
if (adr_i == 3'b000)
spcr <= dat_i | 8'h10; // always set master bit
if (adr_i == 3'b011)
sper <= dat_i;
if (adr_i == 3'b100)
ss_r <= dat_i[SS_WIDTH-1:0];
end
// slave select (active low)
assign ss_o = ~ss_r;
// write fifo
assign wfwe = wb_acc & (adr_i == 3'b010) & ack_o & we_i;
assign wfov = wfwe & wffull;
// dat_o
always @(posedge clk_i)
case(adr_i) // synopsys full_case parallel_case
3'b000: dat_o <= spcr;
3'b001: dat_o <= spsr;
3'b010: dat_o <= rfdout;
3'b011: dat_o <= sper;
3'b100: dat_o <= {{ (8-SS_WIDTH){1'b0} }, ss_r};
default: dat_o <= 0;
endcase
// read fifo
assign rfre = wb_acc & (adr_i == 3'b010) & ack_o & ~we_i;
// ack_o
always @(posedge clk_i)
if (rst_i)
ack_o <= 1'b0;
else
ack_o <= wb_acc & !ack_o;
// decode Serial Peripheral Control Register
wire spie = spcr[7]; // Interrupt enable bit
wire spe = spcr[6]; // System Enable bit
wire dwom = spcr[5]; // Port D Wired-OR Mode Bit
wire mstr = spcr[4]; // Master Mode Select Bit
wire cpol = spcr[3]; // Clock Polarity Bit
wire cpha = spcr[2]; // Clock Phase Bit
wire [1:0] spr = spcr[1:0]; // Clock Rate Select Bits
// decode Serial Peripheral Extension Register
wire [1:0] icnt = sper[7:6]; // interrupt on transfer count
wire [1:0] spre = sper[1:0]; // extended clock rate select
wire [3:0] espr = {spre, spr};
// generate status register
wire wr_spsr = wb_wr & (adr_i == 3'b001);
reg spif;
always @(posedge clk_i)
if (~spe | rst_i)
spif <= 1'b0;
else
spif <= (tirq | spif) & ~(wr_spsr & dat_i[7]);
reg wcol;
always @(posedge clk_i)
if (~spe | rst_i)
wcol <= 1'b0;
else
wcol <= (wfov | wcol) & ~(wr_spsr & dat_i[6]);
assign spsr[7] = spif;
assign spsr[6] = wcol;
assign spsr[5:4] = 2'b00;
assign spsr[3] = wffull;
assign spsr[2] = wfempty;
assign spsr[1] = rffull;
assign spsr[0] = rfempty;
// generate IRQ output (inta_o)
always @(posedge clk_i)
inta_o <= spif & spie;
//
// hookup read/write buffer fifo
fifo4 #(8)
rfifo(
.clk ( clk_i ),
.rst ( ~rst_i ),
.clr ( ~spe ),
.din ( treg ),
.we ( rfwe ),
.dout ( rfdout ),
.re ( rfre ),
.full ( rffull ),
.empty ( rfempty )
),
wfifo(
.clk ( clk_i ),
.rst ( ~rst_i ),
.clr ( ~spe ),
.din ( dat_i ),
.we ( wfwe ),
.dout ( wfdout ),
.re ( wfre ),
.full ( wffull ),
.empty ( wfempty )
);
//
// generate clk divider
reg [11:0] clkcnt;
always @(posedge clk_i)
if(spe & (|clkcnt & |state))
clkcnt <= clkcnt - 11'h1;
else
case (espr) // synopsys full_case parallel_case
4'b0000: clkcnt <= 12'h0; // 2 -- original M68HC11 coding
4'b0001: clkcnt <= 12'h1; // 4 -- original M68HC11 coding
4'b0010: clkcnt <= 12'h3; // 16 -- original M68HC11 coding
4'b0011: clkcnt <= 12'hf; // 32 -- original M68HC11 coding
4'b0100: clkcnt <= 12'h1f; // 8
4'b0101: clkcnt <= 12'h7; // 64
4'b0110: clkcnt <= 12'h3f; // 128
4'b0111: clkcnt <= 12'h7f; // 256
4'b1000: clkcnt <= 12'hff; // 512
4'b1001: clkcnt <= 12'h1ff; // 1024
4'b1010: clkcnt <= 12'h3ff; // 2048
4'b1011: clkcnt <= 12'h7ff; // 4096
default : clkcnt <= 12'hfff;
endcase
// generate clock enable signal
wire ena = ~|clkcnt;
// transfer statemachine
always @(posedge clk_i)
if (~spe | rst_i)
begin
state <= 2'b00; // idle
bcnt <= 3'h0;
treg <= 8'h00;
wfre <= 1'b0;
rfwe <= 1'b0;
sck_o <= 1'b0;
end
else
begin
wfre <= 1'b0;
rfwe <= 1'b0;
case (state) //synopsys full_case parallel_case
2'b00: // idle state
begin
bcnt <= 3'h7; // set transfer counter
treg <= wfdout; // load transfer register
sck_o <= cpol; // set sck
if (~wfempty) begin
wfre <= 1'b1;
state <= 2'b01;
if (cpha) sck_o <= ~sck_o;
end
end
2'b01: // clock-phase2, next data
if (ena) begin
sck_o <= ~sck_o;
state <= 2'b11;
end
2'b11: // clock phase1
if (ena) begin
treg <= {treg[6:0], miso_i};
bcnt <= bcnt -3'h1;
if (~|bcnt) begin
state <= 2'b00;
sck_o <= cpol;
rfwe <= 1'b1;
end else begin
state <= 2'b01;
sck_o <= ~sck_o;
end
end
2'b10: state <= 2'b00;
endcase
end
assign mosi_o = treg[7];
// count number of transfers (for interrupt generation)
reg [1:0] tcnt; // transfer count
always @(posedge clk_i)
if (~spe)
tcnt <= icnt;
else if (rfwe) // rfwe gets asserted when all bits have been transfered
if (|tcnt)
tcnt <= tcnt - 2'h1;
else
tcnt <= icnt;
assign tirq = ~|tcnt & rfwe;
endmodule

View File

@ -1,254 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019-2020 Western Digital Corporation or its affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//********************************************************************************
// $Id$
//
// Function: SweRVolf SoC-level controller
// Comments:
//
//********************************************************************************
module swervolf_syscon
#(parameter [31:0] clk_freq_hz = 0)
(input wire i_clk,
input wire i_rst,
input wire [63:0] i_gpio,
output reg [63:0] o_gpio,
output reg o_timer_irq,
output wire o_sw_irq3,
output wire o_sw_irq4,
input wire i_ram_init_done,
input wire i_ram_init_error,
output reg [31:0] o_nmi_vec,
output wire o_nmi_int,
input wire [5:0] i_wb_adr,
input wire [31:0] i_wb_dat,
input wire [3:0] i_wb_sel,
input wire i_wb_we,
input wire i_wb_cyc,
input wire i_wb_stb,
output reg [31:0] o_wb_rdt,
output reg o_wb_ack);
reg [63:0] mtime;
reg [63:0] mtimecmp;
reg sw_irq3;
reg sw_irq3_edge;
reg sw_irq3_pol;
reg sw_irq3_timer;
reg sw_irq4;
reg sw_irq4_edge;
reg sw_irq4_pol;
reg sw_irq4_timer;
reg irq_timer_en;
reg [31:0] irq_timer_cnt;
reg nmi_int;
reg nmi_int_r;
`ifdef SIMPRINT
reg [1023:0] signature_file;
integer f = 0;
initial begin
if ($value$plusargs("signature=%s", signature_file)) begin
$display("Writing signature to %0s", signature_file);
f = $fopen(signature_file, "w");
end
end
`endif
`ifndef VERSION_DIRTY
`define VERSION_DIRTY 1
`endif
`ifndef VERSION_MAJOR
`define VERSION_MAJOR 255
`endif
`ifndef VERSION_MINOR
`define VERSION_MINOR 255
`endif
`ifndef VERSION_REV
`define VERSION_REV 255
`endif
`ifndef VERSION_SHA
`define VERSION_SHA deadbeef
`endif
wire [31:0] version;
assign version[31] = `VERSION_DIRTY;
assign version[30:24] = `VERSION_REV;
assign version[23:16] = `VERSION_MAJOR;
assign version[15: 8] = `VERSION_MINOR;
assign version[ 7: 0] = `VERSION_PATCH;
assign o_sw_irq4 = sw_irq4^sw_irq4_pol;
assign o_sw_irq3 = sw_irq3^sw_irq3_pol;
assign o_nmi_int = nmi_int | nmi_int_r;
wire reg_we = i_wb_cyc & i_wb_stb & i_wb_we & !o_wb_ack;
//00 = ver
//04 = sha
//08 = simprint
//09 = simexit
//0A = RAM status
//0B = sw_irq
//10 = gpio
//20 = timer/timecmp
//40 = SPI
always @(posedge i_clk) begin
o_wb_ack <= i_wb_cyc & !o_wb_ack;
if (sw_irq3_edge)
sw_irq3 <= 1'b0;
if (sw_irq4_edge)
sw_irq4 <= 1'b0;
if (irq_timer_en)
irq_timer_cnt <= irq_timer_cnt - 1;
nmi_int <= 1'b0;
nmi_int_r <= nmi_int;
if (irq_timer_cnt == 32'd1) begin
irq_timer_en <= 1'b0;
if (sw_irq3_timer)
sw_irq3 <= 1'b1;
if (sw_irq4_timer)
sw_irq4 <= 1'b1;
if (!(sw_irq3_timer | sw_irq4_timer))
nmi_int <= 1'b1;
end
if (reg_we)
case (i_wb_adr[5:2])
2: begin //0x08-0x0B
`ifdef SIMPRINT
if (i_wb_sel[0]) begin
if (|f) $fwrite(f, "%c", i_wb_dat[7:0]);
$write("%c", i_wb_dat[7:0]);
end
if (i_wb_sel[1]) begin
$display("\nFinito");
$finish;
end
`endif
if (i_wb_sel[3]) begin
sw_irq4 <= i_wb_dat[31];
sw_irq4_edge <= i_wb_dat[30];
sw_irq4_pol <= i_wb_dat[29];
sw_irq4_timer <= i_wb_dat[28];
sw_irq3 <= i_wb_dat[27];
sw_irq3_edge <= i_wb_dat[26];
sw_irq3_pol <= i_wb_dat[25];
sw_irq3_timer <= i_wb_dat[24];
end
end
3: begin //0x0C-0x0F
if (i_wb_sel[0]) o_nmi_vec[7:0] <= i_wb_dat[7:0];
if (i_wb_sel[1]) o_nmi_vec[15:8] <= i_wb_dat[15:8];
if (i_wb_sel[2]) o_nmi_vec[23:16] <= i_wb_dat[23:16];
if (i_wb_sel[3]) o_nmi_vec[31:24] <= i_wb_dat[31:24];
end
4 : begin //0x10-0x13
if (i_wb_sel[0]) o_gpio[7:0] <= i_wb_dat[7:0] ;
if (i_wb_sel[1]) o_gpio[15:8] <= i_wb_dat[15:8] ;
if (i_wb_sel[2]) o_gpio[23:16] <= i_wb_dat[23:16];
if (i_wb_sel[3]) o_gpio[31:24] <= i_wb_dat[31:24];
end
5: begin //0x14-0x17
if (i_wb_sel[0]) o_gpio[39:32] <= i_wb_dat[7:0];
if (i_wb_sel[1]) o_gpio[47:40] <= i_wb_dat[15:8];
if (i_wb_sel[2]) o_gpio[55:48] <= i_wb_dat[23:16];
if (i_wb_sel[3]) o_gpio[63:56] <= i_wb_dat[31:24];
end
10 : begin //0x28-0x2B
if (i_wb_sel[0]) mtimecmp[7:0] <= i_wb_dat[7:0];
if (i_wb_sel[1]) mtimecmp[15:8] <= i_wb_dat[15:8];
if (i_wb_sel[2]) mtimecmp[23:16] <= i_wb_dat[23:16];
if (i_wb_sel[3]) mtimecmp[31:24] <= i_wb_dat[31:24];
end
11 : begin //0x2C-0x2F
if (i_wb_sel[0]) mtimecmp[39:32] <= i_wb_dat[7:0];
if (i_wb_sel[1]) mtimecmp[47:40] <= i_wb_dat[15:8];
if (i_wb_sel[2]) mtimecmp[55:48] <= i_wb_dat[23:16];
if (i_wb_sel[3]) mtimecmp[63:56] <= i_wb_dat[31:24];
end
12 : begin //0x30-3f
if (i_wb_sel[0]) irq_timer_cnt[7:0] <= i_wb_dat[7:0] ;
if (i_wb_sel[1]) irq_timer_cnt[15:8] <= i_wb_dat[15:8] ;
if (i_wb_sel[2]) irq_timer_cnt[23:16] <= i_wb_dat[23:16];
if (i_wb_sel[3]) irq_timer_cnt[31:24] <= i_wb_dat[31:24];
end
13 : begin
if (i_wb_sel[0])
irq_timer_en <= i_wb_dat[0];
end
endcase
case (i_wb_adr[5:2])
//0x00-0x03
0 : o_wb_rdt <= version;
//0x04-0x07
1 : o_wb_rdt <= 32'h`VERSION_SHA;
//0x08-0x0C
2 : begin
//0xB
o_wb_rdt[31:28] <= {sw_irq4, sw_irq4_edge, sw_irq4_pol, sw_irq4_timer};
o_wb_rdt[27:24] <= {sw_irq3, sw_irq3_edge, sw_irq3_pol, sw_irq3_timer};
//0xA
o_wb_rdt[23:18] <= 6'd0;
o_wb_rdt[17:16] <= {i_ram_init_error, i_ram_init_done};
//0x8-0x9
o_wb_rdt[15:0] <= 16'd0;
end
//0xC-0xF
3 : o_wb_rdt <= o_nmi_vec;
//0x10-0x13
4 : o_wb_rdt <= i_gpio[31:0];
//0x14-0x17
5 : o_wb_rdt <= i_gpio[63:32];
//0x20-0x23
8 : o_wb_rdt <= mtime[31:0];
//0x24-0x27
9 : o_wb_rdt <= mtime[63:32];
//0x28-0x2B
10 : o_wb_rdt <= mtimecmp[31:0];
//0x2C-0x2F
11 : o_wb_rdt <= mtimecmp[63:32];
//0x30-0x33
12 : o_wb_rdt <= irq_timer_cnt;
//0x34-0x37
13 : o_wb_rdt <= {31'd0, irq_timer_en};
//0x3C
15 : o_wb_rdt <= clk_freq_hz;
endcase
mtime <= mtime + 64'd1;
o_timer_irq <= (mtime >= mtimecmp);
if (i_rst) begin
mtime <= 64'd0;
mtimecmp <= 64'd0;
o_wb_ack <= 1'b0;
end
end
endmodule

View File

@ -1,233 +0,0 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_defines.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// Defines of the Core ////
//// ////
//// Known problems (limits): ////
//// None ////
//// ////
//// To Do: ////
//// Nothing. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// - Igor Mohor (igorm@opencores.org) ////
//// ////
//// Created: 2001/05/12 ////
//// Last Updated: 2001/05/17 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.13 2003/06/11 16:37:47 gorban
// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
//
// Revision 1.12 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
// Revision 1.10 2001/12/11 08:55:40 mohor
// Scratch register define added.
//
// Revision 1.9 2001/12/03 21:44:29 gorban
// Updated specification documentation.
// Added full 32-bit data bus interface, now as default.
// Address is 5-bit wide in 32-bit data bus mode.
// Added wb_sel_i input to the core. It's used in the 32-bit mode.
// Added debug interface with two 32-bit read-only registers in 32-bit mode.
// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
// My small test bench is modified to work with 32-bit mode.
//
// Revision 1.8 2001/11/26 21:38:54 gorban
// Lots of fixes:
// Break condition wasn't handled correctly at all.
// LSR bits could lose their values.
// LSR value after reset was wrong.
// Timing of THRE interrupt signal corrected.
// LSR bit 0 timing corrected.
//
// Revision 1.7 2001/08/24 21:01:12 mohor
// Things connected to parity changed.
// Clock devider changed.
//
// Revision 1.6 2001/08/23 16:05:05 mohor
// Stop bit bug fixed.
// Parity bug fixed.
// WISHBONE read cycle bug fixed,
// OE indicator (Overrun Error) bug fixed.
// PE indicator (Parity Error) bug fixed.
// Register read bug fixed.
//
// Revision 1.5 2001/05/31 20:08:01 gorban
// FIFO changes and other corrections.
//
// Revision 1.4 2001/05/21 19:12:02 gorban
// Corrected some Linter messages.
//
// Revision 1.3 2001/05/17 18:34:18 gorban
// First 'stable' release. Should be sythesizable now. Also added new header.
//
// Revision 1.0 2001-05-17 21:27:11+02 jacob
// Initial revision
//
//
// Uncomment this if you want your UART to have
// 16xBaudrate output port.
// If defined, the enable signal will be used to drive baudrate_o signal
// It's frequency is 16xbaudrate
// `define UART_HAS_BAUDRATE_OUTPUT
// Register addresses
`define UART_REG_RB 3'd0 // receiver buffer
`define UART_REG_TR 3'd0 // transmitter
`define UART_REG_IE 3'd1 // Interrupt enable
`define UART_REG_II 3'd2 // Interrupt identification
`define UART_REG_FC 3'd2 // FIFO control
`define UART_REG_LC 3'd3 // Line Control
`define UART_REG_MC 3'd4 // Modem control
`define UART_REG_LS 3'd5 // Line status
`define UART_REG_MS 3'd6 // Modem status
`define UART_REG_SR 3'd7 // Scratch register
`define UART_REG_DL1 3'd0 // Divisor latch bytes (1-2)
`define UART_REG_DL2 3'd1
// Interrupt Enable register bits
`define UART_IE_RDA 0 // Received Data available interrupt
`define UART_IE_THRE 1 // Transmitter Holding Register empty interrupt
`define UART_IE_RLS 2 // Receiver Line Status Interrupt
`define UART_IE_MS 3 // Modem Status Interrupt
// Interrupt Identification register bits
`define UART_II_IP 0 // Interrupt pending when 0
`define UART_II_II 3:1 // Interrupt identification
// Interrupt identification values for bits 3:1
`define UART_II_RLS 3'b011 // Receiver Line Status
`define UART_II_RDA 3'b010 // Receiver Data available
`define UART_II_TI 3'b110 // Timeout Indication
`define UART_II_THRE 3'b001 // Transmitter Holding Register empty
`define UART_II_MS 3'b000 // Modem Status
// FIFO Control Register bits
`define UART_FC_TL 1:0 // Trigger level
// FIFO trigger level values
`define UART_FC_1 2'b00
`define UART_FC_4 2'b01
`define UART_FC_8 2'b10
`define UART_FC_14 2'b11
// Line Control register bits
`define UART_LC_BITS 1:0 // bits in character
`define UART_LC_SB 2 // stop bits
`define UART_LC_PE 3 // parity enable
`define UART_LC_EP 4 // even parity
`define UART_LC_SP 5 // stick parity
`define UART_LC_BC 6 // Break control
`define UART_LC_DL 7 // Divisor Latch access bit
// Modem Control register bits
`define UART_MC_DTR 0
`define UART_MC_RTS 1
`define UART_MC_OUT1 2
`define UART_MC_OUT2 3
`define UART_MC_LB 4 // Loopback mode
// Line Status Register bits
`define UART_LS_DR 0 // Data ready
`define UART_LS_OE 1 // Overrun Error
`define UART_LS_PE 2 // Parity Error
`define UART_LS_FE 3 // Framing Error
`define UART_LS_BI 4 // Break interrupt
`define UART_LS_TFE 5 // Transmit FIFO is empty
`define UART_LS_TE 6 // Transmitter Empty indicator
`define UART_LS_EI 7 // Error indicator
// Modem Status Register bits
`define UART_MS_DCTS 0 // Delta signals
`define UART_MS_DDSR 1
`define UART_MS_TERI 2
`define UART_MS_DDCD 3
`define UART_MS_CCTS 4 // Complement signals
`define UART_MS_CDSR 5
`define UART_MS_CRI 6
`define UART_MS_CDCD 7
// FIFO parameter defines
`define UART_FIFO_WIDTH 8
`define UART_FIFO_DEPTH 16
`define UART_FIFO_POINTER_W 4
`define UART_FIFO_COUNTER_W 5
// receiver fifo has width 11 because it has break, parity and framing error bits
`define UART_FIFO_REC_WIDTH 11
`define VERBOSE_WB 0 // All activity on the WISHBONE is recorded
`define VERBOSE_LINE_STATUS 0 // Details about the lsr (line status register)
`define FAST_TEST 1 // 64/1024 packets are sent

View File

@ -1,475 +0,0 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_receiver.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// UART core receiver logic ////
//// ////
//// Known problems (limits): ////
//// None known ////
//// ////
//// To Do: ////
//// Thourough testing. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// - Igor Mohor (igorm@opencores.org) ////
//// ////
//// Created: 2001/05/12 ////
//// Last Updated: 2001/05/17 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.29 2002/07/29 21:16:18 gorban
// The uart_defines.v file is included again in sources.
//
// Revision 1.28 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
// Revision 1.27 2001/12/30 20:39:13 mohor
// More than one character was stored in case of break. End of the break
// was not detected correctly.
//
// Revision 1.26 2001/12/20 13:28:27 mohor
// Missing declaration of rf_push_q fixed.
//
// Revision 1.25 2001/12/20 13:25:46 mohor
// rx push changed to be only one cycle wide.
//
// Revision 1.24 2001/12/19 08:03:34 mohor
// Warnings cleared.
//
// Revision 1.23 2001/12/19 07:33:54 mohor
// Synplicity was having troubles with the comment.
//
// Revision 1.22 2001/12/17 14:46:48 mohor
// overrun signal was moved to separate block because many sequential lsr
// reads were preventing data from being written to rx fifo.
// underrun signal was not used and was removed from the project.
//
// Revision 1.21 2001/12/13 10:31:16 mohor
// timeout irq must be set regardless of the rda irq (rda irq does not reset the
// timeout counter).
//
// Revision 1.20 2001/12/10 19:52:05 gorban
// Igor fixed break condition bugs
//
// Revision 1.19 2001/12/06 14:51:04 gorban
// Bug in LSR[0] is fixed.
// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
//
// Revision 1.18 2001/12/03 21:44:29 gorban
// Updated specification documentation.
// Added full 32-bit data bus interface, now as default.
// Address is 5-bit wide in 32-bit data bus mode.
// Added wb_sel_i input to the core. It's used in the 32-bit mode.
// Added debug interface with two 32-bit read-only registers in 32-bit mode.
// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
// My small test bench is modified to work with 32-bit mode.
//
// Revision 1.17 2001/11/28 19:36:39 gorban
// Fixed: timeout and break didn't pay attention to current data format when counting time
//
// Revision 1.16 2001/11/27 22:17:09 gorban
// Fixed bug that prevented synthesis in uart_receiver.v
//
// Revision 1.15 2001/11/26 21:38:54 gorban
// Lots of fixes:
// Break condition wasn't handled correctly at all.
// LSR bits could lose their values.
// LSR value after reset was wrong.
// Timing of THRE interrupt signal corrected.
// LSR bit 0 timing corrected.
//
// Revision 1.14 2001/11/10 12:43:21 gorban
// Logic Synthesis bugs fixed. Some other minor changes
//
// Revision 1.13 2001/11/08 14:54:23 mohor
// Comments in Slovene language deleted, few small fixes for better work of
// old tools. IRQs need to be fix.
//
// Revision 1.12 2001/11/07 17:51:52 gorban
// Heavily rewritten interrupt and LSR subsystems.
// Many bugs hopefully squashed.
//
// Revision 1.11 2001/10/31 15:19:22 gorban
// Fixes to break and timeout conditions
//
// Revision 1.10 2001/10/20 09:58:40 gorban
// Small synopsis fixes
//
// Revision 1.9 2001/08/24 21:01:12 mohor
// Things connected to parity changed.
// Clock devider changed.
//
// Revision 1.8 2001/08/23 16:05:05 mohor
// Stop bit bug fixed.
// Parity bug fixed.
// WISHBONE read cycle bug fixed,
// OE indicator (Overrun Error) bug fixed.
// PE indicator (Parity Error) bug fixed.
// Register read bug fixed.
//
// Revision 1.6 2001/06/23 11:21:48 gorban
// DL made 16-bit long. Fixed transmission/reception bugs.
//
// Revision 1.5 2001/06/02 14:28:14 gorban
// Fixed receiver and transmitter. Major bug fixed.
//
// Revision 1.4 2001/05/31 20:08:01 gorban
// FIFO changes and other corrections.
//
// Revision 1.3 2001/05/27 17:37:49 gorban
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
//
// Revision 1.2 2001/05/21 19:12:02 gorban
// Corrected some Linter messages.
//
// Revision 1.1 2001/05/17 18:34:18 gorban
// First 'stable' release. Should be sythesizable now. Also added new header.
//
// Revision 1.0 2001-05-17 21:27:11+02 jacob
// Initial revision
//
//
`include "uart_defines.v"
module uart_receiver (clk, wb_rst_i, lcr, rf_pop, srx_pad_i, enable,
counter_t, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, lsr_mask, rstate, rf_push_pulse);
input clk;
input wb_rst_i;
input [7:0] lcr;
input rf_pop;
input srx_pad_i;
input enable;
input rx_reset;
input lsr_mask;
output [9:0] counter_t;
output [`UART_FIFO_COUNTER_W-1:0] rf_count;
output [`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
output rf_overrun;
output rf_error_bit;
output [3:0] rstate;
output rf_push_pulse;
reg [3:0] rstate;
reg [3:0] rcounter16;
reg [2:0] rbit_counter;
reg [7:0] rshift; // receiver shift register
reg rparity; // received parity
reg rparity_error;
reg rframing_error; // framing error flag
reg rparity_xor;
reg [7:0] counter_b; // counts the 0 (low) signals
reg rf_push_q;
// RX FIFO signals
reg [`UART_FIFO_REC_WIDTH-1:0] rf_data_in;
wire [`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
wire rf_push_pulse;
reg rf_push;
wire rf_pop;
wire rf_overrun;
wire [`UART_FIFO_COUNTER_W-1:0] rf_count;
wire rf_error_bit; // an error (parity or framing) is inside the fifo
wire break_error = (counter_b == 0);
// RX FIFO instance
uart_rfifo #(`UART_FIFO_REC_WIDTH) fifo_rx(
.clk( clk ),
.wb_rst_i( wb_rst_i ),
.data_in( rf_data_in ),
.data_out( rf_data_out ),
.push( rf_push_pulse ),
.pop( rf_pop ),
.overrun( rf_overrun ),
.count( rf_count ),
.error_bit( rf_error_bit ),
.fifo_reset( rx_reset ),
.reset_status(lsr_mask)
);
wire rcounter16_eq_7 = (rcounter16 == 4'd7);
wire rcounter16_eq_0 = (rcounter16 == 4'd0);
wire [3:0] rcounter16_minus_1 = rcounter16 - 3'd1;
parameter sr_idle = 4'd0;
parameter sr_rec_start = 4'd1;
parameter sr_rec_bit = 4'd2;
parameter sr_rec_parity = 4'd3;
parameter sr_rec_stop = 4'd4;
parameter sr_check_parity = 4'd5;
parameter sr_rec_prepare = 4'd6;
parameter sr_end_bit = 4'd7;
parameter sr_ca_lc_parity = 4'd8;
parameter sr_wait1 = 4'd9;
parameter sr_push = 4'd10;
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
begin
rstate <= sr_idle;
rcounter16 <= 0;
rbit_counter <= 0;
rparity_xor <= 1'b0;
rframing_error <= 1'b0;
rparity_error <= 1'b0;
rparity <= 1'b0;
rshift <= 0;
rf_push <= 1'b0;
rf_data_in <= 0;
end
else
if (enable)
begin
case (rstate)
sr_idle : begin
rf_push <= 1'b0;
rf_data_in <= 0;
rcounter16 <= 4'b1110;
if (srx_pad_i==1'b0 & ~break_error) // detected a pulse (start bit?)
begin
rstate <= sr_rec_start;
end
end
sr_rec_start : begin
rf_push <= 1'b0;
if (rcounter16_eq_7) // check the pulse
if (srx_pad_i==1'b1) // no start bit
rstate <= sr_idle;
else // start bit detected
rstate <= sr_rec_prepare;
rcounter16 <= rcounter16_minus_1;
end
sr_rec_prepare:begin
case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word
2'b00 : rbit_counter <= 3'b100;
2'b01 : rbit_counter <= 3'b101;
2'b10 : rbit_counter <= 3'b110;
2'b11 : rbit_counter <= 3'b111;
endcase
if (rcounter16_eq_0)
begin
rstate <= sr_rec_bit;
rcounter16 <= 4'b1110;
rshift <= 0;
end
else
rstate <= sr_rec_prepare;
rcounter16 <= rcounter16_minus_1;
end
sr_rec_bit : begin
if (rcounter16_eq_0)
rstate <= sr_end_bit;
if (rcounter16_eq_7) // read the bit
case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word
2'b00 : rshift[4:0] <= {srx_pad_i, rshift[4:1]};
2'b01 : rshift[5:0] <= {srx_pad_i, rshift[5:1]};
2'b10 : rshift[6:0] <= {srx_pad_i, rshift[6:1]};
2'b11 : rshift[7:0] <= {srx_pad_i, rshift[7:1]};
endcase
rcounter16 <= rcounter16_minus_1;
end
sr_end_bit : begin
if (rbit_counter==3'b0) // no more bits in word
if (lcr[`UART_LC_PE]) // choose state based on parity
rstate <= sr_rec_parity;
else
begin
rstate <= sr_rec_stop;
rparity_error <= 1'b0; // no parity - no error :)
end
else // else we have more bits to read
begin
rstate <= sr_rec_bit;
rbit_counter <= rbit_counter - 3'd1;
end
rcounter16 <= 4'b1110;
end
sr_rec_parity: begin
if (rcounter16_eq_7) // read the parity
begin
rparity <= srx_pad_i;
rstate <= sr_ca_lc_parity;
end
rcounter16 <= rcounter16_minus_1;
end
sr_ca_lc_parity : begin // rcounter equals 6
rcounter16 <= rcounter16_minus_1;
rparity_xor <= ^{rshift,rparity}; // calculate parity on all incoming data
rstate <= sr_check_parity;
end
sr_check_parity: begin // rcounter equals 5
case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]})
2'b00: rparity_error <= rparity_xor == 0; // no error if parity 1
2'b01: rparity_error <= ~rparity; // parity should sticked to 1
2'b10: rparity_error <= rparity_xor == 1; // error if parity is odd
2'b11: rparity_error <= rparity; // parity should be sticked to 0
endcase
rcounter16 <= rcounter16_minus_1;
rstate <= sr_wait1;
end
sr_wait1 : if (rcounter16_eq_0)
begin
rstate <= sr_rec_stop;
rcounter16 <= 4'b1110;
end
else
rcounter16 <= rcounter16_minus_1;
sr_rec_stop : begin
if (rcounter16_eq_7) // read the parity
begin
rframing_error <= !srx_pad_i; // no framing error if input is 1 (stop bit)
rstate <= sr_push;
end
rcounter16 <= rcounter16_minus_1;
end
sr_push : begin
///////////////////////////////////////
// $display($time, ": received: %b", rf_data_in);
if(srx_pad_i | break_error)
begin
if(break_error)
rf_data_in <= {8'b0, 3'b100}; // break input (empty character) to receiver FIFO
else
rf_data_in <= {rshift, 1'b0, rparity_error, rframing_error};
rf_push <= 1'b1;
rstate <= sr_idle;
end
else if(~rframing_error) // There's always a framing before break_error -> wait for break or srx_pad_i
begin
rf_data_in <= {rshift, 1'b0, rparity_error, rframing_error};
rf_push <= 1'b1;
rcounter16 <= 4'b1110;
rstate <= sr_rec_start;
end
end
default : rstate <= sr_idle;
endcase
end // if (enable)
end // always of receiver
always @ (posedge clk or posedge wb_rst_i)
begin
if(wb_rst_i)
rf_push_q <= 0;
else
rf_push_q <= rf_push;
end
assign rf_push_pulse = rf_push & ~rf_push_q;
//
// Break condition detection.
// Works in conjuction with the receiver state machine
reg [9:0] toc_value; // value to be set to timeout counter
always @(lcr)
case (lcr[3:0])
4'b0000 : toc_value = 447; // 7 bits
4'b0100 : toc_value = 479; // 7.5 bits
4'b0001, 4'b1000 : toc_value = 511; // 8 bits
4'b1100 : toc_value = 543; // 8.5 bits
4'b0010, 4'b0101, 4'b1001 : toc_value = 575; // 9 bits
4'b0011, 4'b0110, 4'b1010, 4'b1101 : toc_value = 639; // 10 bits
4'b0111, 4'b1011, 4'b1110 : toc_value = 703; // 11 bits
4'b1111 : toc_value = 767; // 12 bits
endcase // case(lcr[3:0])
wire [7:0] brc_value; // value to be set to break counter
assign brc_value = toc_value[9:2]; // the same as timeout but 1 insead of 4 character times
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
counter_b <= 8'd159;
else
if (srx_pad_i)
counter_b <= brc_value; // character time length - 1
else
if(enable & counter_b != 8'b0) // only work on enable times break not reached.
counter_b <= counter_b - 8'd1; // decrement break counter
end // always of break condition detection
///
/// Timeout condition detection
reg [9:0] counter_t; // counts the timeout condition clocks
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
counter_t <= 10'd639; // 10 bits for the default 8N1
else
if(rf_push_pulse || rf_pop || rf_count == 0) // counter is reset when RX FIFO is empty, accessed or above trigger level
counter_t <= toc_value;
else
if (enable && counter_t != 10'b0) // we don't want to underflow
counter_t <= counter_t - 10'd1;
end
endmodule

View File

@ -1,888 +0,0 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_regs.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// Registers of the uart 16550 core ////
//// ////
//// Known problems (limits): ////
//// Inserts 1 wait state in all WISHBONE transfers ////
//// ////
//// To Do: ////
//// Nothing or verification. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// - Igor Mohor (igorm@opencores.org) ////
//// ////
//// Created: 2001/05/12 ////
//// Last Updated: (See log for the revision history ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.41 2004/05/21 11:44:41 tadejm
// Added synchronizer flops for RX input.
//
// Revision 1.40 2003/06/11 16:37:47 gorban
// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
//
// Revision 1.39 2002/07/29 21:16:18 gorban
// The uart_defines.v file is included again in sources.
//
// Revision 1.38 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
// Revision 1.37 2001/12/27 13:24:09 mohor
// lsr[7] was not showing overrun errors.
//
// Revision 1.36 2001/12/20 13:25:46 mohor
// rx push changed to be only one cycle wide.
//
// Revision 1.35 2001/12/19 08:03:34 mohor
// Warnings cleared.
//
// Revision 1.34 2001/12/19 07:33:54 mohor
// Synplicity was having troubles with the comment.
//
// Revision 1.33 2001/12/17 10:14:43 mohor
// Things related to msr register changed. After THRE IRQ occurs, and one
// character is written to the transmit fifo, the detection of the THRE bit in the
// LSR is delayed for one character time.
//
// Revision 1.32 2001/12/14 13:19:24 mohor
// MSR register fixed.
//
// Revision 1.31 2001/12/14 10:06:58 mohor
// After reset modem status register MSR should be reset.
//
// Revision 1.30 2001/12/13 10:09:13 mohor
// thre irq should be cleared only when being source of interrupt.
//
// Revision 1.29 2001/12/12 09:05:46 mohor
// LSR status bit 0 was not cleared correctly in case of reseting the FCR (rx fifo).
//
// Revision 1.28 2001/12/10 19:52:41 gorban
// Scratch register added
//
// Revision 1.27 2001/12/06 14:51:04 gorban
// Bug in LSR[0] is fixed.
// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
//
// Revision 1.26 2001/12/03 21:44:29 gorban
// Updated specification documentation.
// Added full 32-bit data bus interface, now as default.
// Address is 5-bit wide in 32-bit data bus mode.
// Added wb_sel_i input to the core. It's used in the 32-bit mode.
// Added debug interface with two 32-bit read-only registers in 32-bit mode.
// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
// My small test bench is modified to work with 32-bit mode.
//
// Revision 1.25 2001/11/28 19:36:39 gorban
// Fixed: timeout and break didn't pay attention to current data format when counting time
//
// Revision 1.24 2001/11/26 21:38:54 gorban
// Lots of fixes:
// Break condition wasn't handled correctly at all.
// LSR bits could lose their values.
// LSR value after reset was wrong.
// Timing of THRE interrupt signal corrected.
// LSR bit 0 timing corrected.
//
// Revision 1.23 2001/11/12 21:57:29 gorban
// fixed more typo bugs
//
// Revision 1.22 2001/11/12 15:02:28 mohor
// lsr1r error fixed.
//
// Revision 1.21 2001/11/12 14:57:27 mohor
// ti_int_pnd error fixed.
//
// Revision 1.20 2001/11/12 14:50:27 mohor
// ti_int_d error fixed.
//
// Revision 1.19 2001/11/10 12:43:21 gorban
// Logic Synthesis bugs fixed. Some other minor changes
//
// Revision 1.18 2001/11/08 14:54:23 mohor
// Comments in Slovene language deleted, few small fixes for better work of
// old tools. IRQs need to be fix.
//
// Revision 1.17 2001/11/07 17:51:52 gorban
// Heavily rewritten interrupt and LSR subsystems.
// Many bugs hopefully squashed.
//
// Revision 1.16 2001/11/02 09:55:16 mohor
// no message
//
// Revision 1.15 2001/10/31 15:19:22 gorban
// Fixes to break and timeout conditions
//
// Revision 1.14 2001/10/29 17:00:46 gorban
// fixed parity sending and tx_fifo resets over- and underrun
//
// Revision 1.13 2001/10/20 09:58:40 gorban
// Small synopsis fixes
//
// Revision 1.12 2001/10/19 16:21:40 gorban
// Changes data_out to be synchronous again as it should have been.
//
// Revision 1.11 2001/10/18 20:35:45 gorban
// small fix
//
// Revision 1.10 2001/08/24 21:01:12 mohor
// Things connected to parity changed.
// Clock devider changed.
//
// Revision 1.9 2001/08/23 16:05:05 mohor
// Stop bit bug fixed.
// Parity bug fixed.
// WISHBONE read cycle bug fixed,
// OE indicator (Overrun Error) bug fixed.
// PE indicator (Parity Error) bug fixed.
// Register read bug fixed.
//
// Revision 1.10 2001/06/23 11:21:48 gorban
// DL made 16-bit long. Fixed transmission/reception bugs.
//
// Revision 1.9 2001/05/31 20:08:01 gorban
// FIFO changes and other corrections.
//
// Revision 1.8 2001/05/29 20:05:04 gorban
// Fixed some bugs and synthesis problems.
//
// Revision 1.7 2001/05/27 17:37:49 gorban
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
//
// Revision 1.6 2001/05/21 19:12:02 gorban
// Corrected some Linter messages.
//
// Revision 1.5 2001/05/17 18:34:18 gorban
// First 'stable' release. Should be sythesizable now. Also added new header.
//
// Revision 1.0 2001-05-17 21:27:11+02 jacob
// Initial revision
//
//
`include "uart_defines.v"
`define UART_DL1 7:0
`define UART_DL2 15:8
module uart_regs
#(parameter SIM = 0)
(clk,
wb_rst_i, wb_addr_i, wb_dat_i, wb_dat_o, wb_we_i, wb_re_i,
// additional signals
modem_inputs,
stx_pad_o, srx_pad_i,
rts_pad_o, dtr_pad_o, int_o
`ifdef UART_HAS_BAUDRATE_OUTPUT
, baud_o
`endif
);
input clk;
input wb_rst_i;
input [2:0] wb_addr_i;
input [7:0] wb_dat_i;
output [7:0] wb_dat_o;
input wb_we_i;
input wb_re_i;
output stx_pad_o;
input srx_pad_i;
input [3:0] modem_inputs;
output rts_pad_o;
output dtr_pad_o;
output int_o;
`ifdef UART_HAS_BAUDRATE_OUTPUT
output baud_o;
`endif
wire [3:0] modem_inputs;
reg enable;
`ifdef UART_HAS_BAUDRATE_OUTPUT
assign baud_o = enable; // baud_o is actually the enable signal
`endif
wire stx_pad_o; // received from transmitter module
wire srx_pad_i;
wire srx_pad;
reg [7:0] wb_dat_o;
wire [2:0] wb_addr_i;
wire [7:0] wb_dat_i;
reg [3:0] ier;
reg [3:0] iir;
reg [1:0] fcr; /// bits 7 and 6 of fcr. Other bits are ignored
reg [4:0] mcr;
reg [7:0] lcr;
reg [7:0] msr;
reg [15:0] dl; // 32-bit divisor latch
reg [7:0] scratch; // UART scratch register
reg start_dlc; // activate dlc on writing to UART_DL1
reg lsr_mask_d; // delay for lsr_mask condition
reg msi_reset; // reset MSR 4 lower bits indicator
//reg threi_clear; // THRE interrupt clear flag
reg [15:0] dlc; // 32-bit divisor latch counter
reg int_o;
reg [3:0] trigger_level; // trigger level of the receiver FIFO
reg rx_reset;
reg tx_reset;
wire dlab; // divisor latch access bit
wire cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i; // modem status bits
wire loopback; // loopback bit (MCR bit 4)
wire cts, dsr, ri, dcd; // effective signals
wire cts_c, dsr_c, ri_c, dcd_c; // Complement effective signals (considering loopback)
wire rts_pad_o, dtr_pad_o; // modem control outputs
// LSR bits wires and regs
wire [7:0] lsr;
wire lsr0, lsr1, lsr2, lsr3, lsr4, lsr5, lsr6, lsr7;
reg lsr0r, lsr1r, lsr2r, lsr3r, lsr4r, lsr5r, lsr6r, lsr7r;
wire lsr_mask; // lsr_mask
//
// ASSINGS
//
assign lsr[7:0] = { lsr7r, lsr6r, lsr5r, lsr4r, lsr3r, lsr2r, lsr1r, lsr0r };
assign {cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i} = modem_inputs;
assign {cts, dsr, ri, dcd} = ~{cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
assign {cts_c, dsr_c, ri_c, dcd_c} = loopback ? {mcr[`UART_MC_RTS],mcr[`UART_MC_DTR],mcr[`UART_MC_OUT1],mcr[`UART_MC_OUT2]}
: {cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
assign dlab = lcr[`UART_LC_DL];
assign loopback = mcr[4];
// assign modem outputs
assign rts_pad_o = mcr[`UART_MC_RTS];
assign dtr_pad_o = mcr[`UART_MC_DTR];
// Interrupt signals
wire rls_int; // receiver line status interrupt
wire rda_int; // receiver data available interrupt
wire ti_int; // timeout indicator interrupt
wire thre_int; // transmitter holding register empty interrupt
wire ms_int; // modem status interrupt
// FIFO signals
reg tf_push;
reg rf_pop;
wire [`UART_FIFO_REC_WIDTH-1:0] rf_data_out;
wire rf_error_bit; // an error (parity or framing) is inside the fifo
wire rf_overrun;
wire rf_push_pulse;
wire [`UART_FIFO_COUNTER_W-1:0] rf_count;
wire [`UART_FIFO_COUNTER_W-1:0] tf_count;
wire [2:0] tstate;
wire [3:0] rstate;
wire [9:0] counter_t;
wire thre_set_en; // THRE status is delayed one character time when a character is written to fifo.
reg [7:0] block_cnt; // While counter counts, THRE status is blocked (delayed one character cycle)
reg [7:0] block_value; // One character length minus stop bit
// Transmitter Instance
wire serial_out;
uart_transmitter #(.SIM (SIM)) transmitter(clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, serial_out, tstate, tf_count, tx_reset, lsr_mask);
// Synchronizing and sampling serial RX input
uart_sync_flops i_uart_sync_flops
(
.rst_i (wb_rst_i),
.clk_i (clk),
.stage1_rst_i (1'b0),
.stage1_clk_en_i (1'b1),
.async_dat_i (srx_pad_i),
.sync_dat_o (srx_pad)
);
defparam i_uart_sync_flops.width = 1;
defparam i_uart_sync_flops.init_value = 1'b1;
// handle loopback
wire serial_in = loopback ? serial_out : srx_pad;
assign stx_pad_o = loopback ? 1'b1 : serial_out;
// Receiver Instance
uart_receiver receiver(clk, wb_rst_i, lcr, rf_pop, serial_in, enable,
counter_t, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, lsr_mask, rstate, rf_push_pulse);
// Asynchronous reading here because the outputs are sampled in uart_wb.v file
always @(dl or dlab or ier or iir or scratch
or lcr or lsr or msr or rf_data_out or wb_addr_i or wb_re_i) // asynchrounous reading
begin
case (wb_addr_i)
`UART_REG_RB : wb_dat_o = dlab ? dl[`UART_DL1] : rf_data_out[10:3];
`UART_REG_IE : wb_dat_o = dlab ? dl[`UART_DL2] : {4'd0,ier};
`UART_REG_II : wb_dat_o = {4'b1100,iir};
`UART_REG_LC : wb_dat_o = lcr;
`UART_REG_LS : wb_dat_o = lsr;
`UART_REG_MS : wb_dat_o = msr;
`UART_REG_SR : wb_dat_o = scratch;
default: wb_dat_o = 8'b0; // ??
endcase // case(wb_addr_i)
end // always @ (dl or dlab or ier or iir or scratch...
// rf_pop signal handling
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
rf_pop <= 0;
else
if (rf_pop) // restore the signal to 0 after one clock cycle
rf_pop <= 0;
else
if (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab)
rf_pop <= 1; // advance read pointer
end
wire lsr_mask_condition;
wire iir_read;
wire msr_read;
wire fifo_read;
wire fifo_write;
assign lsr_mask_condition = (wb_re_i && wb_addr_i == `UART_REG_LS && !dlab);
assign iir_read = (wb_re_i && wb_addr_i == `UART_REG_II && !dlab);
assign msr_read = (wb_re_i && wb_addr_i == `UART_REG_MS && !dlab);
assign fifo_read = (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab);
assign fifo_write = (wb_we_i && wb_addr_i == `UART_REG_TR && !dlab);
// lsr_mask_d delayed signal handling
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
lsr_mask_d <= 0;
else // reset bits in the Line Status Register
lsr_mask_d <= lsr_mask_condition;
end
// lsr_mask is rise detected
assign lsr_mask = lsr_mask_condition && ~lsr_mask_d;
// msi_reset signal handling
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
msi_reset <= 1;
else
if (msi_reset)
msi_reset <= 0;
else
if (msr_read)
msi_reset <= 1; // reset bits in Modem Status Register
end
//
// WRITES AND RESETS //
//
// Line Control Register
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
lcr <= 8'b00000011; // 8n1 setting
else
if (wb_we_i && wb_addr_i==`UART_REG_LC)
lcr <= wb_dat_i;
// Interrupt Enable Register or UART_DL2
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
begin
ier <= 4'b0000; // no interrupts after reset
`ifdef PRESCALER_PRESET_HARD
dl[`UART_DL2] <= `PRESCALER_HIGH_PRESET;
`else
dl[`UART_DL2] <= 8'b0;
`endif
end
else
if (wb_we_i && wb_addr_i==`UART_REG_IE)
if (dlab)
begin
dl[`UART_DL2] <=
`ifdef PRESCALER_PRESET_HARD
dl[`UART_DL2];
`else
wb_dat_i;
`endif
end
else
ier <= wb_dat_i[3:0]; // ier uses only 4 lsb
// FIFO Control Register and rx_reset, tx_reset signals
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) begin
fcr <= 2'b11;
rx_reset <= 0;
tx_reset <= 0;
end else
if (wb_we_i && wb_addr_i==`UART_REG_FC) begin
fcr <= wb_dat_i[7:6];
rx_reset <= wb_dat_i[1];
tx_reset <= wb_dat_i[2];
end else begin
rx_reset <= 0;
tx_reset <= 0;
end
// Modem Control Register
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
mcr <= 5'b0;
else
if (wb_we_i && wb_addr_i==`UART_REG_MC)
mcr <= wb_dat_i[4:0];
// Scratch register
// Line Control Register
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
scratch <= 0; // 8n1 setting
else
if (wb_we_i && wb_addr_i==`UART_REG_SR)
scratch <= wb_dat_i;
// TX_FIFO or UART_DL1
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
begin
`ifdef PRESCALER_PRESET_HARD
dl[`UART_DL1] <= `PRESCALER_LOW_PRESET;
`else
dl[`UART_DL1] <= 8'b0;
`endif
tf_push <= 1'b0;
start_dlc <= 1'b0;
end
else
if (wb_we_i && wb_addr_i==`UART_REG_TR)
if (dlab)
begin
`ifdef PRESCALER_PRESET_HARD
dl[`UART_DL1] <= dl[`UART_DL1];
`else
dl[`UART_DL1] <= wb_dat_i;
`endif
start_dlc <= 1'b1; // enable DL counter
tf_push <= 1'b0;
end
else
begin
tf_push <= 1'b1;
start_dlc <= 1'b0;
end // else: !if(dlab)
else
begin
start_dlc <= 1'b0;
tf_push <= 1'b0;
end // else: !if(dlab)
// Receiver FIFO trigger level selection logic (asynchronous mux)
always @(fcr)
case (fcr[`UART_FC_TL])
2'b00 : trigger_level = 1;
2'b01 : trigger_level = 4;
2'b10 : trigger_level = 8;
2'b11 : trigger_level = 14;
endcase // case(fcr[`UART_FC_TL])
//
// STATUS REGISTERS //
//
// Modem Status Register
reg [3:0] delayed_modem_signals;
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
begin
msr <= 0;
delayed_modem_signals[3:0] <= 0;
end
else begin
msr[`UART_MS_DDCD:`UART_MS_DCTS] <= msi_reset ? 4'b0 :
msr[`UART_MS_DDCD:`UART_MS_DCTS] | ({dcd, ri, dsr, cts} ^ delayed_modem_signals[3:0]);
msr[`UART_MS_CDCD:`UART_MS_CCTS] <= {dcd_c, ri_c, dsr_c, cts_c};
delayed_modem_signals[3:0] <= {dcd, ri, dsr, cts};
end
end
// Line Status Register
// activation conditions
assign lsr0 = (rf_count==0 && rf_push_pulse); // data in receiver fifo available set condition
assign lsr1 = rf_overrun; // Receiver overrun error
assign lsr2 = rf_data_out[1]; // parity error bit
assign lsr3 = rf_data_out[0]; // framing error bit
assign lsr4 = rf_data_out[2]; // break error in the character
assign lsr5 = (tf_count==5'b0 && thre_set_en); // transmitter fifo is empty
assign lsr6 = (tf_count==5'b0 && thre_set_en && (tstate == /*`S_IDLE */ 0)); // transmitter empty
assign lsr7 = rf_error_bit | rf_overrun;
// lsr bit0 (receiver data available)
reg lsr0_d;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr0_d <= 0;
else lsr0_d <= lsr0;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr0r <= 0;
else lsr0r <= (rf_count==1 && rf_pop && !rf_push_pulse || rx_reset) ? 1'b0 : // deassert condition
lsr0r || (lsr0 && ~lsr0_d); // set on rise of lsr0 and keep asserted until deasserted
// lsr bit 1 (receiver overrun)
reg lsr1_d; // delayed
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr1_d <= 0;
else lsr1_d <= lsr1;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr1r <= 0;
else lsr1r <= lsr_mask ? 1'b0 : lsr1r || (lsr1 && ~lsr1_d); // set on rise
// lsr bit 2 (parity error)
reg lsr2_d; // delayed
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr2_d <= 0;
else lsr2_d <= lsr2;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr2r <= 0;
else lsr2r <= lsr_mask ? 1'b0 : lsr2r || (lsr2 && ~lsr2_d); // set on rise
// lsr bit 3 (framing error)
reg lsr3_d; // delayed
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr3_d <= 0;
else lsr3_d <= lsr3;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr3r <= 0;
else lsr3r <= lsr_mask ? 1'b0 : lsr3r || (lsr3 && ~lsr3_d); // set on rise
// lsr bit 4 (break indicator)
reg lsr4_d; // delayed
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr4_d <= 0;
else lsr4_d <= lsr4;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr4r <= 0;
else lsr4r <= lsr_mask ? 1'b0 : lsr4r || (lsr4 && ~lsr4_d);
// lsr bit 5 (transmitter fifo is empty)
reg lsr5_d;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr5_d <= 1;
else lsr5_d <= lsr5;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr5r <= 1;
else lsr5r <= (fifo_write) ? 1'b0 : lsr5r || (lsr5 && ~lsr5_d);
// lsr bit 6 (transmitter empty indicator)
reg lsr6_d;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr6_d <= 1;
else lsr6_d <= lsr6;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr6r <= 1;
else lsr6r <= (fifo_write) ? 1'b0 : lsr6r || (lsr6 && ~lsr6_d);
// lsr bit 7 (error in fifo)
reg lsr7_d;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr7_d <= 0;
else lsr7_d <= lsr7;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) lsr7r <= 0;
else lsr7r <= lsr_mask ? 1'b0 : lsr7r || (lsr7 && ~lsr7_d);
// Frequency divider
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
dlc <= 0;
else
if (start_dlc | ~ (|dlc))
dlc <= dl - 16'd1; // preset counter
else
dlc <= dlc - 16'd1; // decrement counter
end
// Enable signal generation logic
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
enable <= 1'b0;
else
if (|dl & ~(|dlc)) // dl>0 & dlc==0
enable <= 1'b1;
else
enable <= 1'b0;
end
// Delaying THRE status for one character cycle after a character is written to an empty fifo.
always @(lcr)
case (lcr[3:0])
4'b0000 : block_value = 95; // 6 bits
4'b0100 : block_value = 103; // 6.5 bits
4'b0001, 4'b1000 : block_value = 111; // 7 bits
4'b1100 : block_value = 119; // 7.5 bits
4'b0010, 4'b0101, 4'b1001 : block_value = 127; // 8 bits
4'b0011, 4'b0110, 4'b1010, 4'b1101 : block_value = 143; // 9 bits
4'b0111, 4'b1011, 4'b1110 : block_value = 159; // 10 bits
4'b1111 : block_value = 175; // 11 bits
endcase // case(lcr[3:0])
// Counting time of one character minus stop bit
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
block_cnt <= 8'd0;
else
if(lsr5r & fifo_write) // THRE bit set & write to fifo occured
block_cnt <= SIM ? 8'd1 : block_value;
else
if (enable & block_cnt != 8'b0) // only work on enable times
block_cnt <= block_cnt - 8'd1; // decrement break counter
end // always of break condition detection
// Generating THRE status enable signal
assign thre_set_en = ~(|block_cnt);
//
// INTERRUPT LOGIC
//
assign rls_int = ier[`UART_IE_RLS] && (lsr[`UART_LS_OE] || lsr[`UART_LS_PE] || lsr[`UART_LS_FE] || lsr[`UART_LS_BI]);
assign rda_int = ier[`UART_IE_RDA] && (rf_count >= {1'b0,trigger_level});
assign thre_int = ier[`UART_IE_THRE] && lsr[`UART_LS_TFE];
assign ms_int = ier[`UART_IE_MS] && (| msr[3:0]);
assign ti_int = ier[`UART_IE_RDA] && (counter_t == 10'b0) && (|rf_count);
reg rls_int_d;
reg thre_int_d;
reg ms_int_d;
reg ti_int_d;
reg rda_int_d;
// delay lines
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) rls_int_d <= 0;
else rls_int_d <= rls_int;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) rda_int_d <= 0;
else rda_int_d <= rda_int;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) thre_int_d <= 0;
else thre_int_d <= thre_int;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) ms_int_d <= 0;
else ms_int_d <= ms_int;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) ti_int_d <= 0;
else ti_int_d <= ti_int;
// rise detection signals
wire rls_int_rise;
wire thre_int_rise;
wire ms_int_rise;
wire ti_int_rise;
wire rda_int_rise;
assign rda_int_rise = rda_int & ~rda_int_d;
assign rls_int_rise = rls_int & ~rls_int_d;
assign thre_int_rise = thre_int & ~thre_int_d;
assign ms_int_rise = ms_int & ~ms_int_d;
assign ti_int_rise = ti_int & ~ti_int_d;
// interrupt pending flags
reg rls_int_pnd;
reg rda_int_pnd;
reg thre_int_pnd;
reg ms_int_pnd;
reg ti_int_pnd;
// interrupt pending flags assignments
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) rls_int_pnd <= 0;
else
rls_int_pnd <= lsr_mask ? 1'b0 : // reset condition
rls_int_rise ? 1'b1 : // latch condition
rls_int_pnd && ier[`UART_IE_RLS]; // default operation: remove if masked
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) rda_int_pnd <= 0;
else
rda_int_pnd <= ((rf_count == {1'b0,trigger_level}) && fifo_read) ? 1'b0 : // reset condition
rda_int_rise ? 1'b1 : // latch condition
rda_int_pnd && ier[`UART_IE_RDA]; // default operation: remove if masked
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) thre_int_pnd <= 0;
else
thre_int_pnd <= fifo_write || (iir_read & ~iir[`UART_II_IP] & iir[`UART_II_II] == `UART_II_THRE)? 1'b0 :
thre_int_rise ? 1'b1 :
thre_int_pnd && ier[`UART_IE_THRE];
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) ms_int_pnd <= 0;
else
ms_int_pnd <= msr_read ? 1'b0 :
ms_int_rise ? 1'b1 :
ms_int_pnd && ier[`UART_IE_MS];
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) ti_int_pnd <= 0;
else
ti_int_pnd <= fifo_read ? 1'b0 :
ti_int_rise ? 1'b1 :
ti_int_pnd && ier[`UART_IE_RDA];
// end of pending flags
// INT_O logic
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
int_o <= 1'b0;
else
int_o <=
rls_int_pnd ? ~lsr_mask :
rda_int_pnd ? 1'b1 :
ti_int_pnd ? ~fifo_read :
thre_int_pnd ? !(fifo_write & iir_read) :
ms_int_pnd ? ~msr_read :
1'd0; // if no interrupt are pending
end
// Interrupt Identification register
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
iir <= 1;
else
if (rls_int_pnd) // interrupt is pending
begin
iir[`UART_II_II] <= `UART_II_RLS; // set identification register to correct value
iir[`UART_II_IP] <= 1'b0; // and clear the IIR bit 0 (interrupt pending)
end else // the sequence of conditions determines priority of interrupt identification
if (rda_int)
begin
iir[`UART_II_II] <= `UART_II_RDA;
iir[`UART_II_IP] <= 1'b0;
end
else if (ti_int_pnd)
begin
iir[`UART_II_II] <= `UART_II_TI;
iir[`UART_II_IP] <= 1'b0;
end
else if (thre_int_pnd)
begin
iir[`UART_II_II] <= `UART_II_THRE;
iir[`UART_II_IP] <= 1'b0;
end
else if (ms_int_pnd)
begin
iir[`UART_II_II] <= `UART_II_MS;
iir[`UART_II_IP] <= 1'b0;
end else // no interrupt is pending
begin
iir[`UART_II_II] <= 0;
iir[`UART_II_IP] <= 1'b1;
end
end
endmodule

View File

@ -1,316 +0,0 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_rfifo.v (Modified from uart_fifo.v) ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// UART core receiver FIFO ////
//// ////
//// To Do: ////
//// Nothing. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// - Igor Mohor (igorm@opencores.org) ////
//// ////
//// Created: 2001/05/12 ////
//// Last Updated: 2002/07/22 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.3 2003/06/11 16:37:47 gorban
// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
//
// Revision 1.2 2002/07/29 21:16:18 gorban
// The uart_defines.v file is included again in sources.
//
// Revision 1.1 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
// Revision 1.16 2001/12/20 13:25:46 mohor
// rx push changed to be only one cycle wide.
//
// Revision 1.15 2001/12/18 09:01:07 mohor
// Bug that was entered in the last update fixed (rx state machine).
//
// Revision 1.14 2001/12/17 14:46:48 mohor
// overrun signal was moved to separate block because many sequential lsr
// reads were preventing data from being written to rx fifo.
// underrun signal was not used and was removed from the project.
//
// Revision 1.13 2001/11/26 21:38:54 gorban
// Lots of fixes:
// Break condition wasn't handled correctly at all.
// LSR bits could lose their values.
// LSR value after reset was wrong.
// Timing of THRE interrupt signal corrected.
// LSR bit 0 timing corrected.
//
// Revision 1.12 2001/11/08 14:54:23 mohor
// Comments in Slovene language deleted, few small fixes for better work of
// old tools. IRQs need to be fix.
//
// Revision 1.11 2001/11/07 17:51:52 gorban
// Heavily rewritten interrupt and LSR subsystems.
// Many bugs hopefully squashed.
//
// Revision 1.10 2001/10/20 09:58:40 gorban
// Small synopsis fixes
//
// Revision 1.9 2001/08/24 21:01:12 mohor
// Things connected to parity changed.
// Clock devider changed.
//
// Revision 1.8 2001/08/24 08:48:10 mohor
// FIFO was not cleared after the data was read bug fixed.
//
// Revision 1.7 2001/08/23 16:05:05 mohor
// Stop bit bug fixed.
// Parity bug fixed.
// WISHBONE read cycle bug fixed,
// OE indicator (Overrun Error) bug fixed.
// PE indicator (Parity Error) bug fixed.
// Register read bug fixed.
//
// Revision 1.3 2001/05/31 20:08:01 gorban
// FIFO changes and other corrections.
//
// Revision 1.3 2001/05/27 17:37:48 gorban
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
//
// Revision 1.2 2001/05/17 18:34:18 gorban
// First 'stable' release. Should be sythesizable now. Also added new header.
//
// Revision 1.0 2001-05-17 21:27:12+02 jacob
// Initial revision
//
//
`include "uart_defines.v"
module uart_rfifo (clk,
wb_rst_i, data_in, data_out,
// Control signals
push, // push strobe, active high
pop, // pop strobe, active high
// status signals
overrun,
count,
error_bit,
fifo_reset,
reset_status
);
// FIFO parameters
parameter fifo_width = `UART_FIFO_WIDTH;
parameter fifo_depth = `UART_FIFO_DEPTH;
parameter fifo_pointer_w = `UART_FIFO_POINTER_W;
parameter fifo_counter_w = `UART_FIFO_COUNTER_W;
input clk;
input wb_rst_i;
input push;
input pop;
input [fifo_width-1:0] data_in;
input fifo_reset;
input reset_status;
output [fifo_width-1:0] data_out;
output overrun;
output [fifo_counter_w-1:0] count;
output error_bit;
wire [fifo_width-1:0] data_out;
wire [7:0] data8_out;
// flags FIFO
reg [2:0] fifo[fifo_depth-1:0];
// FIFO pointers
reg [fifo_pointer_w-1:0] top;
reg [fifo_pointer_w-1:0] bottom;
reg [fifo_counter_w-1:0] count;
reg overrun;
wire [fifo_pointer_w-1:0] top_plus_1 = top + 4'h1;
raminfr #(fifo_pointer_w,8,fifo_depth) rfifo
(.clk(clk),
.we(push),
.a(top),
.dpra(bottom),
.di(data_in[fifo_width-1:fifo_width-8]),
.dpo(data8_out)
);
always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
begin
if (wb_rst_i)
begin
top <= 0;
bottom <= 0;
count <= 0;
fifo[0] <= 0;
fifo[1] <= 0;
fifo[2] <= 0;
fifo[3] <= 0;
fifo[4] <= 0;
fifo[5] <= 0;
fifo[6] <= 0;
fifo[7] <= 0;
fifo[8] <= 0;
fifo[9] <= 0;
fifo[10] <= 0;
fifo[11] <= 0;
fifo[12] <= 0;
fifo[13] <= 0;
fifo[14] <= 0;
fifo[15] <= 0;
end
else
if (fifo_reset) begin
top <= 0;
bottom <= 0;
count <= 0;
fifo[0] <= 0;
fifo[1] <= 0;
fifo[2] <= 0;
fifo[3] <= 0;
fifo[4] <= 0;
fifo[5] <= 0;
fifo[6] <= 0;
fifo[7] <= 0;
fifo[8] <= 0;
fifo[9] <= 0;
fifo[10] <= 0;
fifo[11] <= 0;
fifo[12] <= 0;
fifo[13] <= 0;
fifo[14] <= 0;
fifo[15] <= 0;
end
else
begin
case ({push, pop})
2'b10 : if (count<fifo_depth) // overrun condition
begin
top <= top_plus_1;
fifo[top] <= data_in[2:0];
count <= count + 5'd1;
end
2'b01 : if(count>0)
begin
fifo[bottom] <= 0;
bottom <= bottom + 4'd1;
count <= count - 5'd1;
end
2'b11 : begin
bottom <= bottom + 4'd1;
top <= top_plus_1;
fifo[top] <= data_in[2:0];
end
default: ;
endcase
end
end // always
always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
begin
if (wb_rst_i)
overrun <= 1'b0;
else
if(fifo_reset | reset_status)
overrun <= 1'b0;
else
if(push & ~pop & (count==fifo_depth))
overrun <= 1'b1;
end // always
// please note though that data_out is only valid one clock after pop signal
assign data_out = {data8_out,fifo[bottom]};
// Additional logic for detection of error conditions (parity and framing) inside the FIFO
// for the Line Status Register bit 7
wire [2:0] word0 = fifo[0];
wire [2:0] word1 = fifo[1];
wire [2:0] word2 = fifo[2];
wire [2:0] word3 = fifo[3];
wire [2:0] word4 = fifo[4];
wire [2:0] word5 = fifo[5];
wire [2:0] word6 = fifo[6];
wire [2:0] word7 = fifo[7];
wire [2:0] word8 = fifo[8];
wire [2:0] word9 = fifo[9];
wire [2:0] word10 = fifo[10];
wire [2:0] word11 = fifo[11];
wire [2:0] word12 = fifo[12];
wire [2:0] word13 = fifo[13];
wire [2:0] word14 = fifo[14];
wire [2:0] word15 = fifo[15];
// a 1 is returned if any of the error bits in the fifo is 1
assign error_bit = |(word0[2:0] | word1[2:0] | word2[2:0] | word3[2:0] |
word4[2:0] | word5[2:0] | word6[2:0] | word7[2:0] |
word8[2:0] | word9[2:0] | word10[2:0] | word11[2:0] |
word12[2:0] | word13[2:0] | word14[2:0] | word15[2:0] );
endmodule

View File

@ -1,117 +0,0 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_sync_flops.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// UART core receiver logic ////
//// ////
//// Known problems (limits): ////
//// None known ////
//// ////
//// To Do: ////
//// Thourough testing. ////
//// ////
//// Author(s): ////
//// - Andrej Erzen (andreje@flextronics.si) ////
//// - Tadej Markovic (tadejm@flextronics.si) ////
//// ////
//// Created: 2004/05/20 ////
//// Last Updated: 2004/05/20 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
//
module uart_sync_flops
(
// internal signals
rst_i,
clk_i,
stage1_rst_i,
stage1_clk_en_i,
async_dat_i,
sync_dat_o
);
parameter width = 1;
parameter init_value = 1'b0;
input rst_i; // reset input
input clk_i; // clock input
input stage1_rst_i; // synchronous reset for stage 1 FF
input stage1_clk_en_i; // synchronous clock enable for stage 1 FF
input [width-1:0] async_dat_i; // asynchronous data input
output [width-1:0] sync_dat_o; // synchronous data output
//
// Interal signal declarations
//
reg [width-1:0] sync_dat_o;
reg [width-1:0] flop_0;
// first stage
always @ (posedge clk_i or posedge rst_i)
begin
if (rst_i)
flop_0 <= {width{init_value}};
else
flop_0 <= async_dat_i;
end
// second stage
always @ (posedge clk_i or posedge rst_i)
begin
if (rst_i)
sync_dat_o <= {width{init_value}};
else if (stage1_rst_i)
sync_dat_o <= {width{init_value}};
else if (stage1_clk_en_i)
sync_dat_o <= flop_0;
end
endmodule

View File

@ -1,239 +0,0 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_tfifo.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// UART core transmitter FIFO ////
//// ////
//// To Do: ////
//// Nothing. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// - Igor Mohor (igorm@opencores.org) ////
//// ////
//// Created: 2001/05/12 ////
//// Last Updated: 2002/07/22 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
// Revision 1.16 2001/12/20 13:25:46 mohor
// rx push changed to be only one cycle wide.
//
// Revision 1.15 2001/12/18 09:01:07 mohor
// Bug that was entered in the last update fixed (rx state machine).
//
// Revision 1.14 2001/12/17 14:46:48 mohor
// overrun signal was moved to separate block because many sequential lsr
// reads were preventing data from being written to rx fifo.
// underrun signal was not used and was removed from the project.
//
// Revision 1.13 2001/11/26 21:38:54 gorban
// Lots of fixes:
// Break condition wasn't handled correctly at all.
// LSR bits could lose their values.
// LSR value after reset was wrong.
// Timing of THRE interrupt signal corrected.
// LSR bit 0 timing corrected.
//
// Revision 1.12 2001/11/08 14:54:23 mohor
// Comments in Slovene language deleted, few small fixes for better work of
// old tools. IRQs need to be fix.
//
// Revision 1.11 2001/11/07 17:51:52 gorban
// Heavily rewritten interrupt and LSR subsystems.
// Many bugs hopefully squashed.
//
// Revision 1.10 2001/10/20 09:58:40 gorban
// Small synopsis fixes
//
// Revision 1.9 2001/08/24 21:01:12 mohor
// Things connected to parity changed.
// Clock devider changed.
//
// Revision 1.8 2001/08/24 08:48:10 mohor
// FIFO was not cleared after the data was read bug fixed.
//
// Revision 1.7 2001/08/23 16:05:05 mohor
// Stop bit bug fixed.
// Parity bug fixed.
// WISHBONE read cycle bug fixed,
// OE indicator (Overrun Error) bug fixed.
// PE indicator (Parity Error) bug fixed.
// Register read bug fixed.
//
// Revision 1.3 2001/05/31 20:08:01 gorban
// FIFO changes and other corrections.
//
// Revision 1.3 2001/05/27 17:37:48 gorban
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
//
// Revision 1.2 2001/05/17 18:34:18 gorban
// First 'stable' release. Should be sythesizable now. Also added new header.
//
// Revision 1.0 2001-05-17 21:27:12+02 jacob
// Initial revision
//
//
`include "uart_defines.v"
module uart_tfifo (clk,
wb_rst_i, data_in, data_out,
// Control signals
push, // push strobe, active high
pop, // pop strobe, active high
// status signals
overrun,
count,
fifo_reset,
reset_status
);
// FIFO parameters
parameter fifo_width = `UART_FIFO_WIDTH;
parameter fifo_depth = `UART_FIFO_DEPTH;
parameter fifo_pointer_w = `UART_FIFO_POINTER_W;
parameter fifo_counter_w = `UART_FIFO_COUNTER_W;
input clk;
input wb_rst_i;
input push;
input pop;
input [fifo_width-1:0] data_in;
input fifo_reset;
input reset_status;
output [fifo_width-1:0] data_out;
output overrun;
output [fifo_counter_w-1:0] count;
wire [fifo_width-1:0] data_out;
// FIFO pointers
reg [fifo_pointer_w-1:0] top;
reg [fifo_pointer_w-1:0] bottom;
reg [fifo_counter_w-1:0] count;
reg overrun;
wire [fifo_pointer_w-1:0] top_plus_1 = top + 4'd1;
raminfr #(fifo_pointer_w,fifo_width,fifo_depth) tfifo
(.clk(clk),
.we(push),
.a(top),
.dpra(bottom),
.di(data_in),
.dpo(data_out)
);
always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
begin
if (wb_rst_i)
begin
top <= 0;
bottom <= 0;
count <= 0;
end
else
if (fifo_reset) begin
top <= 0;
bottom <= 0;
count <= 0;
end
else
begin
case ({push, pop})
2'b10 : if (count<fifo_depth) // overrun condition
begin
top <= top_plus_1;
count <= count + 5'd1;
end
2'b01 : if(count>0)
begin
bottom <= bottom + 4'd1;
count <= count - 5'd1;
end
2'b11 : begin
bottom <= bottom + 4'd1;
top <= top_plus_1;
end
default: ;
endcase
end
end // always
always @(posedge clk or posedge wb_rst_i) // synchronous FIFO
begin
if (wb_rst_i)
overrun <= 1'b0;
else
if(fifo_reset | reset_status)
overrun <= 1'b0;
else
if(push & (count==fifo_depth))
overrun <= 1'b1;
end // always
endmodule

View File

@ -1,261 +0,0 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_top.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// UART core top level. ////
//// ////
//// Known problems (limits): ////
//// Note that transmitter and receiver instances are inside ////
//// the uart_regs.v file. ////
//// ////
//// To Do: ////
//// Nothing so far. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// - Igor Mohor (igorm@opencores.org) ////
//// ////
//// Created: 2001/05/12 ////
//// Last Updated: 2001/05/17 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.18 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
// Revision 1.17 2001/12/19 08:40:03 mohor
// Warnings fixed (unused signals removed).
//
// Revision 1.16 2001/12/06 14:51:04 gorban
// Bug in LSR[0] is fixed.
// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
//
// Revision 1.15 2001/12/03 21:44:29 gorban
// Updated specification documentation.
// Added full 32-bit data bus interface, now as default.
// Address is 5-bit wide in 32-bit data bus mode.
// Added wb_sel_i input to the core. It's used in the 32-bit mode.
// Added debug interface with two 32-bit read-only registers in 32-bit mode.
// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
// My small test bench is modified to work with 32-bit mode.
//
// Revision 1.14 2001/11/07 17:51:52 gorban
// Heavily rewritten interrupt and LSR subsystems.
// Many bugs hopefully squashed.
//
// Revision 1.13 2001/10/20 09:58:40 gorban
// Small synopsis fixes
//
// Revision 1.12 2001/08/25 15:46:19 gorban
// Modified port names again
//
// Revision 1.11 2001/08/24 21:01:12 mohor
// Things connected to parity changed.
// Clock devider changed.
//
// Revision 1.10 2001/08/23 16:05:05 mohor
// Stop bit bug fixed.
// Parity bug fixed.
// WISHBONE read cycle bug fixed,
// OE indicator (Overrun Error) bug fixed.
// PE indicator (Parity Error) bug fixed.
// Register read bug fixed.
//
// Revision 1.4 2001/05/31 20:08:01 gorban
// FIFO changes and other corrections.
//
// Revision 1.3 2001/05/21 19:12:02 gorban
// Corrected some Linter messages.
//
// Revision 1.2 2001/05/17 18:34:18 gorban
// First 'stable' release. Should be sythesizable now. Also added new header.
//
// Revision 1.0 2001-05-17 21:27:12+02 jacob
// Initial revision
//
//
`include "uart_defines.v"
module uart_top (
wb_clk_i,
// Wishbone signals
wb_rst_i, wb_adr_i, wb_dat_i, wb_dat_o, wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_sel_i,
int_o, // interrupt request
// UART signals
// serial input/output
stx_pad_o, srx_pad_i,
// modem signals
rts_pad_o, cts_pad_i, dtr_pad_o, dsr_pad_i, ri_pad_i, dcd_pad_i
`ifdef UART_HAS_BAUDRATE_OUTPUT
, baud_o
`endif
);
parameter SIM = 0;
parameter debug = 0;
input wb_clk_i;
// WISHBONE interface
input wb_rst_i;
input [2:0] wb_adr_i;
input [7:0] wb_dat_i;
output [7:0] wb_dat_o;
input wb_we_i;
input wb_stb_i;
input wb_cyc_i;
input [3:0] wb_sel_i;
output wb_ack_o;
output int_o;
// UART signals
input srx_pad_i;
output stx_pad_o;
output rts_pad_o;
input cts_pad_i;
output dtr_pad_o;
input dsr_pad_i;
input ri_pad_i;
input dcd_pad_i;
// optional baudrate output
`ifdef UART_HAS_BAUDRATE_OUTPUT
output baud_o;
`endif
wire stx_pad_o;
wire rts_pad_o;
wire dtr_pad_o;
wire [2:0] wb_adr_i;
wire [7:0] wb_dat_i;
wire [7:0] wb_dat_o;
wire [7:0] wb_dat8_i; // 8-bit internal data input
wire [7:0] wb_dat8_o; // 8-bit internal data output
wire [31:0] wb_dat32_o; // debug interface 32-bit output
wire [3:0] wb_sel_i; // WISHBONE select signal
wire [2:0] wb_adr_int;
wire we_o; // Write enable for registers
wire re_o; // Read enable for registers
//
// MODULE INSTANCES
//
//// WISHBONE interface module
uart_wb wb_interface(
.clk( wb_clk_i ),
.wb_rst_i( wb_rst_i ),
.wb_dat_i(wb_dat_i),
.wb_dat_o(wb_dat_o),
.wb_dat8_i(wb_dat8_i),
.wb_dat8_o(wb_dat8_o),
.wb_dat32_o(32'b0),
.wb_sel_i(4'b0),
.wb_we_i( wb_we_i ),
.wb_stb_i( wb_stb_i ),
.wb_cyc_i( wb_cyc_i ),
.wb_ack_o( wb_ack_o ),
.wb_adr_i(wb_adr_i),
.wb_adr_int(wb_adr_int),
.we_o( we_o ),
.re_o(re_o)
);
// Registers
uart_regs #(.SIM (SIM)) regs(
.clk( wb_clk_i ),
.wb_rst_i( wb_rst_i ),
.wb_addr_i( wb_adr_int ),
.wb_dat_i( wb_dat8_i ),
.wb_dat_o( wb_dat8_o ),
.wb_we_i( we_o ),
.wb_re_i(re_o),
.modem_inputs( {cts_pad_i, dsr_pad_i,
ri_pad_i, dcd_pad_i} ),
.stx_pad_o( stx_pad_o ),
.srx_pad_i( srx_pad_i ),
.rts_pad_o( rts_pad_o ),
.dtr_pad_o( dtr_pad_o ),
.int_o( int_o )
`ifdef UART_HAS_BAUDRATE_OUTPUT
, .baud_o(baud_o)
`endif
);
initial
begin
if(debug) begin
`ifdef UART_HAS_BAUDRATE_OUTPUT
$display("(%m) UART INFO: Has baudrate output\n");
`else
$display("(%m) UART INFO: Doesn't have baudrate output\n");
`endif
end
end
endmodule

View File

@ -1,354 +0,0 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_transmitter.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// UART core transmitter logic ////
//// ////
//// Known problems (limits): ////
//// None known ////
//// ////
//// To Do: ////
//// Thourough testing. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// - Igor Mohor (igorm@opencores.org) ////
//// ////
//// Created: 2001/05/12 ////
//// Last Updated: 2001/05/17 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.18 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
// Revision 1.16 2002/01/08 11:29:40 mohor
// tf_pop was too wide. Now it is only 1 clk cycle width.
//
// Revision 1.15 2001/12/17 14:46:48 mohor
// overrun signal was moved to separate block because many sequential lsr
// reads were preventing data from being written to rx fifo.
// underrun signal was not used and was removed from the project.
//
// Revision 1.14 2001/12/03 21:44:29 gorban
// Updated specification documentation.
// Added full 32-bit data bus interface, now as default.
// Address is 5-bit wide in 32-bit data bus mode.
// Added wb_sel_i input to the core. It's used in the 32-bit mode.
// Added debug interface with two 32-bit read-only registers in 32-bit mode.
// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
// My small test bench is modified to work with 32-bit mode.
//
// Revision 1.13 2001/11/08 14:54:23 mohor
// Comments in Slovene language deleted, few small fixes for better work of
// old tools. IRQs need to be fix.
//
// Revision 1.12 2001/11/07 17:51:52 gorban
// Heavily rewritten interrupt and LSR subsystems.
// Many bugs hopefully squashed.
//
// Revision 1.11 2001/10/29 17:00:46 gorban
// fixed parity sending and tx_fifo resets over- and underrun
//
// Revision 1.10 2001/10/20 09:58:40 gorban
// Small synopsis fixes
//
// Revision 1.9 2001/08/24 21:01:12 mohor
// Things connected to parity changed.
// Clock devider changed.
//
// Revision 1.8 2001/08/23 16:05:05 mohor
// Stop bit bug fixed.
// Parity bug fixed.
// WISHBONE read cycle bug fixed,
// OE indicator (Overrun Error) bug fixed.
// PE indicator (Parity Error) bug fixed.
// Register read bug fixed.
//
// Revision 1.6 2001/06/23 11:21:48 gorban
// DL made 16-bit long. Fixed transmission/reception bugs.
//
// Revision 1.5 2001/06/02 14:28:14 gorban
// Fixed receiver and transmitter. Major bug fixed.
//
// Revision 1.4 2001/05/31 20:08:01 gorban
// FIFO changes and other corrections.
//
// Revision 1.3 2001/05/27 17:37:49 gorban
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
//
// Revision 1.2 2001/05/21 19:12:02 gorban
// Corrected some Linter messages.
//
// Revision 1.1 2001/05/17 18:34:18 gorban
// First 'stable' release. Should be sythesizable now. Also added new header.
//
// Revision 1.0 2001-05-17 21:27:12+02 jacob
// Initial revision
//
//
`include "uart_defines.v"
module uart_transmitter
#(parameter SIM = 0)
(clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, stx_pad_o, tstate, tf_count, tx_reset, lsr_mask);
input clk;
input wb_rst_i;
input [7:0] lcr;
input tf_push;
input [7:0] wb_dat_i;
input enable;
input tx_reset;
input lsr_mask; //reset of fifo
output stx_pad_o;
output [2:0] tstate;
output [`UART_FIFO_COUNTER_W-1:0] tf_count;
reg [2:0] tstate;
reg [4:0] counter;
reg [2:0] bit_counter; // counts the bits to be sent
reg [6:0] shift_out; // output shift register
reg stx_o_tmp;
reg parity_xor; // parity of the word
reg tf_pop;
reg bit_out;
// TX FIFO instance
//
// Transmitter FIFO signals
wire [`UART_FIFO_WIDTH-1:0] tf_data_in;
wire [`UART_FIFO_WIDTH-1:0] tf_data_out;
wire tf_push;
wire tf_overrun;
wire [`UART_FIFO_COUNTER_W-1:0] tf_count;
assign tf_data_in = wb_dat_i;
uart_tfifo fifo_tx( // error bit signal is not used in transmitter FIFO
.clk( clk ),
.wb_rst_i( wb_rst_i ),
.data_in( tf_data_in ),
.data_out( tf_data_out ),
.push( tf_push ),
.pop( tf_pop ),
.overrun( tf_overrun ),
.count( tf_count ),
.fifo_reset( tx_reset ),
.reset_status(lsr_mask)
);
// TRANSMITTER FINAL STATE MACHINE
localparam s_idle = 3'd0;
localparam s_send_start = 3'd1;
localparam s_send_byte = 3'd2;
localparam s_send_parity = 3'd3;
localparam s_send_stop = 3'd4;
localparam s_pop_byte = 3'd5;
always @(posedge clk or posedge wb_rst_i)
begin
if (wb_rst_i)
begin
tstate <= s_idle;
stx_o_tmp <= 1'b1;
counter <= 5'b0;
shift_out <= 7'b0;
bit_out <= 1'b0;
parity_xor <= 1'b0;
tf_pop <= 1'b0;
bit_counter <= 3'b0;
end
else
if (enable | SIM)
begin
case (tstate)
s_idle : if (~|tf_count) // if tf_count==0
begin
tstate <= s_idle;
stx_o_tmp <= 1'b1;
end
else
begin
tf_pop <= 1'b0;
stx_o_tmp <= 1'b1;
tstate <= s_pop_byte;
end
s_pop_byte : begin
tf_pop <= 1'b1;
case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word
2'b00 : begin
bit_counter <= 3'b100;
parity_xor <= ^tf_data_out[4:0];
end
2'b01 : begin
bit_counter <= 3'b101;
parity_xor <= ^tf_data_out[5:0];
end
2'b10 : begin
bit_counter <= 3'b110;
parity_xor <= ^tf_data_out[6:0];
end
2'b11 : begin
bit_counter <= 3'b111;
parity_xor <= ^tf_data_out[7:0];
end
endcase
{shift_out[6:0], bit_out} <= tf_data_out;
tstate <= s_send_start;
end
s_send_start : begin
tf_pop <= 1'b0;
if (~|counter)
counter <= 5'b01111;
else
if (counter == 5'b00001)
begin
counter <= 0;
tstate <= s_send_byte;
end
else
counter <= counter - 5'd1;
stx_o_tmp <= 1'b0;
if (SIM) begin
tstate <= s_idle;
$write("%c", tf_data_out);
$fflush(32'h80000001);
end
end
s_send_byte : begin
if (~|counter)
counter <= 5'b01111;
else
if (counter == 5'b00001)
begin
if (bit_counter > 3'b0)
begin
bit_counter <= bit_counter - 3'd1;
{shift_out[5:0],bit_out } <= {shift_out[6:1], shift_out[0]};
tstate <= s_send_byte;
end
else // end of byte
if (~lcr[`UART_LC_PE])
begin
tstate <= s_send_stop;
end
else
begin
case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]})
2'b00: bit_out <= ~parity_xor;
2'b01: bit_out <= 1'b1;
2'b10: bit_out <= parity_xor;
2'b11: bit_out <= 1'b0;
endcase
tstate <= s_send_parity;
end
counter <= 0;
end
else
counter <= counter - 5'd1;
stx_o_tmp <= bit_out; // set output pin
end
s_send_parity : begin
if (~|counter)
counter <= 5'b01111;
else
if (counter == 5'b00001)
begin
counter <= 5'd0;
tstate <= s_send_stop;
end
else
counter <= counter - 5'd1;
stx_o_tmp <= bit_out;
end
s_send_stop : begin
if (~|counter)
begin
casez ({lcr[`UART_LC_SB],lcr[`UART_LC_BITS]})
3'b0??: counter <= 5'b01101; // 1 stop bit ok igor
3'b100: counter <= 5'b10101; // 1.5 stop bit
default: counter <= 5'b11101; // 2 stop bits
endcase
end
else
if (counter == 5'b00001)
begin
counter <= 0;
tstate <= s_idle;
end
else
counter <= counter - 5'd1;
stx_o_tmp <= 1'b1;
end
default : // should never get here
tstate <= s_idle;
endcase
end // end if enable
else
tf_pop <= 1'b0; // tf_pop must be 1 cycle width
end // transmitter logic
assign stx_pad_o = lcr[`UART_LC_BC] ? 1'b0 : stx_o_tmp; // Break condition
endmodule

View File

@ -1,258 +0,0 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// uart_wb.v ////
//// ////
//// ////
//// This file is part of the "UART 16550 compatible" project ////
//// http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Documentation related to this project: ////
//// - http://www.opencores.org/cores/uart16550/ ////
//// ////
//// Projects compatibility: ////
//// - WISHBONE ////
//// RS232 Protocol ////
//// 16550D uart (mostly supported) ////
//// ////
//// Overview (main Features): ////
//// UART core WISHBONE interface. ////
//// ////
//// Known problems (limits): ////
//// Inserts one wait state on all transfers. ////
//// Note affected signals and the way they are affected. ////
//// ////
//// To Do: ////
//// Nothing. ////
//// ////
//// Author(s): ////
//// - gorban@opencores.org ////
//// - Jacob Gorban ////
//// - Igor Mohor (igorm@opencores.org) ////
//// ////
//// Created: 2001/05/12 ////
//// Last Updated: 2001/05/17 ////
//// (See log for the revision history) ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000, 2001 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.16 2002/07/29 21:16:18 gorban
// The uart_defines.v file is included again in sources.
//
// Revision 1.15 2002/07/22 23:02:23 gorban
// Bug Fixes:
// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
// Problem reported by Kenny.Tung.
// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
//
// Improvements:
// * Made FIFO's as general inferrable memory where possible.
// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
//
// * Added optional baudrate output (baud_o).
// This is identical to BAUDOUT* signal on 16550 chip.
// It outputs 16xbit_clock_rate - the divided clock.
// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
//
// Revision 1.12 2001/12/19 08:03:34 mohor
// Warnings cleared.
//
// Revision 1.11 2001/12/06 14:51:04 gorban
// Bug in LSR[0] is fixed.
// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
//
// Revision 1.10 2001/12/03 21:44:29 gorban
// Updated specification documentation.
// Added full 32-bit data bus interface, now as default.
// Address is 5-bit wide in 32-bit data bus mode.
// Added wb_sel_i input to the core. It's used in the 32-bit mode.
// Added debug interface with two 32-bit read-only registers in 32-bit mode.
// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
// My small test bench is modified to work with 32-bit mode.
//
// Revision 1.9 2001/10/20 09:58:40 gorban
// Small synopsis fixes
//
// Revision 1.8 2001/08/24 21:01:12 mohor
// Things connected to parity changed.
// Clock devider changed.
//
// Revision 1.7 2001/08/23 16:05:05 mohor
// Stop bit bug fixed.
// Parity bug fixed.
// WISHBONE read cycle bug fixed,
// OE indicator (Overrun Error) bug fixed.
// PE indicator (Parity Error) bug fixed.
// Register read bug fixed.
//
// Revision 1.4 2001/05/31 20:08:01 gorban
// FIFO changes and other corrections.
//
// Revision 1.3 2001/05/21 19:12:01 gorban
// Corrected some Linter messages.
//
// Revision 1.2 2001/05/17 18:34:18 gorban
// First 'stable' release. Should be sythesizable now. Also added new header.
//
// Revision 1.0 2001-05-17 21:27:13+02 jacob
// Initial revision
//
//
// UART core WISHBONE interface
//
// Author: Jacob Gorban (jacob.gorban@flextronicssemi.com)
// Company: Flextronics Semiconductor
//
`include "uart_defines.v"
module uart_wb (clk, wb_rst_i,
wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_adr_i,
wb_adr_int, wb_dat_i, wb_dat_o, wb_dat8_i, wb_dat8_o, wb_dat32_o, wb_sel_i,
we_o, re_o // Write and read enable output for the core
);
input clk;
// WISHBONE interface
input wb_rst_i;
input wb_we_i;
input wb_stb_i;
input wb_cyc_i;
input [3:0] wb_sel_i;
input [2:0] wb_adr_i; //WISHBONE address line
input [7:0] wb_dat_i; //input WISHBONE bus
output [7:0] wb_dat_o;
reg [7:0] wb_dat_o;
wire [7:0] wb_dat_i;
reg [7:0] wb_dat_is;
output [2:0] wb_adr_int; // internal signal for address bus
input [7:0] wb_dat8_o; // internal 8 bit output to be put into wb_dat_o
output [7:0] wb_dat8_i;
input [31:0] wb_dat32_o; // 32 bit data output (for debug interface)
output wb_ack_o;
output we_o;
output re_o;
wire we_o;
reg wb_ack_o;
reg [7:0] wb_dat8_i;
wire [7:0] wb_dat8_o;
wire [2:0] wb_adr_int; // internal signal for address bus
reg [2:0] wb_adr_is;
reg wb_we_is;
reg wb_cyc_is;
reg wb_stb_is;
wire [3:0] wb_sel_i;
reg wre ;// timing control signal for write or read enable
// wb_ack_o FSM
reg [1:0] wbstate;
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) begin
wb_ack_o <= 1'b0;
wbstate <= 0;
wre <= 1'b1;
end else
case (wbstate)
0: begin
if (wb_stb_is & wb_cyc_is) begin
wre <= 0;
wbstate <= 1;
wb_ack_o <= 1;
end else begin
wre <= 1;
wb_ack_o <= 0;
end
end
1: begin
wb_ack_o <= 0;
wbstate <= 2;
wre <= 0;
end
2: begin
wb_ack_o <= 0;
wbstate <= 3;
wre <= 0;
end
3: begin
wb_ack_o <= 0;
wbstate <= 0;
wre <= 1;
end
endcase
assign we_o = wb_we_is & wb_stb_is & wb_cyc_is & wre ; //WE for registers
assign re_o = ~wb_we_is & wb_stb_is & wb_cyc_is & wre ; //RE for registers
// Sample input signals
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i) begin
wb_adr_is <= 0;
wb_we_is <= 0;
wb_cyc_is <= 0;
wb_stb_is <= 0;
wb_dat_is <= 0;
end else begin
wb_adr_is <= wb_adr_i;
wb_we_is <= wb_we_i;
wb_cyc_is <= wb_cyc_i;
wb_stb_is <= wb_stb_i;
wb_dat_is <= wb_dat_i;
end
always @(posedge clk or posedge wb_rst_i)
if (wb_rst_i)
wb_dat_o <= 0;
else
wb_dat_o <= wb_dat8_o;
always @(wb_dat_is)
wb_dat8_i = wb_dat_is;
assign wb_adr_int = wb_adr_is;
endmodule

View File

@ -1,72 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2019 Western Digital Corporation or its affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//********************************************************************************
// $Id$
//
// Function: Wrapper for on-chip memory instantiations
// Comments:
//
//********************************************************************************
`default_nettype none
module wb_mem_wrapper
#(parameter MEM_SIZE = 0,
parameter mem_clear = 0,
parameter INIT_FILE = "")
(
input wire i_clk,
input wire i_rst,
input wire [$clog2(MEM_SIZE)-1:2] i_wb_adr,
input wire [31:0] i_wb_dat,
input wire [3:0] i_wb_sel,
input wire i_wb_we ,
input wire i_wb_cyc,
input wire i_wb_stb,
output reg o_wb_ack,
output wire [31:0] o_wb_rdt);
wire [31:0] mem_addr;
wire [63:0] mem_wdata;
wire [63:0] mem_rdata;
wire [7:0] mem_we;
assign mem_we[3:0] = (i_wb_cyc & i_wb_stb & i_wb_we & !i_wb_adr[2]) ? i_wb_sel : 4'd0;
assign mem_we[7:4] = (i_wb_cyc & i_wb_stb & i_wb_we & i_wb_adr[2]) ? i_wb_sel : 4'd0;
assign mem_wdata = {i_wb_dat, i_wb_dat};
assign o_wb_rdt = i_wb_adr[2] ? mem_rdata[63:32] : mem_rdata[31:0];
always @(posedge i_clk) begin
o_wb_ack <= i_wb_cyc & i_wb_stb & !o_wb_ack;
if (i_rst)
o_wb_ack <= 1'b0;
end
dpram64
#(.SIZE (MEM_SIZE),
.mem_clear (mem_clear),
.memfile (INIT_FILE))
ram
(.clk (i_clk),
.we (mem_we),
.din (mem_wdata),
.waddr ({i_wb_adr[$clog2(MEM_SIZE)-1:3],3'b000}),
.raddr ({i_wb_adr[$clog2(MEM_SIZE)-1:3],3'b000}),
.dout (mem_rdata));
endmodule

View File

@ -2,417 +2,337 @@ package dbg
import chisel3._
import chisel3.util._
import lib._
import include._
import lib._
import dec._
class dbg_dma extends Bundle {
val dbg_dma_bubble = Input(Bool()) // Debug needs a bubble to send a valid
val dma_dbg_ready = Output(Bool()) // DMA is ready to accept debug request
}
object state_t {
val idle = 0.U(4.W)
val halting = 1.U(4.W)
val halted = 2.U(4.W)
val core_cmd_start = 3.U(4.W)
val core_cmd_wait = 4.U(4.W)
val sb_cmd_start = 5.U(4.W)
val sb_cmd_send = 6.U(4.W)
val sb_cmd_resp = 7.U(4.W)
val cmd_done = 8.U(4.W)
val resuming = 9.U(4.W)
val idle = 0.U(3.W)
val halting = 1.U(3.W)
val halted = 2.U(3.W)
val cmd_start = 3.U(3.W)
val cmd_wait = 4.U(3.W)
val cmd_done = 5.U(3.W)
val resuming = 6.U(3.W)
}
object sb_state_t {
val sbidle = 0.U(4.W)
val wait_rd = 1.U(4.W)
val wait_wr = 2.U(4.W)
val cmd_rd = 3.U(4.W)
val cmd_wr = 4.U(4.W)
val cmd_wr_addr = 5.U(4.W)
val cmd_wr_data = 6.U(4.W)
val rsp_rd = 7.U(4.W)
val rsp_wr = 8.U(4.W)
val done = 9.U(4.W)
val sbidle = 0.U(4.W)
val wait_rd = 1.U(4.W)
val wait_wr = 2.U(4.W)
val cmd_rd = 3.U(4.W)
val cmd_wr = 4.U(4.W)
val cmd_wr_addr = 5.U(4.W)
val cmd_wr_data = 6.U(4.W)
val rsp_rd = 7.U(4.W)
val rsp_wr = 8.U(4.W)
val done = 9.U(4.W)
}
class dbg extends Module with lib with RequireAsyncReset {
val io = IO(new Bundle {
val dbg_cmd_size = Output(UInt(2.W))
val dbg_core_rst_l = Output(Bool())
val core_dbg_rddata = Input(UInt(32.W))
val core_dbg_cmd_done = Input(Bool())
val core_dbg_cmd_fail = Input(Bool())
val dbg_halt_req = Output(Bool())
val dbg_resume_req = Output(Bool())
val dec_tlu_debug_mode = Input(Bool())
val dec_tlu_dbg_halted = Input(Bool())
val dec_tlu_mpc_halted_only = Input(Bool())
val dec_tlu_resume_ack = Input(Bool())
val dmi_reg_en = Input(Bool())
val dmi_reg_addr = Input(UInt(7.W))
val dmi_reg_wr_en = Input(Bool())
val dmi_reg_wdata = Input(UInt(32.W))
val dmi_reg_rdata = Output(UInt(32.W))
val dbg_cmd_size = Output(UInt(2.W))
val dbg_core_rst_l = Output(Bool())
val core_dbg_rddata = Input(UInt(32.W))
val core_dbg_cmd_done = Input(Bool())
val core_dbg_cmd_fail = Input(Bool())
val dbg_halt_req = Output(Bool())
val dbg_resume_req = Output(Bool())
val dec_tlu_debug_mode = Input(Bool())
val dec_tlu_dbg_halted = Input(Bool())
val dec_tlu_mpc_halted_only = Input(Bool())
val dec_tlu_resume_ack = Input(Bool())
val dmi_reg_en = Input(Bool())
val dmi_reg_addr = Input(UInt(7.W))
val dmi_reg_wr_en = Input(Bool())
val dmi_reg_wdata = Input(UInt(32.W))
val dmi_reg_rdata = Output(UInt(32.W))
val sb_axi = new axi_channels(SB_BUS_TAG)
val dbg_dec_dma = Flipped(new dec_dbg)
// val dbg_dma = Flipped(new dec_dbg)
val dbg_dma = Flipped(new dbg_dma)
val dbg_bus_clk_en = Input(Bool())
val dbg_rst_l = Input(AsyncReset())
val clk_override = Input(Bool())
val scan_mode = Input(Bool())
val dbg_bus_clk_en = Input(Bool())
val dbg_rst_l = Input(Bool())
val clk_override = Input(Bool())
val scan_mode = Input(Bool())
})
val dbg_state = WireInit(state_t.idle)
val dbg_state_en = WireInit(false.B)
val sb_state = WireInit(sb_state_t.sbidle)
val sb_state_en = WireInit(Bool(), false.B)
val dmcontrol_reg = WireInit(0.U(32.W))
val sbaddress0_reg = WireInit(0.U(32.W))
val sbcs_sbbusy_wren = WireInit(false.B)
val sbcs_sberror_wren = WireInit(false.B)
val sb_bus_rdata = WireInit(0.U(64.W))
val sbaddress0_reg_wren1 = WireInit(false.B)
val dmstatus_reg = WireInit(0.U(32.W))
val dmstatus_havereset = WireInit(false.B)
val dmstatus_haveresetn = WireInit(false.B)
val dmstatus_resumeack = WireInit(false.B)
val dmstatus_unavail = WireInit(false.B)
val dmstatus_running = WireInit(false.B)
val dmstatus_halted = WireInit(false.B)
val abstractcs_busy_wren = WireInit(false.B)
val abstractcs_busy_din = WireInit(false.B)
val sb_bus_cmd_read = WireInit(false.B)
val sb_bus_cmd_write_addr = WireInit(false.B)
val sb_bus_cmd_write_data = WireInit(false.B)
val sb_bus_rsp_read = WireInit(false.B)
val sb_bus_rsp_error = WireInit(false.B)
val sb_bus_rsp_write = WireInit(false.B)
val sbcs_sbbusy_din = WireInit(false.B)
val sbcs_sberror_din = WireInit(0.U(3.W))
val data1_reg = WireInit(0.U(32.W))
val sbcs_reg = WireInit(0.U(32.W))
val execute_command = WireInit(false.B)
val command_reg = WireInit(0.U(32.W))
val dbg_sb_bus_error = WireInit(false.B)
val command_wren = WireInit(false.B)
val command_din = WireInit(0.U(32.W))
val dbg_cmd_next_addr = WireInit(0.U(32.W))
val data0_reg_wren2 = WireInit(false.B)
val sb_abmem_cmd_done_in = WireInit(false.B)
val sb_abmem_data_done_in = WireInit(false.B)
val sb_abmem_cmd_done_en = WireInit(false.B)
val sb_abmem_data_done_en = WireInit(false.B)
val abmem_addr_external = WireInit(false.B)
val sb_cmd_pending = WireInit(false.B)
val sb_abmem_cmd_write = WireInit(false.B)
val abmem_addr_in_dccm_region = WireInit(false.B)
val abmem_addr_in_iccm_region = WireInit(false.B)
val abmem_addr_in_pic_region = WireInit(false.B)
val sb_abmem_cmd_size = WireInit(0.U(4.W))
val abstractcs_error_din = WireInit(0.U(3.W))
val dmcontrol_wren_Q = WireInit(false.B)
val abstractcs_reg = WireInit(2.U(32.W))
val dbg_state = WireInit(state_t.idle)
val dbg_state_en = WireInit(false.B)
val sb_state = WireInit(sb_state_t.sbidle)
val sb_state_en = WireInit(Bool(), false.B)
val dmcontrol_reg = WireInit(0.U(32.W))
val sbaddress0_reg = WireInit(0.U(32.W))
val sbcs_sbbusy_wren = WireInit(false.B)
val sbcs_sberror_wren = WireInit(false.B)
val sb_bus_rdata = WireInit(0.U(64.W))
val sbaddress0_reg_wren1 = WireInit(false.B)
val dmstatus_reg = WireInit(0.U(32.W))
val dmstatus_havereset = WireInit(false.B)
val dmstatus_resumeack = WireInit(false.B)
val dmstatus_unavail = WireInit(false.B)
val dmstatus_running = WireInit(false.B)
val dmstatus_halted = WireInit(false.B)
val abstractcs_busy_wren = WireInit(false.B)
val abstractcs_busy_din = WireInit(false.B)
val sb_bus_cmd_read = WireInit(false.B)
val sb_bus_cmd_write_addr = WireInit(false.B)
val sb_bus_cmd_write_data = WireInit(false.B)
val sb_bus_rsp_read = WireInit(false.B)
val sb_bus_rsp_error = WireInit(false.B)
val sb_bus_rsp_write = WireInit(false.B)
val sbcs_sbbusy_din = WireInit(false.B)
val sbcs_sberror_din = WireInit(0.U(3.W))
val data1_reg = WireInit(0.U(32.W))
val sbcs_reg = WireInit(0.U(32.W))
val dbg_free_clken = io.dmi_reg_en | execute_command | (dbg_state =/= state_t.idle) | dbg_state_en | io.dec_tlu_dbg_halted |
io.dec_tlu_mpc_halted_only | io.dec_tlu_debug_mode | io.dbg_halt_req | io.clk_override
val sb_free_clken = io.dmi_reg_en | execute_command | sb_state_en | (sb_state =/= sb_state_t.sbidle) | io.clk_override;
val dbg_free_clken = io.dmi_reg_en | (dbg_state =/= state_t.idle) | dbg_state_en | io.dec_tlu_dbg_halted | io.clk_override
val sb_free_clken = io.dmi_reg_en | sb_state_en | (sb_state =/= sb_state_t.sbidle) | io.clk_override;
val dbg_free_clk = rvclkhdr(clock, dbg_free_clken, io.scan_mode) // dbg_free_cgc
val sb_free_clk = rvclkhdr(clock, sb_free_clken, io.scan_mode) // sb_free_cgc
val dbg_free_clk = rvoclkhdr(clock, dbg_free_clken, io.scan_mode) // dbg_free_cgc
val sb_free_clk = rvoclkhdr(clock, sb_free_clken, io.scan_mode) // sb_free_cgc
val dbg_dm_rst_l = (io.dbg_rst_l.asBool() & (dmcontrol_reg(0) | io.scan_mode)).asAsyncReset()
dontTouch(dbg_dm_rst_l)
val rst_temp = (dbg_dm_rst_l.asBool() & reset.asBool()).asAsyncReset()
dontTouch(rst_temp)
val dbg_dm_rst_l = (io.dbg_rst_l.asBool() & (dmcontrol_reg(0) | io.scan_mode)).asAsyncReset()
io.dbg_core_rst_l := (!dmcontrol_reg(1)).asBool() | io.scan_mode
val sbcs_wren = (io.dmi_reg_addr === "h38".U(7.W)) & io.dmi_reg_en & io.dmi_reg_wr_en & (sb_state === sb_state_t.sbidle)
val sbcs_sbbusyerror_wren = (sbcs_wren & io.dmi_reg_wdata(22)) | (sbcs_reg(21) & io.dmi_reg_en & ((io.dmi_reg_wr_en &
(io.dmi_reg_addr === "h39".U(7.W))) | (io.dmi_reg_addr === "h3c".U(7.W)) |
(io.dmi_reg_addr === "h3d".U(7.W))))
io.dbg_core_rst_l := (!dmcontrol_reg(1)).asBool()
val sbcs_wren = (io.dmi_reg_addr === "h38".U) & io.dmi_reg_en & io.dmi_reg_wr_en & (sb_state === sb_state_t.sbidle)
val sbcs_sbbusyerror_wren = (sbcs_wren & io.dmi_reg_wdata(22)) | ((sb_state =/= sb_state_t.sbidle) & io.dmi_reg_en &
((io.dmi_reg_addr === "h39".U) | (io.dmi_reg_addr === "h3c".U) | (io.dmi_reg_addr === "h3d".U)))
val sbcs_sbbusyerror_din = (~(sbcs_wren & io.dmi_reg_wdata(22))).asUInt()
val temp_sbcs_22 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
RegEnable(sbcs_sbbusyerror_din, 0.U, sbcs_sbbusyerror_wren)} // sbcs_sbbusyerror_reg
val temp_sbcs_21 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
RegEnable(sbcs_sbbusy_din, 0.U, sbcs_sbbusy_wren)} // sbcs_sbbusy_reg
val temp_sbcs_20 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
RegEnable(io.dmi_reg_wdata(20), 0.U, sbcs_wren)} // sbcs_sbreadonaddr_reg
val temp_sbcs_19_15 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
RegEnable(Cat(io.dmi_reg_wdata(19), ~io.dmi_reg_wdata(18), io.dmi_reg_wdata(17, 15)), 0.U, sbcs_wren)} // sbcs_misc_reg
val temp_sbcs_14_12 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
RegEnable(sbcs_sberror_din(2, 0), 0.U, sbcs_sberror_wren)} // sbcs_error_reg
val sbcs_sbbusyerror_din = (~(sbcs_wren & io.dmi_reg_wdata(22))).asUInt()
val temp_sbcs_22 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
RegEnable(sbcs_sbbusyerror_din, 0.U, sbcs_sbbusyerror_wren)
} // sbcs_sbbusyerror_reg
sbcs_reg := Cat(1.U(3.W), 0.U(6.W), temp_sbcs_22, temp_sbcs_21, temp_sbcs_20, temp_sbcs_19_15(4), ~temp_sbcs_19_15(3),
temp_sbcs_19_15(2,0), temp_sbcs_14_12, "h20".U(7.W), "b01111".U(5.W))
val temp_sbcs_21 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
RegEnable(sbcs_sbbusy_din, 0.U, sbcs_sbbusy_wren)
} // sbcs_sbbusy_reg
val sbcs_unaligned = (sbcs_reg(19, 17) === 1.U(3.W)) & sbaddress0_reg(0) |
(sbcs_reg(19, 17) === 2.U(3.W)) & sbaddress0_reg(1, 0).orR |
(sbcs_reg(19, 17) === 3.U(3.W)) & sbaddress0_reg(2, 0).orR
val temp_sbcs_20 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
RegEnable(io.dmi_reg_wdata(20), 0.U, sbcs_wren)
} // sbcs_sbreadonaddr_reg
val temp_sbcs_19_15 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
RegEnable(io.dmi_reg_wdata(19, 15), 0.U, sbcs_wren)
} // sbcs_misc_reg
val temp_sbcs_14_12 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
RegEnable(sbcs_sberror_din(2, 0), 0.U, sbcs_sberror_wren)
} // sbcs_error_reg
sbcs_reg := Cat(1.U(3.W), 0.U(6.W), temp_sbcs_22, temp_sbcs_21, temp_sbcs_20, temp_sbcs_19_15, temp_sbcs_14_12, "h20".U(7.W), "b01111".U(5.W))
val sbcs_unaligned = (sbcs_reg(19, 17) === "b001".U(3.W)) & sbaddress0_reg(0) |
(sbcs_reg(19, 17) === "b010".U(3.W)) & sbaddress0_reg(1, 0).orR |
(sbcs_reg(19, 17) === "b011".U(3.W)) & sbaddress0_reg(2, 0).orR
val sbcs_illegal_size = sbcs_reg(19)
val sbaddress0_incr = Fill(4, (sbcs_reg(19, 17) === 0.U(3.W))) & 1.U(4.W) | Fill(4, (sbcs_reg(19, 17) === 1.U(3.W))) & 2.U(4.W) |
Fill(4, (sbcs_reg(19, 17) === 2.U(3.W))) & 4.U(4.W) | Fill(4, (sbcs_reg(19, 17) === 3.U(3.W))) & 8.U(4.W)
val sbaddress0_incr = Fill(4, (sbcs_reg(19, 17) === "h0".U)) & "b0001".U(4.W) | Fill(4, (sbcs_reg(19, 17) === "h1".U)) & "b0010".U(4.W) |
Fill(4, (sbcs_reg(19, 17) === "h2".U)) & "b0100".U(4.W) | Fill(4, (sbcs_reg(19, 17) === "h3".U)) & "b1000".U(4.W)
val sbdata0_reg_wren0 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h3c".U)
val sbdata0_reg_wren1 = (sb_state === sb_state_t.rsp_rd) & sb_state_en & !sbcs_sberror_wren
val sbdata0_reg_wren = sbdata0_reg_wren0 | sbdata0_reg_wren1
val sbdata0_reg_wren = sbdata0_reg_wren0 | sbdata0_reg_wren1
val sbdata1_reg_wren0 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h3d".U)
val sbdata1_reg_wren1 = (sb_state === sb_state_t.rsp_rd) & sb_state_en & !sbcs_sberror_wren
val sbdata1_reg_wren = sbdata1_reg_wren0 | sbdata1_reg_wren1
val sbdata0_din = Fill(32, sbdata0_reg_wren0) & io.dmi_reg_wdata | Fill(32, sbdata0_reg_wren1) & sb_bus_rdata(31, 0)
val sbdata1_din = Fill(32, sbdata1_reg_wren0) & io.dmi_reg_wdata | Fill(32, sbdata1_reg_wren1) & sb_bus_rdata(63, 32)
val sbdata1_reg_wren = sbdata1_reg_wren0 | sbdata1_reg_wren1
val sbdata0_din = Fill(32, sbdata0_reg_wren0) & io.dmi_reg_wdata |
Fill(32, sbdata0_reg_wren1) & sb_bus_rdata(31, 0)
val sbdata0_reg = withReset(dbg_dm_rst_l) { rvdffe(sbdata0_din, sbdata0_reg_wren, clock, io.scan_mode)} // dbg_sbdata0_reg
val sbdata1_reg = withReset(dbg_dm_rst_l) { rvdffe(sbdata1_din, sbdata1_reg_wren, clock, io.scan_mode)} // dbg_sbdata1_reg
val sbdata1_din = Fill(32, sbdata1_reg_wren0) & io.dmi_reg_wdata |
Fill(32, sbdata1_reg_wren1) & sb_bus_rdata(63, 32)
val sbaddress0_reg_wren0 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h39".U)
val sbaddress0_reg_wren = sbaddress0_reg_wren0 | sbaddress0_reg_wren1
val sbaddress0_reg_din = Fill(32, sbaddress0_reg_wren0) & io.dmi_reg_wdata |
val sbdata0_reg = withReset(dbg_dm_rst_l) {
rvdffe(sbdata0_din, sbdata0_reg_wren, clock, io.scan_mode)
} // dbg_sbdata0_reg
val sbdata1_reg = withReset(dbg_dm_rst_l) {
rvdffe(sbdata1_din, sbdata1_reg_wren, clock, io.scan_mode)
} // dbg_sbdata1_reg
val sbaddress0_reg_wren0 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h39".U)
val sbaddress0_reg_wren = sbaddress0_reg_wren0 | sbaddress0_reg_wren1
val sbaddress0_reg_din = Fill(32, sbaddress0_reg_wren0) & io.dmi_reg_wdata |
Fill(32, sbaddress0_reg_wren1) & (sbaddress0_reg + Cat(0.U(28.W), sbaddress0_incr))
sbaddress0_reg := withReset(dbg_dm_rst_l) { rvdffe(sbaddress0_reg_din, sbaddress0_reg_wren, clock, io.scan_mode)} // dbg_sbaddress0_reg
sbaddress0_reg := withReset(dbg_dm_rst_l) {
rvdffe(sbaddress0_reg_din, sbaddress0_reg_wren, clock, io.scan_mode)
} // dbg_sbaddress0_reg
val sbreadonaddr_access = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h39".U) & sbcs_reg(20)
val sbreadondata_access = io.dmi_reg_en & !io.dmi_reg_wr_en & (io.dmi_reg_addr === "h3c".U) & sbcs_reg(15)
val sbdata0wr_access = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h3c".U)
val dmcontrol_wren = (io.dmi_reg_addr === "h10".U) & io.dmi_reg_en & io.dmi_reg_wr_en
val resumereq = (dmcontrol_reg(30) & !dmcontrol_reg(31) & dmcontrol_wren_Q).asBool()
val sbdata0wr_access = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h3c".U)
val dmcontrol_wren = (io.dmi_reg_addr === "h10".U) & io.dmi_reg_en & io.dmi_reg_wr_en
val dm_temp = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegEnable(
Cat(io.dmi_reg_wdata(31, 30), io.dmi_reg_wdata(28), io.dmi_reg_wdata(1)),
0.U, dmcontrol_wren)
} // dmcontrolff
val dm_temp = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegEnable(Cat(io.dmi_reg_wdata(31, 30), io.dmi_reg_wdata(28), io.dmi_reg_wdata(1)),0.U, dmcontrol_wren)} // dmcontrolff
val dm_temp_0 = withClockAndReset(dbg_free_clk, io.dbg_rst_l) {
RegEnable(io.dmi_reg_wdata(0), 0.U, dmcontrol_wren)} // dmcontrol_dmactive_ff
val temp = Cat(dm_temp(3, 2), 0.U, dm_temp(1), 0.U(26.W), dm_temp(0), dm_temp_0)
dmcontrol_reg := temp
val dm_temp_0 = withClockAndReset(dbg_free_clk, io.dbg_rst_l.asAsyncReset()) {
RegEnable(io.dmi_reg_wdata(0), 0.U, dmcontrol_wren)
} // dmcontrol_dmactive_ff
dmcontrol_wren_Q := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegNext(dmcontrol_wren, 0.U)} // dmcontrol_wrenff
val temp = Cat(dm_temp(3, 2), 0.U, dm_temp(1), 0.U(26.W), dm_temp(0), dm_temp_0)
dmcontrol_reg := temp
dmstatus_reg := Cat(0.U(12.W), Fill(2, dmstatus_havereset), Fill(2, dmstatus_resumeack), 0.U(2.W), Fill(2, dmstatus_unavail),
Fill(2, dmstatus_running), Fill(2, dmstatus_halted), 1.U(1.W), 0.U(3.W), 2.U(4.W))
val dmcontrol_wren_Q = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegNext(dmcontrol_wren, 0.U)
} // dmcontrol_wrenff
val dmstatus_resumeack_wren = (dbg_state === state_t.resuming) & io.dec_tlu_resume_ack | dmstatus_resumeack & resumereq & dmstatus_halted
val dmstatus_resumeack_din = (dbg_state === state_t.resuming) & io.dec_tlu_resume_ack
val dmstatus_haveresetn_wren = (io.dmi_reg_addr === "h10".U) & io.dmi_reg_wdata(28) & io.dmi_reg_en & io.dmi_reg_wr_en & dmcontrol_reg(0)
dmstatus_havereset := ~dmstatus_haveresetn
dmstatus_reg := Cat(0.U(12.W), Fill(2, dmstatus_havereset), Fill(2, dmstatus_resumeack), 0.U(2.W), Fill(2, dmstatus_unavail), Fill(2, dmstatus_running), Fill(2, dmstatus_halted), 1.U(1.W), 0.U(3.W), 2.U(4.W))
val temp_rst = reset.asBool()
val dmstatus_resumeack_wren = (dbg_state === state_t.resuming) & io.dec_tlu_resume_ack | dmstatus_resumeack & !dmcontrol_reg(30)
val dmstatus_resumeack_din = (dbg_state === state_t.resuming) & io.dec_tlu_resume_ack
val dmstatus_havereset_wren = (io.dmi_reg_addr === "h10".U) & io.dmi_reg_wdata(1) & io.dmi_reg_en & io.dmi_reg_wr_en
val dmstatus_havereset_rst = (io.dmi_reg_addr === "h10".U) & io.dmi_reg_wdata(28) & io.dmi_reg_en & io.dmi_reg_wr_en;
val temp_rst = reset.asBool()
dmstatus_unavail := (dmcontrol_reg(1) | !(temp_rst)).asBool()
dmstatus_running := ~(dmstatus_unavail | dmstatus_halted)
dmstatus_resumeack := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegEnable(dmstatus_resumeack_din, 0.U, dmstatus_resumeack_wren.asBool())} // dmstatus_resumeack_reg
dmstatus_halted := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegNext(io.dec_tlu_dbg_halted & !io.dec_tlu_mpc_halted_only, 0.U)} // dmstatus_halted_reg
dmstatus_haveresetn := withClock(dbg_free_clk) {
RegEnable(true.B, 0.U, dmstatus_haveresetn_wren)} // dmstatus_haveresetn_reg
RegEnable(dmstatus_resumeack_din, 0.U, dmstatus_resumeack_wren)
} // dmstatus_resumeack_reg
val haltsum0_reg = Cat(0.U(31.W), dmstatus_halted)
dmstatus_halted := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegNext(io.dec_tlu_dbg_halted & !io.dec_tlu_mpc_halted_only, 0.U)
} // dmstatus_halted_reg
val abstractcs_error_sel0 = abstractcs_reg(12) & ~(abstractcs_reg(10,8).orR) & io.dmi_reg_en & ((io.dmi_reg_wr_en & ((io.dmi_reg_addr === "h16".U(7.W)) |
(io.dmi_reg_addr === "h17".U(7.W))) | (io.dmi_reg_addr === "h18".U(7.W))) | (io.dmi_reg_addr === 4.U(7.W)) |
(io.dmi_reg_addr === 5.U(7.W)))
val abstractcs_error_sel1 = execute_command & ~(abstractcs_reg(10,8).orR) &
((!((command_reg(31,24) === 0.U(8.W)) | (command_reg(31,24) === 2.U(8.W)))) | // Illegal command
(((command_reg(22,20) === 3.U(3.W)) | (command_reg(22))) & (command_reg(31,24) === 2.U(8.W))) | // Illegal abstract memory size (can't be DW or higher)
((command_reg(22,20) =/= 2.U(3.W)) & ((command_reg(31,24) === 0.U(8.W)) & command_reg(17))) | // Illegal abstract reg size
((command_reg(31,24) === 0.U(8.W)) & command_reg(18))) // postexec for abstract register access
val abstractcs_error_sel2 = ((io.core_dbg_cmd_done & io.core_dbg_cmd_fail) | // exception from core
(execute_command & (command_reg(31,24) === 0.U(8.W)) & // unimplemented regs
(((command_reg(15,12) === 1.U(4.W)) & (command_reg(11,5) =/= 0.U(7.W))) | (command_reg(15,13) =/= 0.U(3.W))))) & ~(abstractcs_reg(10,8).orR)
val abstractcs_error_sel3 = execute_command & (dbg_state =/= state_t.halted) & ~(abstractcs_reg(10,8).orR)
val abstractcs_error_sel4 = dbg_sb_bus_error & io.dbg_bus_clk_en & ~(abstractcs_reg(10,8).orR) // sb bus error for abstract memory command
val abstractcs_error_sel5 = execute_command & (command_reg(31,24) === 2.U(8.W)) & ~(abstractcs_reg(10,8).orR) &
(((command_reg(22,20) === 1.U(3.W)) & data1_reg(0)) | ((command_reg(22,20) === 2.U(3.W)) & (data1_reg(1,0).orR))) //Unaligned address for abstract memory
val abstractcs_error_sel6 = (io.dmi_reg_addr === "h16".U(7.W)) & io.dmi_reg_en & io.dmi_reg_wr_en
dmstatus_havereset := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegNext(Mux(dmstatus_havereset_wren, true.B, dmstatus_havereset) & !dmstatus_havereset_rst, false.B)
} // dmstatus_havereset_reg
val haltsum0_reg = Cat(0.U(31.W), dmstatus_halted)
val abstractcs_reg = WireInit(2.U(32.W))
val abstractcs_error_sel0 = abstractcs_reg(12) & io.dmi_reg_en & (io.dmi_reg_wr_en & ((io.dmi_reg_addr === "h16".U) | (io.dmi_reg_addr === "h17".U)) | (io.dmi_reg_addr === "h4".U))
val abstractcs_error_sel1 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h17".U) & !((io.dmi_reg_wdata(31, 24) === 0.U) | (io.dmi_reg_wdata(31, 24) === "h2".U))
val abstractcs_error_sel2 = io.core_dbg_cmd_done & io.core_dbg_cmd_fail
val abstractcs_error_sel3 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h17".U) & !dmstatus_reg(9);
val abstractcs_error_sel4 = (io.dmi_reg_addr === "h17".U) & io.dmi_reg_en & io.dmi_reg_wr_en &
((io.dmi_reg_wdata(22, 20) =/= "b010".U(3.W)) | ((io.dmi_reg_wdata(31, 24) === "h2".U) && data1_reg(1, 0).orR))
val abstractcs_error_sel5 = (io.dmi_reg_addr === "h16".U) & io.dmi_reg_en & io.dmi_reg_wr_en
val abstractcs_error_selor = abstractcs_error_sel0 | abstractcs_error_sel1 | abstractcs_error_sel2 | abstractcs_error_sel3 | abstractcs_error_sel4 | abstractcs_error_sel5
val abstractcs_error_din = (Fill(3, abstractcs_error_sel0) & "b001".U(3.W)) |
(Fill(3, abstractcs_error_sel1) & "b010".U(3.W)) |
(Fill(3, abstractcs_error_sel2) & "b011".U(3.W)) |
(Fill(3, abstractcs_error_sel3) & "b100".U(3.W)) |
(Fill(3, abstractcs_error_sel4) & "b111".U(3.W)) |
(Fill(3, abstractcs_error_sel5) & (~io.dmi_reg_wdata(10, 8)).asUInt() & abstractcs_reg(10, 8)) |
(Fill(3, (~abstractcs_error_selor).asUInt()) & abstractcs_reg(10, 8))
val abs_temp_12 = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegEnable(abstractcs_busy_din, 0.U, abstractcs_busy_wren)
} // dmabstractcs_busy_reg
abstractcs_error_din := MuxCase(abstractcs_reg(10,8), Array(
abstractcs_error_sel0 -> 1.U(3.W),
abstractcs_error_sel1 -> 2.U(3.W),
abstractcs_error_sel2 -> 3.U(3.W),
abstractcs_error_sel3 -> 4.U(3.W),
abstractcs_error_sel4 -> 5.U(3.W),
abstractcs_error_sel5 -> 7.U(3.W),
abstractcs_error_sel6 -> (~io.dmi_reg_wdata(10,8) & abstractcs_reg(10,8))
))
val abs_temp_12 = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegEnable(abstractcs_busy_din, 0.U, abstractcs_busy_wren)} // dmabstractcs_busy_reg
val abs_temp_10_8 = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegNext(abstractcs_error_din, 0.U)} // dmabstractcs_error_reg
RegNext(abstractcs_error_din(2, 0), 0.U)
} // dmabstractcs_error_reg
abstractcs_reg := Cat(0.U(19.W), abs_temp_12, 0.U(1.W), abs_temp_10_8, 2.U(8.W))
abstractcs_reg := Cat(0.U(19.W), abs_temp_12, 0.U(1.W), abs_temp_10_8, 2.U(8.W))
val abstractauto_reg_wren = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h18".U(7.W)) & !abstractcs_reg(12)
val abstractauto_reg = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegEnable(io.dmi_reg_wdata(1,0), 0.U, abstractauto_reg_wren)} // dbg_abstractauto_reg
val command_wren = (io.dmi_reg_addr === "h17".U) & io.dmi_reg_en & io.dmi_reg_wr_en & (dbg_state === state_t.halted)
val command_din = Cat(io.dmi_reg_wdata(31, 24), 0.U(1.W), io.dmi_reg_wdata(22, 20), 0.U(3.W), io.dmi_reg_wdata(16, 0))
val command_reg = withReset(dbg_dm_rst_l) {
rvdffe(command_din, command_wren,clock,io.scan_mode)
} // dmcommand_reg
val execute_command_ns = command_wren | (io.dmi_reg_en & !abstractcs_reg(12) & (((io.dmi_reg_addr === 4.U(7.W)) &
abstractauto_reg(0)) | ((io.dmi_reg_addr === 5.U(7.W)) & abstractauto_reg(1))))
command_wren := (io.dmi_reg_addr === "h17".U(7.W)) & io.dmi_reg_en & io.dmi_reg_wr_en
val command_regno_wren = command_wren | ((command_reg(31,24) === 0.U(8.W)) & command_reg(19) & (dbg_state === state_t.cmd_done) &
~(abstractcs_reg(10,8).orR)) // aarpostincrement
val data0_reg_wren0 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h4".U) & (dbg_state === state_t.halted)
val data0_reg_wren1 = io.core_dbg_cmd_done & (dbg_state === state_t.cmd_wait) & !command_reg(16)
val command_postexec_din = (io.dmi_reg_wdata(31,24) === 0.U(8.W)) & io.dmi_reg_wdata(18)
val command_transfer_din = (io.dmi_reg_wdata(31,24) === 0.U(8.W)) & io.dmi_reg_wdata(17)
val temp_command_din_31_16 = Cat(io.dmi_reg_wdata(31,24), 0.U, io.dmi_reg_wdata(22,19), command_postexec_din, command_transfer_din, io.dmi_reg_wdata(16))
val temp_command_din_15_0 = Mux(command_wren, io.dmi_reg_wdata(15,0), dbg_cmd_next_addr(15,0))
command_din := Cat(temp_command_din_31_16, temp_command_din_15_0)
execute_command := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegNext(execute_command_ns, false.B)} // execute_commandff
val temp_command_reg_31_16 = withReset(dbg_dm_rst_l) {
rvdffe(command_din(31,16), command_wren, clock, io.scan_mode)} // dmcommand_reg
val temp_command_reg_15_0 = withReset(dbg_dm_rst_l) {
rvdffe(command_din(15,0), command_regno_wren, clock, io.scan_mode)} // dmcommand_regno_reg
command_reg := Cat(temp_command_reg_31_16, temp_command_reg_15_0)
val data0_reg_wren0 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h4".U) & (dbg_state === state_t.halted) & !abstractcs_reg(12)
val data0_reg_wren1 = io.core_dbg_cmd_done & (dbg_state === state_t.core_cmd_wait) & !command_reg(16)
val data0_reg_wren = data0_reg_wren0 | data0_reg_wren1 | data0_reg_wren2
val data0_din = Fill(32, data0_reg_wren0) & io.dmi_reg_wdata |
Fill(32, data0_reg_wren1) & io.core_dbg_rddata |
Fill(32, data0_reg_wren2) & sb_bus_rdata(31,0)
val data0_reg = withReset(dbg_dm_rst_l.asAsyncReset()) {
rvdffe(data0_din, data0_reg_wren, clock, io.scan_mode)
val data0_reg_wren = data0_reg_wren0 | data0_reg_wren1
val data0_din = Fill(32, data0_reg_wren0) & io.dmi_reg_wdata | Fill(32, data0_reg_wren1) & io.core_dbg_rddata
val data0_reg = withReset(dbg_dm_rst_l) {
rvdffe(data0_din,data0_reg_wren,clock,io.scan_mode)
} // dbg_data0_reg
val data1_reg_wren0 = (io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === 5.U(7.W)) & (dbg_state === state_t.halted)) & !abstractcs_reg(12)
val data1_reg_wren1 = (dbg_state === state_t.cmd_done) & (command_reg(31,24) === 2.U(8.W)) & command_reg(19) & ~(abstractcs_reg(10,8).orR) // aampostincrement
val data1_reg_wren = data1_reg_wren0 | data1_reg_wren1
val data1_din = Fill(32, data1_reg_wren0) & io.dmi_reg_wdata | Fill(32, data1_reg_wren1) & dbg_cmd_next_addr(31,0)
data1_reg := withReset(dbg_dm_rst_l.asAsyncReset()) {
rvdffe(data1_din, data1_reg_wren, clock, io.scan_mode)} // dbg_data1_reg
val sb_abmem_cmd_done = withClockAndReset(dbg_free_clk, dbg_dm_rst_l){
RegEnable(sb_abmem_cmd_done_in, false.B, sb_abmem_cmd_done_en)} // sb_abmem_cmd_doneff
val sb_abmem_data_done = withClockAndReset(dbg_free_clk, dbg_dm_rst_l){
RegEnable(sb_abmem_data_done_in, false.B, sb_abmem_data_done_en)} // sb_abmem_data_doneff
val data1_reg_wren = (io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h5".U) & (dbg_state === state_t.halted))
val data1_din = Fill(32, data1_reg_wren) & io.dmi_reg_wdata
data1_reg := withReset(dbg_dm_rst_l) {
rvdffe(data1_din, data1_reg_wren, clock, io.scan_mode)
} // dbg_data1_reg
val dbg_nxtstate = WireInit(state_t.idle)
dbg_nxtstate := state_t.idle
dbg_state_en := false.B
abstractcs_busy_wren := false.B
abstractcs_busy_din := false.B
io.dbg_halt_req := false.B
io.dbg_resume_req := false.B
dbg_sb_bus_error := false.B
data0_reg_wren2 := false.B
sb_abmem_cmd_done_in := false.B
sb_abmem_data_done_in := false.B
sb_abmem_cmd_done_en := false.B
sb_abmem_data_done_en := false.B
dbg_nxtstate := state_t.idle
dbg_state_en := false.B
abstractcs_busy_wren := false.B
abstractcs_busy_din := false.B
io.dbg_halt_req := false.B
io.dbg_resume_req := false.B
switch(dbg_state) {
is(state_t.idle) {
dbg_nxtstate := Mux(dmstatus_reg(9) | io.dec_tlu_mpc_halted_only, state_t.halted, state_t.halting)
dbg_state_en := ((dmcontrol_reg(31) | dmstatus_reg(9) | io.dec_tlu_mpc_halted_only))
io.dbg_halt_req := dmcontrol_reg(31).asBool()
dbg_nxtstate := Mux(dmstatus_reg(9) | io.dec_tlu_mpc_halted_only, state_t.halted, state_t.halting)
dbg_state_en := ((dmcontrol_reg(31) & !io.dec_tlu_debug_mode) | dmstatus_reg(9) | io.dec_tlu_mpc_halted_only) & !dmcontrol_reg(1)
io.dbg_halt_req := (dmcontrol_reg(31) & !dmcontrol_reg(1)).asBool()
}
is(state_t.halting) {
dbg_nxtstate := state_t.halted
dbg_state_en := dmstatus_reg(9) | io.dec_tlu_mpc_halted_only
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
dbg_nxtstate := Mux(dmcontrol_reg(1), state_t.idle, state_t.halted)
dbg_state_en := dmstatus_reg(9) | dmcontrol_reg(1)
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31) & (~dmcontrol_reg(1)).asUInt()).asBool()
}
is(state_t.halted) {
dbg_nxtstate := Mux(dmstatus_reg(9), Mux(resumereq, state_t.resuming, Mux((command_reg(31, 24) === 2.U(8.W)) & abmem_addr_external,
state_t.sb_cmd_start, state_t.core_cmd_start)), Mux(dmcontrol_reg(31), state_t.halting, state_t.idle)) // This is MPC halted case
dbg_state_en := dmstatus_reg(9) & resumereq | execute_command | !(dmstatus_reg(9) | io.dec_tlu_mpc_halted_only)
abstractcs_busy_wren := dbg_state_en & ((dbg_nxtstate === state_t.core_cmd_start) | (dbg_nxtstate === state_t.sb_cmd_start))
abstractcs_busy_din := "b1".U
io.dbg_resume_req := (dbg_state_en & (dbg_nxtstate === state_t.resuming)).asBool()
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
dbg_nxtstate := Mux(dmstatus_reg(9) & !dmcontrol_reg(1),
Mux(dmcontrol_reg(30) & !dmcontrol_reg(31), state_t.resuming, state_t.cmd_start),
Mux(dmcontrol_reg(31), state_t.halting, state_t.idle))
dbg_state_en := dmstatus_reg(9) & dmcontrol_reg(30) & !dmcontrol_reg(31) & dmcontrol_wren_Q | command_wren |
dmcontrol_reg(1) | !(dmstatus_reg(9) | io.dec_tlu_mpc_halted_only)
abstractcs_busy_wren := dbg_state_en & (dbg_nxtstate === state_t.cmd_start)
abstractcs_busy_din := "b1".U
io.dbg_resume_req := (dbg_state_en & (dbg_nxtstate === state_t.resuming)).asBool()
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31) & (~dmcontrol_reg(1)).asUInt()).asBool()
}
is(state_t.core_cmd_start) {
dbg_nxtstate := Mux(abstractcs_reg(10, 8).orR | ((command_reg(31, 24) === 0.U(8.W)) & !command_reg(17)), state_t.cmd_done, state_t.core_cmd_wait)
dbg_state_en := io.dbg_dec_dma.dbg_ib.dbg_cmd_valid | abstractcs_reg(10, 8).orR | ((command_reg(31, 24) === 0.U(8.W)) & !command_reg(17))
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
is(state_t.cmd_start) {
dbg_nxtstate := Mux(dmcontrol_reg(1), state_t.idle, Mux(abstractcs_reg(10, 8).orR, state_t.cmd_done, state_t.cmd_wait))
dbg_state_en := io.dbg_dec_dma.dbg_ib.dbg_cmd_valid | abstractcs_reg(10, 8).orR | dmcontrol_reg(1)
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31) & (~dmcontrol_reg(1)).asUInt()).asBool()
}
is(state_t.core_cmd_wait) {
dbg_nxtstate := state_t.cmd_done
dbg_state_en := io.core_dbg_cmd_done
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
}
is(state_t.sb_cmd_start) {
dbg_nxtstate := Mux(abstractcs_reg(10, 8).orR, state_t.cmd_done, state_t.sb_cmd_send)
dbg_state_en := (io.dbg_bus_clk_en & !sb_cmd_pending) | abstractcs_reg(10, 8).orR
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
}
is(state_t.sb_cmd_send) {
sb_abmem_cmd_done_in := true.B
sb_abmem_data_done_in := true.B
sb_abmem_cmd_done_en := (sb_bus_cmd_read | sb_bus_cmd_write_addr) & io.dbg_bus_clk_en
sb_abmem_data_done_en := (sb_bus_cmd_read | sb_bus_cmd_write_data) & io.dbg_bus_clk_en
dbg_nxtstate := state_t.sb_cmd_resp
dbg_state_en := (sb_abmem_cmd_done | sb_abmem_cmd_done_en) & (sb_abmem_data_done | sb_abmem_data_done_en) & io.dbg_bus_clk_en
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
}
is(state_t.sb_cmd_resp) {
dbg_nxtstate := state_t.cmd_done
dbg_state_en := (sb_bus_rsp_read | sb_bus_rsp_write) & io.dbg_bus_clk_en
dbg_sb_bus_error := (sb_bus_rsp_read | sb_bus_rsp_write) & sb_bus_rsp_error & io.dbg_bus_clk_en
data0_reg_wren2 := dbg_state_en & !sb_abmem_cmd_write & !dbg_sb_bus_error
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
is(state_t.cmd_wait) {
dbg_nxtstate := Mux(dmcontrol_reg(1), state_t.idle, state_t.cmd_done)
dbg_state_en := io.core_dbg_cmd_done | dmcontrol_reg(1)
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31) & (~dmcontrol_reg(1)).asUInt()).asBool()
}
is(state_t.cmd_done) {
dbg_nxtstate := state_t.halted
dbg_state_en := true.B
abstractcs_busy_wren := dbg_state_en
abstractcs_busy_din := false.B
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
sb_abmem_cmd_done_in := false.B
sb_abmem_data_done_in := false.B
sb_abmem_cmd_done_en := true.B
sb_abmem_data_done_en := true.B
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
dbg_nxtstate := Mux(dmcontrol_reg(1), state_t.idle, state_t.halted)
dbg_state_en := true.B
abstractcs_busy_wren := dbg_state_en
abstractcs_busy_din := "b0".U
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31) & (~dmcontrol_reg(1)).asUInt()).asBool()
}
is(state_t.resuming) {
dbg_nxtstate := state_t.idle;
dbg_state_en := dmstatus_reg(17)
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
dbg_state_en := dmstatus_reg(17) | dmcontrol_reg(1)
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31) & (~dmcontrol_reg(1)).asUInt()).asBool()
}}
val dmi_reg_rdata_din = Fill(32, io.dmi_reg_addr === "h4".U(7.W)).asUInt & data0_reg |
Fill(32, io.dmi_reg_addr === "h5".U(7.W)) & data1_reg |
Fill(32, io.dmi_reg_addr === "h10".U(7.W)) & Cat(0.U(2.W), dmcontrol_reg(29), 0.U, dmcontrol_reg(27,0)) |
Fill(32, io.dmi_reg_addr === "h11".U(7.W)) & dmstatus_reg |
Fill(32, io.dmi_reg_addr === "h16".U(7.W)) & abstractcs_reg |
Fill(32, io.dmi_reg_addr === "h17".U(7.W)) & command_reg |
Fill(32, io.dmi_reg_addr === "h18".U(7.W)) & Cat(0.U(30.W), abstractauto_reg(1,0)) |
Fill(32, io.dmi_reg_addr === "h40".U(7.W)) & haltsum0_reg |
Fill(32, io.dmi_reg_addr === "h38".U(7.W)) & sbcs_reg |
Fill(32, io.dmi_reg_addr === "h39".U(7.W)) & sbaddress0_reg |
Fill(32, io.dmi_reg_addr === "h3c".U(7.W)) & sbdata0_reg |
Fill(32, io.dmi_reg_addr === "h3d".U(7.W)) & sbdata1_reg
val dmi_reg_rdata_din = Fill(32, io.dmi_reg_addr === "h4".U).asUInt & data0_reg | Fill(32, io.dmi_reg_addr === "h5".U) & data1_reg |
Fill(32, io.dmi_reg_addr === "h10".U) & dmcontrol_reg | Fill(32, io.dmi_reg_addr === "h11".U) & dmstatus_reg |
Fill(32, io.dmi_reg_addr === "h16".U) & abstractcs_reg | Fill(32, io.dmi_reg_addr === "h17".U) & command_reg |
Fill(32, io.dmi_reg_addr === "h40".U) & haltsum0_reg | Fill(32, io.dmi_reg_addr === "h38".U) & sbcs_reg |
Fill(32, io.dmi_reg_addr === "h39".U) & sbaddress0_reg | Fill(32, io.dmi_reg_addr === "h3c".U) & sbdata0_reg |
Fill(32, io.dmi_reg_addr === "h3d".U) & sbdata1_reg
dbg_state := withClockAndReset(dbg_free_clk, (dbg_dm_rst_l.asBool() & temp_rst).asAsyncReset()) {
RegEnable(dbg_nxtstate, 0.U, dbg_state_en)} // dbg_state_reg
dbg_state := withClockAndReset(dbg_free_clk, rst_temp) {
RegEnable(dbg_nxtstate, 0.U, dbg_state_en)
} // dbg_state_reg
io.dmi_reg_rdata := withReset(dbg_dm_rst_l) {
rvdffe(dmi_reg_rdata_din, io.dmi_reg_en, clock, io.scan_mode)} // dmi_rddata_reg
val abmem_addr = data1_reg
val abmem_addr_core_local = (abmem_addr_in_dccm_region | abmem_addr_in_iccm_region | abmem_addr_in_pic_region)
abmem_addr_external := !abmem_addr_core_local
io.dmi_reg_rdata := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegEnable(dmi_reg_rdata_din, 0.U, io.dmi_reg_en)
} // dmi_rddata_reg
abmem_addr_in_dccm_region := (abmem_addr(31,28) === DCCM_REGION.asUInt) & (DCCM_ENABLE==1).B
abmem_addr_in_iccm_region := (abmem_addr(31,28) === ICCM_REGION.asUInt) & (ICCM_ENABLE==1).B
abmem_addr_in_pic_region := (abmem_addr(31,28) === PIC_REGION.asUInt)
io.dbg_dec_dma.dbg_ib.dbg_cmd_addr := Mux((command_reg(31, 24) === "h2".U), data1_reg, Cat(0.U(20.W), command_reg(11, 0)))
io.dbg_dec_dma.dbg_ib.dbg_cmd_addr := Mux((command_reg(31, 24) === "h2".U), Cat(data1_reg(31, 2), "b00".U(2.W)), Cat(0.U(20.W), command_reg(11, 0)))
io.dbg_dec_dma.dbg_dctl.dbg_cmd_wrdata := data0_reg(31, 0)
io.dbg_dec_dma.dbg_ib.dbg_cmd_valid := (dbg_state === state_t.core_cmd_start) & !((abstractcs_reg(10,8).orR) | ((command_reg(31,24) === 0.U(8.W)) & !command_reg(17)) |
((command_reg(31,24) === 2.U(8.W)) & abmem_addr_external)) & io.dbg_dma.dma_dbg_ready
io.dbg_dec_dma.dbg_ib.dbg_cmd_write := command_reg(16).asBool()
io.dbg_dec_dma.dbg_ib.dbg_cmd_type := Mux((command_reg(31, 24) === "h2".U), "b10".U, Cat("b0".U, (command_reg(15, 12) === "b0".U)))
io.dbg_cmd_size := command_reg(21, 20)
val dbg_cmd_addr_incr = Mux((command_reg(31,24) === 2.U(8.W)), (1.U(4.W) << sb_abmem_cmd_size(1,0)), 1.U(4.W))
val dbg_cmd_curr_addr = Mux((command_reg(31,24) === 2.U(8.W)), data1_reg, Cat(0.U(16.W), command_reg(15,0)))
dbg_cmd_next_addr := dbg_cmd_curr_addr + Cat(0.U(28.W), dbg_cmd_addr_incr)
io.dbg_dma.dbg_dma_bubble := ((dbg_state === state_t.core_cmd_start) & ~(abstractcs_reg(10, 8).orR) | (dbg_state === state_t.core_cmd_wait)).asBool()
sb_cmd_pending := (sb_state === sb_state_t.cmd_rd) | (sb_state === sb_state_t.cmd_wr) | (sb_state === sb_state_t.cmd_wr_addr) |
(sb_state === sb_state_t.cmd_wr_data) | (sb_state === sb_state_t.rsp_rd) | (sb_state === sb_state_t.rsp_wr)
val sb_abmem_cmd_pending = (dbg_state === state_t.sb_cmd_start) | (dbg_state === state_t.sb_cmd_send) | (dbg_state === state_t.sb_cmd_resp)
io.dbg_dec_dma.dbg_ib.dbg_cmd_valid := ((dbg_state === state_t.cmd_start) & !(abstractcs_reg(10, 8).orR) & io.dbg_dma.dma_dbg_ready).asBool()
io.dbg_dec_dma.dbg_ib.dbg_cmd_write := command_reg(16).asBool()
io.dbg_dec_dma.dbg_ib.dbg_cmd_type := Mux((command_reg(31, 24) === "h2".U), "b10".U(2.W), Cat("b0".U, (command_reg(15, 12) === "b0".U)))
io.dbg_cmd_size := command_reg(21, 20)
io.dbg_dma.dbg_dma_bubble := ((dbg_state === state_t.cmd_start) & !(abstractcs_reg(10, 8).orR) | (dbg_state === state_t.cmd_wait)).asBool()
val sb_nxtstate = WireInit(sb_state_t.sbidle)
sb_nxtstate := sb_state_t.sbidle
@ -425,31 +345,30 @@ class dbg extends Module with lib with RequireAsyncReset {
switch(sb_state) {
is(sb_state_t.sbidle) {
sb_nxtstate := Mux(sbdata0wr_access, sb_state_t.wait_wr, sb_state_t.wait_rd)
sb_state_en := (sbdata0wr_access | sbreadondata_access | sbreadonaddr_access) & ~(sbcs_reg(14,12).orR) & !sbcs_reg(22)
sb_state_en := sbdata0wr_access | sbreadondata_access | sbreadonaddr_access
sbcs_sbbusy_wren := sb_state_en
sbcs_sbbusy_din := true.B
sbcs_sberror_wren := sbcs_wren & io.dmi_reg_wdata(14, 12).orR
sbcs_sberror_din := ~io.dmi_reg_wdata(14, 12) & sbcs_reg(14, 12)
}
is(sb_state_t.wait_rd) {
sb_nxtstate := Mux(sbcs_unaligned | sbcs_illegal_size, sb_state_t.done, sb_state_t.cmd_rd)
sb_state_en := (io.dbg_bus_clk_en & !sb_abmem_cmd_pending) | sbcs_unaligned | sbcs_illegal_size
sb_nxtstate := Mux(sbcs_unaligned | sbcs_illegal_size, sb_state_t.done, sb_state_t.cmd_rd)
sb_state_en := io.dbg_bus_clk_en | sbcs_unaligned | sbcs_illegal_size
sbcs_sberror_wren := sbcs_unaligned | sbcs_illegal_size
sbcs_sberror_din := Mux(sbcs_unaligned, "b011".U(3.W), "b100".U(3.W))
sbcs_sberror_din := Mux(sbcs_unaligned, "b011".U(3.W), "b100".U(3.W))
}
is(sb_state_t.wait_wr) {
sb_nxtstate := Mux(sbcs_unaligned | sbcs_illegal_size, sb_state_t.done, sb_state_t.cmd_wr)
sb_state_en := (io.dbg_bus_clk_en & !sb_abmem_cmd_pending) | sbcs_unaligned | sbcs_illegal_size
sb_nxtstate := Mux(sbcs_unaligned | sbcs_illegal_size, sb_state_t.done, sb_state_t.cmd_wr)
sb_state_en := io.dbg_bus_clk_en | sbcs_unaligned | sbcs_illegal_size
sbcs_sberror_wren := sbcs_unaligned | sbcs_illegal_size;
sbcs_sberror_din := Mux(sbcs_unaligned, "b011".U(3.W), "b100".U(3.W))
sbcs_sberror_din := Mux(sbcs_unaligned, "b011".U(3.W), "b100".U)
}
is(sb_state_t.cmd_rd) {
sb_nxtstate := sb_state_t.rsp_rd
sb_state_en := sb_bus_cmd_read & io.dbg_bus_clk_en
}
is(sb_state_t.cmd_wr) {
sb_nxtstate := Mux(sb_bus_cmd_write_addr & sb_bus_cmd_write_data, sb_state_t.rsp_wr,
Mux(sb_bus_cmd_write_data, sb_state_t.cmd_wr_addr, sb_state_t.cmd_wr_data))
sb_nxtstate := Mux(sb_bus_cmd_write_addr & sb_bus_cmd_write_data, sb_state_t.rsp_wr, Mux(sb_bus_cmd_write_data, sb_state_t.cmd_wr_addr, sb_state_t.cmd_wr_data))
sb_state_en := (sb_bus_cmd_write_addr | sb_bus_cmd_write_data) & io.dbg_bus_clk_en
}
is(sb_state_t.cmd_wr_addr) {
@ -477,88 +396,64 @@ class dbg extends Module with lib with RequireAsyncReset {
sb_state_en := true.B
sbcs_sbbusy_wren := true.B
sbcs_sbbusy_din := false.B
sbaddress0_reg_wren1 := sbcs_reg(16) & (sbcs_reg(14,12) === 0.U(3.W))
sbaddress0_reg_wren1 := sbcs_reg(16)
}}
sb_state := withClockAndReset(sb_free_clk, dbg_dm_rst_l.asAsyncReset()) {
sb_state := withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
RegEnable(sb_nxtstate, 0.U, sb_state_en)
} // sb_state_reg
sb_abmem_cmd_write := command_reg(16)
sb_abmem_cmd_size := Cat(0.U(1.W), command_reg(21,20))
val sb_abmem_cmd_addr = abmem_addr
val sb_abmem_cmd_wdata = data0_reg
val sb_cmd_size = sbcs_reg(19,17)
val sb_cmd_wdata = Cat(sbdata1_reg(31,0), sbdata0_reg(31,0))
val sb_cmd_addr = sbaddress0_reg(31,0)
val sb_abmem_cmd_awvalid = (dbg_state === state_t.sb_cmd_send) & sb_abmem_cmd_write & !sb_abmem_cmd_done
val sb_abmem_cmd_wvalid = (dbg_state === state_t.sb_cmd_send) & sb_abmem_cmd_write & !sb_abmem_data_done
val sb_abmem_cmd_arvalid = (dbg_state === state_t.sb_cmd_send) & !sb_abmem_cmd_write & !sb_abmem_cmd_done & !sb_abmem_data_done
val sb_abmem_read_pend = (dbg_state === state_t.sb_cmd_resp) & !sb_abmem_cmd_write
val sb_cmd_awvalid = ((sb_state === sb_state_t.cmd_wr) | (sb_state === sb_state_t.cmd_wr_addr))
val sb_cmd_wvalid = ((sb_state === sb_state_t.cmd_wr) | (sb_state === sb_state_t.cmd_wr_data))
val sb_cmd_arvalid = (sb_state === sb_state_t.cmd_rd)
val sb_read_pend = (sb_state === sb_state_t.cmd_rd)
val sb_axi_size = Mux((sb_abmem_cmd_awvalid | sb_abmem_cmd_wvalid | sb_abmem_cmd_arvalid | sb_abmem_read_pend), sb_abmem_cmd_size(2,0), sb_cmd_size(2,0))
val sb_axi_addr = Mux((sb_abmem_cmd_awvalid | sb_abmem_cmd_wvalid | sb_abmem_cmd_arvalid | sb_abmem_read_pend), sb_abmem_cmd_addr(31,0), sb_cmd_addr(31,0))
val sb_axi_wrdata = Mux((sb_abmem_cmd_awvalid | sb_abmem_cmd_wvalid), Fill(2, sb_abmem_cmd_wdata(31,0)), sb_cmd_wdata(63,0))
sb_bus_cmd_read := io.sb_axi.ar.valid & io.sb_axi.ar.ready
sb_bus_cmd_read := io.sb_axi.ar.valid & io.sb_axi.ar.ready
sb_bus_cmd_write_addr := io.sb_axi.aw.valid & io.sb_axi.aw.ready
sb_bus_cmd_write_data := io.sb_axi.w.valid & io.sb_axi.w.ready
sb_bus_rsp_read := io.sb_axi.r.valid & io.sb_axi.r.ready
sb_bus_rsp_write := io.sb_axi.b.valid & io.sb_axi.b.ready
sb_bus_rsp_error := sb_bus_rsp_read & io.sb_axi.r.bits.resp(1, 0).orR | sb_bus_rsp_write & io.sb_axi.b.bits.resp(1, 0).orR
sb_bus_rsp_read := io.sb_axi.r.valid & io.sb_axi.r.ready
sb_bus_rsp_write := io.sb_axi.b.valid & io.sb_axi.b.ready
sb_bus_rsp_error := sb_bus_rsp_read & io.sb_axi.r.bits.resp(1, 0).orR | sb_bus_rsp_write & io.sb_axi.b.bits.resp(1, 0).orR
io.sb_axi.aw.valid := ((sb_state === sb_state_t.cmd_wr) | (sb_state === sb_state_t.cmd_wr_addr)).asBool()
io.sb_axi.aw.bits.addr := sbaddress0_reg
io.sb_axi.aw.bits.id := 0.U
io.sb_axi.aw.bits.size := sbcs_reg(19, 17)
io.sb_axi.aw.bits.prot := 0.U
io.sb_axi.aw.bits.cache := "b1111".U
io.sb_axi.aw.bits.region := sbaddress0_reg(31, 28)
io.sb_axi.aw.bits.len := 0.U
io.sb_axi.aw.bits.burst := "b01".U(2.W)
io.sb_axi.aw.bits.qos := 0.U
io.sb_axi.aw.bits.lock := false.B
io.sb_axi.w.valid := ((sb_state === sb_state_t.cmd_wr) | (sb_state === sb_state_t.cmd_wr_data)).asBool()
io.sb_axi.w.bits.data := Fill(64, (sbcs_reg(19, 17) === 0.U)) & Fill(8, (sbdata0_reg(7, 0))) | Fill(64, (sbcs_reg(19, 17) === "h1".U)) & Fill(4, sbdata0_reg(15, 0)) |
Fill(64, (sbcs_reg(19, 17) === "h2".U)) & Fill(2, (sbdata0_reg(31, 0))) | Fill(64, (sbcs_reg(19, 17) === "h3".U)) & Cat(sbdata1_reg(31, 0), sbdata0_reg(31, 0))
io.sb_axi.aw.valid := sb_abmem_cmd_awvalid | sb_cmd_awvalid
io.sb_axi.aw.bits.addr := sb_axi_addr
io.sb_axi.aw.bits.id := 0.U
io.sb_axi.aw.bits.size := sb_axi_size
io.sb_axi.aw.bits.prot := 1.U(3.W)
io.sb_axi.aw.bits.cache := "b1111".U(4.W)
io.sb_axi.aw.bits.region := sb_axi_addr(31, 28)
io.sb_axi.aw.bits.len := 0.U
io.sb_axi.aw.bits.burst := "b01".U(2.W)
io.sb_axi.aw.bits.qos := 0.U
io.sb_axi.aw.bits.lock := false.B
io.sb_axi.w.valid := sb_abmem_cmd_wvalid | sb_cmd_wvalid
io.sb_axi.w.bits.data := Fill(64, (sb_axi_size === 0.U(3.W))) & Fill(8, (sb_axi_wrdata(7, 0))) |
Fill(64, (sb_axi_size === 1.U(3.W))) & Fill(4, sb_axi_wrdata(15, 0)) |
Fill(64, (sb_axi_size === 2.U(3.W))) & Fill(2, (sb_axi_wrdata(31, 0))) |
Fill(64, (sb_axi_size === 3.U(3.W))) & sb_axi_wrdata
io.sb_axi.w.bits.strb := Fill(8, (sb_axi_size === 0.U(3.W))) & ("h1".U(8.W) << sb_axi_addr(2, 0)) |
Fill(8, (sb_axi_size === 1.U(3.W))) & ("h3".U(8.W) << Cat(sb_axi_addr(2, 1), 0.U(1.W))) |
Fill(8, (sb_axi_size === 2.U(3.W))) & ("hf".U(8.W) << Cat(sb_axi_addr(2), 0.U(2.W))) |
Fill(8, (sb_axi_size === 3.U(3.W))) & "hff".U(8.W)
io.sb_axi.w.bits.last := true.B
io.sb_axi.ar.valid := sb_abmem_cmd_arvalid | sb_cmd_arvalid
io.sb_axi.ar.bits.addr := sb_axi_addr
io.sb_axi.ar.bits.id := 0.U
io.sb_axi.ar.bits.size := sb_axi_size
io.sb_axi.ar.bits.prot := 1.U(3.W)
io.sb_axi.ar.bits.cache := 0.U(4.W)
io.sb_axi.ar.bits.region := sb_axi_addr(31, 28)
io.sb_axi.ar.bits.len := 0.U
io.sb_axi.ar.bits.burst := 1.U(2.W)
io.sb_axi.ar.bits.qos := 0.U
io.sb_axi.ar.bits.lock := false.B
io.sb_axi.w.bits.strb := Fill(8, (sbcs_reg(19, 17) === "h0".U)) & ("h1".U(8.W) << sbaddress0_reg(2, 0)) |
Fill(8, (sbcs_reg(19, 17) === "h1".U)) & ("h3".U(8.W) << Cat(sbaddress0_reg(2, 1), "b0".U)) |
Fill(8, (sbcs_reg(19, 17) === "h2".U)) & ("hf".U(8.W) << Cat(sbaddress0_reg(2), "b00".U(2.W))) |
Fill(8, (sbcs_reg(19, 17) === "h3".U)) & "hff".U
io.sb_axi.w.bits.last := true.B
io.sb_axi.ar.valid := (sb_state === sb_state_t.cmd_rd).asBool()
io.sb_axi.ar.bits.addr := sbaddress0_reg
io.sb_axi.ar.bits.id := 0.U
io.sb_axi.ar.bits.size := sbcs_reg(19, 17)
io.sb_axi.ar.bits.prot := 0.U
io.sb_axi.ar.bits.cache := 0.U
io.sb_axi.ar.bits.region := sbaddress0_reg(31, 28)
io.sb_axi.ar.bits.len := 0.U
io.sb_axi.ar.bits.burst := "b01".U(2.W)
io.sb_axi.ar.bits.qos := 0.U
io.sb_axi.ar.bits.lock := false.B
io.sb_axi.b.ready := true.B
io.sb_axi.r.ready := true.B
sb_bus_rdata := Fill(64, (sbcs_reg(19, 17) === "h0".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 8.U * sbaddress0_reg(2, 0)) & "hff".U(64.W)) |
Fill(64, (sbcs_reg(19, 17) === "h1".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 16.U * sbaddress0_reg(2, 1)) & "hffff".U(64.W)) |
Fill(64, (sbcs_reg(19, 17) === "h2".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 32.U * sbaddress0_reg(2)) & "hffff_ffff".U(64.W)) |
Fill(64, (sbcs_reg(19, 17) === "h3".U)) & io.sb_axi.r.bits.data(63, 0)
sb_bus_rdata := Fill(64, (sb_axi_size === "h0".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 8.U * sb_axi_addr(2, 0)) & "hff".U(64.W)) |
Fill(64, (sb_axi_size === "h1".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 16.U * sb_axi_addr(2, 1)) & "hffff".U(64.W)) |
Fill(64, (sb_axi_size === "h2".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 32.U * sb_axi_addr(2)) & "hffff_ffff".U(64.W)) |
Fill(64, (sb_axi_size === "h3".U)) & io.sb_axi.r.bits.data(63, 0)
// io.dbg_dma.dbg_ib.dbg_cmd_addr := io.dbg_dec_dma.dbg_ib.dbg_cmd_addr
// io.dbg_dma.dbg_dctl.dbg_cmd_wrdata := io.dbg_dec_dma.dbg_dctl.dbg_cmd_wrdata
// io.dbg_dma.dbg_ib.dbg_cmd_valid := io.dbg_dec_dma.dbg_ib.dbg_cmd_valid
// io.dbg_dma.dbg_ib.dbg_cmd_write := io.dbg_dec_dma.dbg_ib.dbg_cmd_write
// io.dbg_dma.dbg_ib.dbg_cmd_type := io.dbg_dec_dma.dbg_ib.dbg_cmd_type
}
object debug extends App {
(new chisel3.stage.ChiselStage).emitVerilog(new dbg)
}

View File

@ -8,16 +8,12 @@ import lsu._
class dec_IO extends Bundle with lib {
val free_clk = Input(Clock())
val active_clk = Input(Clock())
val free_l2clk = Input(Clock())
val lsu_fastint_stall_any = Input(Bool()) // needed by lsu for 2nd pass of dma with ecc correction, stall next cycle
val dec_pause_state_cg = Output(Bool()) // to top for active state clock gating
val dec_tlu_core_empty = Output(Bool())
val rst_vec = Input(UInt(31.W)) // [31:1] reset vector, from core pins
val ifu_i0_fa_index = Input(UInt(log2Ceil(BTB_SIZE).W))
val dec_fa_error_index = Output(UInt(log2Ceil(BTB_SIZE).W))
val nmi_int = Input(Bool()) // NMI pin
val nmi_vec = Input(UInt(31.W)) // [31:1] NMI vector, from pins
val lsu_nonblock_load_data = Input(UInt(32.W))
val i_cpu_halt_req = Input(Bool()) // Asynchronous Halt request to CPU
val i_cpu_run_req = Input(Bool()) // Asynchronous Restart request to CPU
@ -70,7 +66,6 @@ class dec_IO extends Bundle with lib {
val dec_tlu_resume_ack = Output(Bool()) // Resume acknowledge
val dec_tlu_mpc_halted_only = Output(Bool()) // Core is halted only due to MPC
val dec_dbg_rddata = Output(UInt(32.W)) // debug command read data
val dec_csr_rddata_d = Output(UInt(32.W))
val dec_dbg_cmd_done = Output(Bool()) // abstract command is done
val dec_dbg_cmd_fail = Output(Bool()) // abstract command failed (illegal reg address)
@ -84,9 +79,8 @@ class dec_IO extends Bundle with lib {
val dec_tlu_perfcnt1 = Output(Bool()) // toggles when slot0 perf counter 1 has an event inc
val dec_tlu_perfcnt2 = Output(Bool()) // toggles when slot0 perf counter 2 has an event inc
val dec_tlu_perfcnt3 = Output(Bool()) // toggles when slot0 perf counter 3 has an event inc
val dec_tlu_flush_lower_wb = Output(Bool())
val dec_lsu_valid_raw_d = Output(Bool())
val trace_rv_trace_pkt = Output(new trace_pkt_t) // trace packet
val rv_trace_pkt = (new trace_pkt_t) // trace packet
// clock gating overrides from mcgc
val dec_tlu_misc_clk_override = Output(Bool()) // override misc clock domain gating
@ -94,12 +88,9 @@ class dec_IO extends Bundle with lib {
val dec_tlu_lsu_clk_override = Output(Bool()) // override load/store clock domain gating
val dec_tlu_bus_clk_override = Output(Bool()) // override bus clock domain gating
val dec_tlu_pic_clk_override = Output(Bool()) // override PIC clock domain gating
val dec_tlu_picio_clk_override = Output(Bool())
val dec_tlu_dccm_clk_override = Output(Bool()) // override DCCM clock domain gating
val dec_tlu_icm_clk_override = Output(Bool()) // override ICCM clock domain gating
val dec_i0_decode_d = Output(Bool())
val scan_mode = Input(Bool())
val ifu_dec = Flipped(new ifu_dec)
val dec_exu = Flipped(new dec_exu)
@ -120,10 +111,6 @@ class dec extends Module with param with RequireAsyncReset{
val dec_tlu_exc_cause_wb1 = WireInit(UInt(5.W),0.U)
val dec_tlu_mtval_wb1 = WireInit(UInt(32.W),0.U)
val dec_tlu_i0_exc_valid_wb1 = WireInit(Bool(),0.B)
val dec_tlu_trace_disable = WireInit(Bool(),0.B)
// val dec_i0_bp_fa_index = WireInit(UInt(log2Ceil(BTB_SIZE).W),0.U)
//val dec_debug_valid_d = WireInit(Bool(),0.B)
//--------------------------------------------------------------------------//
@ -138,20 +125,17 @@ class dec extends Module with param with RequireAsyncReset{
instbuff.io.ifu_ib <> io.ifu_dec.dec_aln.aln_ib
instbuff.io.ib_exu <> io.dec_exu.ib_exu
instbuff.io.dbg_ib <> io.dec_dbg.dbg_ib
instbuff.io.ifu_i0_fa_index := io.ifu_i0_fa_index
dec_trigger.io.dec_i0_pc_d := instbuff.io.ib_exu.dec_i0_pc_d
dec_trigger.io.trigger_pkt_any := tlu.io.trigger_pkt_any
val dec_i0_trigger_match_d = dec_trigger.io.dec_i0_trigger_match_d
dontTouch(dec_i0_trigger_match_d)
decode.io.dec_aln <> io.ifu_dec.dec_aln.aln_dec
io.dec_i0_decode_d := decode.io.dec_i0_decode_d
decode.io.decode_exu<> io.dec_exu.decode_exu
decode.io.dec_alu<> io.dec_exu.dec_alu
decode.io.dec_div<> io.dec_exu.dec_div
decode.io.dctl_dma <> io.dec_dma.dctl_dma
decode.io.dec_tlu_trace_disable := tlu.io.dec_tlu_trace_disable
decode.io.dec_debug_valid_d := instbuff.io.dec_debug_valid_d
decode.io.dec_tlu_flush_extint := tlu.io.dec_tlu_flush_extint
decode.io.dec_tlu_force_halt := tlu.io.tlu_mem.dec_tlu_force_halt
decode.io.dctl_busbuff <> io.lsu_dec.dctl_busbuff
@ -161,18 +145,18 @@ class dec extends Module with param with RequireAsyncReset{
decode.io.lsu_trigger_match_m := io.lsu_trigger_match_m
decode.io.lsu_pmu_misaligned_m := io.lsu_pmu_misaligned_m
decode.io.dec_tlu_debug_stall := tlu.io.dec_tlu_debug_stall
decode.io.dec_i0_bp_fa_index := instbuff.io.dec_i0_bp_fa_index
decode.io.dec_tlu_flush_leak_one_r := tlu.io.tlu_bp.dec_tlu_flush_leak_one_wb
decode.io.dec_debug_fence_d := instbuff.io.dec_debug_fence_d
decode.io.dbg_dctl <> io.dec_dbg.dbg_dctl
decode.io.dec_i0_icaf_d := instbuff.io.dec_i0_icaf_d
decode.io.dec_i0_icaf_second_d := instbuff.io.dec_i0_icaf_second_d
decode.io.dec_i0_icaf_f1_d := instbuff.io.dec_i0_icaf_f1_d
decode.io.dec_i0_icaf_type_d := instbuff.io.dec_i0_icaf_type_d
decode.io.dec_i0_dbecc_d := instbuff.io.dec_i0_dbecc_d
decode.io.dec_i0_brp := instbuff.io.dec_i0_brp
decode.io.dec_i0_bp_index := instbuff.io.dec_i0_bp_index
decode.io.dec_i0_bp_fghr := instbuff.io.dec_i0_bp_fghr
decode.io.dec_i0_bp_btag := instbuff.io.dec_i0_bp_btag
decode.io.dec_i0_pc_d := instbuff.io.ib_exu.dec_i0_pc_d
decode.io.lsu_idle_any := io.lsu_idle_any
decode.io.lsu_load_stall_any := io.lsu_load_stall_any
decode.io.lsu_store_stall_any := io.lsu_store_stall_any
@ -192,19 +176,16 @@ class dec extends Module with param with RequireAsyncReset{
decode.io.exu_flush_final := io.exu_flush_final
decode.io.dec_i0_instr_d := instbuff.io.dec_i0_instr_d
decode.io.dec_ib0_valid_d := instbuff.io.dec_ib0_valid_d
decode.io.free_l2clk := io.free_l2clk
decode.io.free_clk := io.free_clk
decode.io.active_clk := io.active_clk
decode.io.clk_override := tlu.io.dec_tlu_dec_clk_override
decode.io.scan_mode := io.scan_mode
dec_i0_inst_wb1 := decode.io.dec_i0_inst_wb //for tracer
dec_i0_pc_wb1 := decode.io.dec_i0_pc_wb //for tracer
io.lsu_p := decode.io.lsu_p
io.dec_lsu_valid_raw_d := decode.io.dec_lsu_valid_raw_d
io.dec_lsu_offset_d := decode.io.dec_lsu_offset_d
io.dec_pause_state_cg := decode.io.dec_pause_state_cg
io.dec_exu.decode_exu.dec_qual_lsu_d := decode.io.decode_exu.dec_qual_lsu_d
io.dec_fa_error_index :=decode.io.dec_fa_error_index
dec_i0_inst_wb1 := decode.io.dec_i0_inst_wb1 //for tracer
dec_i0_pc_wb1 := decode.io.dec_i0_pc_wb1 //for tracer
io.lsu_p := decode.io.lsu_p
io.dec_lsu_valid_raw_d := decode.io.dec_lsu_valid_raw_d
io.dec_lsu_offset_d := decode.io.dec_lsu_offset_d
io.dec_pause_state_cg := decode.io.dec_pause_state_cg
gpr.io.raddr0 := decode.io.dec_i0_rs1_d
gpr.io.raddr1 := decode.io.dec_i0_rs2_d
gpr.io.wen0 := decode.io.dec_i0_wen_r
@ -212,19 +193,18 @@ class dec extends Module with param with RequireAsyncReset{
gpr.io.wd0 := decode.io.dec_i0_wdata_r
gpr.io.wen1 := decode.io.dec_nonblock_load_wen
gpr.io.waddr1 := decode.io.dec_nonblock_load_waddr
gpr.io.wd1 := io.lsu_nonblock_load_data
gpr.io.wd1 := io.lsu_dec.dctl_busbuff.lsu_nonblock_load_data
gpr.io.wen2 := io.exu_div_wren
gpr.io.waddr2 := decode.io.div_waddr_wb
gpr.io.wd2 := io.exu_div_result
gpr.io.scan_mode := io.scan_mode
io.dec_exu.gpr_exu <> gpr.io.gpr_exu
tlu.io.tlu_mem <> io.ifu_dec.dec_mem_ctrl
tlu.io.tlu_ifc <> io.ifu_dec.dec_ifc
tlu.io.tlu_bp <> io.ifu_dec.dec_bp
tlu.io.tlu_exu <> io.dec_exu.tlu_exu
tlu.io.tlu_dma <> io.dec_dma.tlu_dma
tlu.io.free_l2clk := io.free_l2clk
tlu.io.active_clk := io.active_clk
tlu.io.free_clk := io.free_clk
tlu.io.scan_mode := io.scan_mode
tlu.io.rst_vec := io.rst_vec
@ -259,7 +239,7 @@ class dec extends Module with param with RequireAsyncReset{
tlu.io.dec_tlu_i0_pc_r := decode.io.dec_tlu_i0_pc_r
tlu.io.dec_tlu_packet_r := decode.io.dec_tlu_packet_r
tlu.io.dec_illegal_inst := decode.io.dec_illegal_inst
tlu.io.dec_i0_decode_d := decode.io.dec_i0_decode_d
tlu.io.dec_i0_decode_d := decode.io.dec_aln.dec_i0_decode_d
tlu.io.exu_i0_br_way_r := io.exu_i0_br_way_r
tlu.io.dbg_halt_req := io.dbg_halt_req
tlu.io.dbg_resume_req := io.dbg_resume_req
@ -302,26 +282,20 @@ class dec extends Module with param with RequireAsyncReset{
io.dec_tlu_pic_clk_override := tlu.io.dec_tlu_pic_clk_override
io.dec_tlu_dccm_clk_override := tlu.io.dec_tlu_dccm_clk_override
io.dec_tlu_icm_clk_override := tlu.io.dec_tlu_icm_clk_override
io.dec_tlu_picio_clk_override := tlu.io.dec_tlu_picio_clk_override
io.dec_tlu_core_empty := tlu.io.dec_tlu_core_empty
io.dec_csr_rddata_d := tlu.io.dec_csr_rddata_d
io.dec_tlu_flush_lower_wb := tlu.io.dec_tlu_flush_lower_wb
//--------------------------------------------------------------------------//
io.trace_rv_trace_pkt.rv_i_insn_ip := decode.io.dec_i0_inst_wb
io.trace_rv_trace_pkt.rv_i_address_ip := Cat(decode.io.dec_i0_pc_wb, 0.U)
io.trace_rv_trace_pkt.rv_i_valid_ip := tlu.io.dec_tlu_int_valid_wb1 | tlu.io.dec_tlu_i0_valid_wb1 | tlu.io.dec_tlu_i0_exc_valid_wb1
io.trace_rv_trace_pkt.rv_i_exception_ip := tlu.io.dec_tlu_int_valid_wb1 | tlu.io.dec_tlu_i0_exc_valid_wb1
io.trace_rv_trace_pkt.rv_i_ecause_ip := tlu.io.dec_tlu_exc_cause_wb1(4,0)
io.trace_rv_trace_pkt.rv_i_interrupt_ip := tlu.io.dec_tlu_int_valid_wb1
io.trace_rv_trace_pkt.rv_i_tval_ip := tlu.io.dec_tlu_mtval_wb1
io.rv_trace_pkt.rv_i_insn_ip := decode.io.dec_i0_inst_wb1
io.rv_trace_pkt.rv_i_address_ip := Cat(decode.io.dec_i0_pc_wb1, 0.U)
io.rv_trace_pkt.rv_i_valid_ip := Cat(tlu.io.dec_tlu_int_valid_wb1, tlu.io.dec_tlu_i0_valid_wb1 | tlu.io.dec_tlu_i0_exc_valid_wb1)
io.rv_trace_pkt.rv_i_exception_ip := Cat(tlu.io.dec_tlu_int_valid_wb1, tlu.io.dec_tlu_i0_exc_valid_wb1)
io.rv_trace_pkt.rv_i_ecause_ip := tlu.io.dec_tlu_exc_cause_wb1(4,0)
io.rv_trace_pkt.rv_i_interrupt_ip := Cat(tlu.io.dec_tlu_int_valid_wb1, 0.U)
io.rv_trace_pkt.rv_i_tval_ip := tlu.io.dec_tlu_mtval_wb1
// debug command read data
io.dec_dbg_rddata := decode.io.dec_i0_wdata_r
}
object dec_main extends App {
println((new chisel3.stage.ChiselStage).emitVerilog(new dec()))
}

View File

@ -17,254 +17,105 @@ class dec_dec_ctl extends Module with lib{
pat.reduce(_&_)
}
io.out.alu := pattern(List(30,24,23,-22,-21,-20,14,-5,4)) | pattern(List(29,-27,-24,4)) |
pattern(List(-25,-13,-12,4)) | pattern(List(-30,-25,13,12)) | pattern(List(27,25,14,4)) |
pattern(List(29,27,-14,4)) | pattern(List(29,-14,5,4)) | pattern(List(-27,-25,14,4)) |
pattern(List(30,-29,-13,4)) | pattern(List(-30,-27,-25,4)) | pattern(List(13,-5,4)) |
pattern(List(-12,-5,4)) | pattern(List(2)) | pattern(List(6)) | pattern(List(30,24,23,22,21,20,-5,4)) |
pattern(List(-30,29,-24,-23,22,21,20,-5,4)) | pattern(List(-30,24,-23,-22,-21,-20,-5,4))
io.out.rs1 := pattern(List(-14,-13,-2)) | pattern(List(-13,11,-2)) | pattern(List(19,13,-2)) |
pattern(List(-13,10,-2)) | pattern(List(18,13,-2)) | pattern(List(-13,9,-2)) | pattern(List(17,13,-2)) |
pattern(List(-13,8,-2)) | pattern(List(16,13,-2)) | pattern(List(-13,7,-2)) |
pattern(List(15,13,-2)) | pattern(List(-4,-3)) | pattern(List(-6,-2))
io.out.alu := io.ins(2) | io.ins(6) | (!io.ins(25)&io.ins(4)) | (!io.ins(5)&io.ins(4))
io.out.rs1 := pattern(List(-14,-13,-2)) | pattern(List(-13,11,-2)) |
pattern(List(19,13,-2)) | pattern(List(-13,10,-2)) |
pattern(List(18,13,-2)) | pattern(List(-13,9,-2)) |
pattern(List(17,13,-2)) | pattern(List(-13,8,-2)) |
pattern(List(16,13,-2)) | pattern(List(-13,7,-2)) |
pattern(List(15,13,-2)) |pattern(List(-4,-3)) | pattern(List(-6,-2))
io.out.rs2 := pattern(List(5,-4,-2)) | pattern(List(-6,5,-2))
io.out.imm12 := pattern(List(-4,-3,2)) | pattern(List(13,-5,4,-2)) | pattern(List(-13,-12,6,4)) | pattern(List(-12,-5,4,-2))
io.out.rd := pattern(List(-5,-2)) | pattern(List(5,2)) | pattern(List(4))
io.out.shimm5 := pattern(List(27,-13,12,-5,4,-2)) | pattern(List(-30,-13,12,-5,4,-2)) | pattern(List(14,-13,12,-5,4,-2))
io.out.imm20 := pattern(List(5,3)) | pattern(List(4,2))
io.out.pc := pattern(List(-5,-3,2)) | pattern(List(5,3))
io.out.imm12 := pattern(List(-4,-3,2)) | pattern(List(13,-5,4,-2)) |
pattern(List(-13,-12,6,4)) | pattern(List(-12,-5,4,-2))
io.out.rd := (!io.ins(5) & !io.ins(2)) | (io.ins(5) & io.ins(2)) | io.ins(4)
io.out.shimm5 := pattern(List(-13,12,-5,4,-2))
io.out.imm20 := (io.ins(5)&io.ins(3)) | (io.ins(4)&io.ins(2))
io.out.pc := (!io.ins(5) & !io.ins(3) & io.ins(2)) | (io.ins(5) & io.ins(3))
io.out.load := pattern(List(-5,-4,-2))
io.out.store := pattern(List(-6,5,-4))
io.out.lsu := pattern(List(-6,-4,-2))
io.out.add := pattern(List(-14,-13,-12,-5,4)) | pattern(List(-5,-3,2)) | pattern(List(-30,-25,-14,-13,-12,-6,4,-2))
io.out.sub := pattern(List(30,-14,-12,-6,5,4,-2)) | pattern(List(-29,-25,-14,13,-6,4,-2)) |
pattern(List(27,25,14,-6,5,-2)) | pattern(List(-14,13,-5,4,-2)) | pattern(List(6,-4,-2))
io.out.land := pattern(List(-27,-25,14,13,12,-6,-2)) | pattern(List(14,13,12,-5,-2))
io.out.lor := pattern(List(-6,3)) | pattern(List(-29,-27,-25,14,13,-12,-6,-2)) | pattern(List(5,4,2)) |
pattern(List(-13,-12,6,4)) | pattern(List(14,13,-12,-5,-2))
io.out.lxor := pattern(List(-29,-27,-25,14,-13,-12,4,-2)) | pattern(List(14,-13,-12,-5,4,-2))
io.out.sll := pattern(List(-29,-27,-25,-14,-13,12,-6,4,-2))
io.out.sra := pattern(List(30,-29,-27,-13,12,-6,4,-2))
io.out.srl := pattern(List(-30,-29,-27,-25,14,-13,12,-6,4,-2))
io.out.slt := pattern(List(-29,-25,-14,13,-6,4,-2)) | pattern(List(-14,13,-5,4,-2))
io.out.unsign := pattern(List(-27,25,14,12,-6,5,-2)) | pattern(List(-14,13,12,-5,-2)) |
pattern(List(13,6,-4,-2)) | pattern(List(14,-5,-4)) | pattern(List(-25,-14,13,12,-6,-2)) |
pattern(List(27,25,14,13,-6,5,-2))
io.out.add := pattern(List(-14,-13,-12,-5,4)) | pattern(List(-5,-3,2)) |
pattern(List(-30,-25,-14,-13,-12,-6,4,-2))
io.out.sub := pattern(List(30,-12,-6,5,4,-2)) | pattern(List(-25,-14,13,-6,4,-2)) |
pattern(List(-14,13,-5,4,-2)) | pattern(List(6,-4,-2))
io.out.land := pattern(List(14,13,12,-5,-2)) | pattern(List(-25,14,13,12,-6,-2))
io.out.lor := pattern(List(-6,3)) | pattern(List(-25,14,13,-12,-6,-2)) |
pattern(List(5,4,2)) | pattern(List(-13,-12,6,4)) |
pattern(List(14,13,-12,-5,-2))
io.out.lxor := pattern(List(-25,14,-13,-12,4,-2)) | pattern(List(14,-13,-12,-5,4,-2))
io.out.sll := pattern(List(-25,-14,-13,12,-6,4,-2))
io.out.sra := pattern(List(30,-13,12,-6,4,-2))
io.out.srl := pattern(List(-30,-25,14,-13,12,-6,4,-2))
io.out.slt := pattern(List(-25,-14,13,-6,4,-2)) | pattern(List(-14,13,-5,4,-2))
io.out.unsign := pattern(List(-14,13,12,-5,-2)) | pattern(List(13,6,-4,-2)) |
pattern(List(14,-5,-4)) | pattern(List(-25,-14,13,12,-6,-2)) |
pattern(List(25,14,12,-6,5,-2))
io.out.condbr := pattern(List(6,-4,-2))
io.out.beq := pattern(List(-14,-12,6,-4,-2))
io.out.bne := pattern(List(-14,12,6,-4,-2))
io.out.bge := pattern(List(14,12,5,-4,-2))
io.out.blt := pattern(List(14,-12,5,-4,-2))
io.out.jal := pattern(List(6,2))
io.out.by := pattern(List(-13,-12,-6,-4,-2))
io.out.half := pattern(List(12,-6,-4,-2))
io.out.word := pattern(List(13,-6,-4))
io.out.csr_read := pattern(List(13,6,4)) | pattern(List(7,6,4)) | pattern(List(8,6,4)) |
pattern(List(9,6,4)) | pattern(List(10,6,4)) | pattern(List(11,6,4))
io.out.csr_read := pattern(List(13,6,4)) | pattern(List(7,6,4)) |
pattern(List(8,6,4)) | pattern(List(9,6,4)) | pattern(List(10,6,4)) |
pattern(List(11,6,4))
io.out.csr_clr := pattern(List(15,13,12,6,4)) | pattern(List(16,13,12,6,4)) |
pattern(List(17,13,12,6,4)) | pattern(List(18,13,12,6,4)) | pattern(List(19,13,12,6,4))
io.out.csr_set := pattern(List(15,-12,6,4)) | pattern(List(16,-12,6,4)) | pattern(List(17,-12,6,4)) |
pattern(List(18,-12,6,4)) | pattern(List(19,-12,6,4))
pattern(List(17,13,12,6,4)) | pattern(List(18,13,12,6,4)) |
pattern(List(19,13,12,6,4))
io.out.csr_write := pattern(List(-13,12,6,4))
io.out.csr_imm := pattern(List(14,-13,6,4)) | pattern(List(15,14,6,4)) | pattern(List(16,14,6,4)) |
pattern(List(17,14,6,4)) | pattern(List(18,14,6,4)) | pattern(List(19,14,6,4))
io.out.presync := pattern(List(-5,3)) | pattern(List(-13,7,6,4)) | pattern(List(-13,8,6,4)) |
pattern(List(-13,9,6,4)) | pattern(List(-13,10,6,4)) | pattern(List(-13,11,6,4)) |
pattern(List(15,13,6,4)) | pattern(List(16,13,6,4)) | pattern(List(17,13,6,4)) |
pattern(List(18,13,6,4)) | pattern(List(19,13,6,4))
io.out.postsync := pattern(List(12,-5,3)) | pattern(List(-22,-13,-12,6,4)) |
pattern(List(-13,7,6,4)) | pattern(List(-13,8,6,4)) | pattern(List(-13,9,6,4)) | pattern(List(-13,10,6,4)) |
pattern(List(-13,11,6,4)) | pattern(List(15,13,6,4)) | pattern(List(16,13,6,4)) | pattern(List(17,13,6,4)) |
pattern(List(18,13,6,4)) | pattern(List(19,13,6,4))
io.out.csr_imm := pattern(List(14,-13,6,4)) | pattern(List(15,14,6,4)) |
pattern(List(16,14,6,4)) | pattern(List(17,14,6,4)) |
pattern(List(18,14,6,4)) | pattern(List(19,14,6,4))
io.out.csr_set := pattern(List(15,-12,6,4)) | pattern(List(16,-12,6,4)) |
pattern(List(17,-12,6,4)) | pattern(List(18,-12,6,4)) |
pattern(List(19,-12,6,4))
io.out.ebreak := pattern(List(-22,20,-13,-12,6,4))
io.out.ecall := pattern(List(-21,-20,-13,-12,6,4))
io.out.mret := pattern(List(29,-13,-12,6,4))
io.out.mul := pattern(List(-30,27,24,20,14,-13,12,-5,4,-2)) | pattern(List(29,27,-24,23,14,-13,12,-5,4,-2)) |
pattern(List(29,27,-24,-20,14,-13,12,-5,4,-2)) | pattern(List(27,-25,13,-12,-6,5,4,-2)) |
pattern(List(30,27,13,-6,5,4,-2)) | pattern(List(29,27,22,-20,14,-13,12,-5,4,-2)) |
pattern(List(29,27,-21,20,14,-13,12,-5,4,-2)) | pattern(List(29,27,-22,21,14,-13,12,-5,4,-2)) |
pattern(List(30,29,27,-23,14,-13,12,-5,4,-2)) | pattern(List(-30,27,23,14,-13,12,-5,4,-2)) |
pattern(List(-30,-29,27,-25,-13,12,-6,4,-2)) | pattern(List(25,-14,-6,5,4,-2)) |
pattern(List(30,-27,24,-14,-13,12,-5,4,-2)) | pattern(List(29,27,14,-6,5,-2))
io.out.rs1_sign := pattern(List(-27,25,-14,13,-12,-6,5,4,-2)) | pattern(List(-27,25,-14,-13,12,-6,4,-2))
io.out.rs2_sign := pattern(List(-27,25,-14,-13,12,-6,4,-2))
io.out.mul := pattern(List(25,-14,-6,5,4,-2))
io.out.rs1_sign := pattern(List(25,-14,13,-12,-6,5,4,-2)) |
pattern(List(25,-14,-13,12,-6,4,-2))
io.out.rs2_sign := pattern(List(25,-14,-13,12,-6,4,-2))
io.out.low := pattern(List(25,-14,-13,-12,5,4,-2))
io.out.div := pattern(List(-27,25,14,-6,5,-2))
io.out.rem := pattern(List(-27,25,14,13,-6,5,-2))
io.out.div := pattern(List(25,14,-6,5,-2))
io.out.rem := pattern(List(25,14,13,-6,5,-2))
io.out.fence := pattern(List(-5,3))
io.out.fence_i := pattern(List(12,-5,3))
io.out.clz := pattern(List(30,-27,-24,-22,-21,-20,-14,-13,12,-5,4,-2))
io.out.ctz := pattern(List(30,-27,-24,-22,20,-14,-13,12,-5,4,-2))
io.out.pcnt := pattern(List(30,-27,-24,21,-14,-13,12,-5,4,-2))
io.out.sext_b := pattern(List(30,-27,22,-20,-14,-13,12,-5,4,-2))
io.out.sext_h := pattern(List(30,-27,22,20,-14,-13,12,-5,4,-2))
io.out.slo := pattern(List(-30,29,-27,-14,-13,12,-6,4,-2))
io.out.sro := pattern(List(-30,29,-27,14,-13,12,-6,4,-2))
io.out.min := pattern(List(27,25,14,-12,-6,5,-2))
io.out.max := pattern(List(27,25,14,12,-6,5,-2))
io.out.pack := pattern(List(-30,27,-25,-13,-12,5,4,-2))
io.out.packu := pattern(List(30,27,-13,-12,5,4,-2))
io.out.packh := pattern(List(-30,27,-25,13,12,-6,5,-2))
io.out.rol := pattern(List(30,-27,-14,12,-6,5,4,-2))
io.out.ror := pattern(List(30,29,-27,14,-13,12,-6,4,-2))
io.out.zbb := pattern(List(30,-27,-24,-14,-13,12,-5,4,-2)) | pattern(List(-30,27,14,13,12,-6,5,-2)) |
pattern(List(30,29,-27,14,-13,12,-5,4,-2)) | pattern(List(27,-13,-12,5,4,-2)) |
pattern(List(30,14,-13,-12,-6,5,-2)) | pattern(List(30,-27,13,-6,5,4,-2)) |
pattern(List(30,29,-27,-6,5,4,-2)) | pattern(List(30,29,24,23,22,21,20,14,-13,12,-5,4,-2)) |
pattern(List(-30,29,27,-24,-23,22,21,20,14,-13,12,-5,4,-2)) |
pattern(List(-30,27,24,-23,-22,-21,-20,14,-13,12,-5,4,-2)) |
pattern(List(30,29,24,23,-22,-21,-20,14,-13,12,-5,4,-2)) | pattern(List(27,25,14,-6,5,-2))
io.out.sbset := pattern(List(-30,29,27,-14,-13,12,-6,4,-2))
io.out.sbclr := pattern(List(30,-29,-14,-13,12,-6,4,-2))
io.out.sbinv := pattern(List(30,29,27,-14,-13,12,-6,4,-2))
io.out.sbext := pattern(List(30,-29,27,14,-13,12,-6,4,-2))
io.out.zbs := pattern(List(29,27,-14,-13,12,-6,4,-2)) | pattern(List(30,-29,27,-13,12,-6,4,-2))
io.out.bext := pattern(List(-30,27,-25,13,-12,-6,5,4,-2))
io.out.bdep := pattern(List(30,27,13,-12,-6,5,4,-2))
io.out.zbe := pattern(List(27,-25,13,-12,-6,5,4,-2))
io.out.clmul := pattern(List(27,25,-14,-13,-6,5,4,-2))
io.out.clmulh := pattern(List(27,-14,13,12,-6,5,-2))
io.out.clmulr := pattern(List(27,-14,-12,-6,5,4,-2))
io.out.zbc := pattern(List(27,25,-14,-6,5,4,-2))
io.out.grev := pattern(List(30,29,27,14,-13,12,-6,4,-2))
io.out.gorc := pattern(List(-30,29,27,14,-13,12,-6,4,-2))
io.out.shfl := pattern(List(-30,-29,27,-25,-14,-13,12,-6,4,-2))
io.out.unshfl := pattern(List(-30,-29,27,-25,14,-13,12,-6,4,-2))
io.out.zbp := pattern(List(-30,29,-27,-13,12,-5,4,-2)) | pattern(List(-30,-29,27,-13,12,-5,4,-2)) |
pattern(List(30,-27,13,-6,5,4,-2)) | pattern(List(27,-25,-13,-12,5,4,-2)) |
pattern(List(30,14,-13,-12,5,4,-2)) | pattern(List(29,-27,12,-6,5,4,-2)) |
pattern(List(-30,-29,27,-25,12,-6,5,4,-2)) | pattern(List(29,14,-13,12,-6,4,-2))
io.out.crc32_b := pattern(List(30,-27,24,-23,-21,-20,-14,-13,12,-5,4,-2))
io.out.crc32_h := pattern(List(30,-27,24,-23,20,-14,-13,12,-5,4,-2))
io.out.crc32_w := pattern(List(30,-27,24,-23,21,-14,-13,12,-5,4,-2))
io.out.crc32c_b := pattern(List(30,-27,23,-21,-20,-14,-13,12,-5 ,4,-2))
io.out.crc32c_h := pattern(List(30,-27,23,20,-14,-13,12,-5,4,-2))
io.out.crc32c_w := pattern(List(30,-27,23,21,-14,-13,12,-5,4,-2))
io.out.zbr := pattern(List(30,-27,24,-14,-13,12,-5,4,-2))
io.out.bfp := pattern(List(30,27,13,12,-6,5,-2))
io.out.zbf := pattern(List(30,27,13,12,-6,5,-2))
io.out.sh1add := pattern(List(29,-14,-12,-6,5,4,-2))
io.out.sh2add := pattern(List(29,14,-13,-12,5,4,-2))
io.out.sh3add := pattern(List(29,14,13,-6,5,-2))
io.out.zba := pattern(List(29,-12,-6,5,4,-2))
io.out.pm_alu := pattern(List(28,22,-13,-12,4)) | pattern(List(-30,-29,-27,-25,-6,4)) |
pattern(List(-29,-27,-25,-13,12,-6,4)) | pattern(List(-29,-27,-25,-14,-6,4)) |
pattern(List(13,-5,4)) | pattern(List(4,2)) | pattern(List(-12,-5,4))
io.out.legal := pattern(List(-31,-30,-29,28,-27,-26,-25,-24,-23,22,-21,20,-19,-18,-17,-16,-15,-14,-11,-10,-9,-8,-7,6,5,4,-3,-2,1,0)) |
pattern(List(-31,-30,29,28,-27,-26,-25,-24,-23,-22,21,-20,-19,-18,-17,-16,-15,-14,-11,-10,-9,-8,-7,6,5,4,-3,-2,1,0)) |
io.out.pm_alu := pattern(List(28,22,-13,-12,4)) | pattern(List(4,2)) |
pattern(List(-25,-6,4)) | pattern(List(-5,4))
io.out.presync := pattern(List(-5,3)) | pattern(List(-13,7,6,4)) |
pattern(List(-13,8,6,4)) | pattern(List(-13,9,6,4)) |
pattern(List(-13,10,6,4)) | pattern(List(-13,11,6,4)) |
pattern(List(15,13,6,4)) | pattern(List(16,13,6,4)) |
pattern(List(17,13,6,4)) | pattern(List(18,13,6,4)) |
pattern(List(19,13,6,4))
io.out.postsync := pattern(List(12,-5,3)) | pattern(List(-22,-13,-12,6,4)) |
pattern(List(-13,7,6,4)) | pattern(List(-13,8,6,4)) |
pattern(List(-13,9,6,4)) | pattern(List(-13,10,6,4)) |
pattern(List(-13,11,6,4)) | pattern(List(15,13,6,4)) |
pattern(List(16,13,6,4)) | pattern(List(17,13,6,4)) |
pattern(List(18,13,6,4)) | pattern(List(19,13,6,4))
io.out.legal := pattern(List(-31,-30,29,28,-27,-26,-25,-24,-23,-22,21,-20,-19,-18,-17,-16,-15,-14,-11,-10,-9,-8,-7,6,5,4,-3,-2,1,0)) |
pattern(List(-31,-30,-29,28,-27,-26,-25,-24,-23,22,-21,20,-19,-18,-17,-16,-15,-14,-11,-10,-9,-8,-7,6,5,4,-3,-2,1,0)) |
pattern(List(-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-19,-18,-17,-16,-15,-14,-11,-10,-9,-8,-7,5,4,-3,-2,1,0)) |
pattern(List(-31,29,-28,-26,-25,24,-22,-20,-6,-5,4,-3,1,0)) | pattern(List(-31,29,-28,-26,-25,24,-22,-21,-6,-5,4,-3,1,0)) |
pattern(List(-31,29,-28,-26,-25,-23,-22,-20,-6,-5,4,-3,1,0)) | pattern(List(-31,29,-28,-26,-25,-24,-23,-21,-6,-5,4,-3,1,0)) |
pattern(List(-31,-30,-29,-28,-26,25,13,-6,4,-3,1,0)) | pattern(List(-31,-30,-28,-26,-25,-24,-6,-5,4,-3,1,0)) |
pattern(List(-31,-30,-28,-27,-26,-25,14,-12,-6,4,-3,1,0)) | pattern(List(-31,-30,-28,-27,-26,-25,13,-12,-6,4,-3,1,0)) |
pattern(List(-31,-29,-28,-27,-26,-25,-13,-12,-6,4,-3,1,0)) | pattern(List(-31,-28,-27,-26,-25,14,-6,-5,4,-3,1,0)) |
pattern(List(-31,-30,-29,-28,-26,-13,12,5,4,-3,-2,1,0)) | pattern(List(-31,-30,-29,-28,-26,14,-6,5,4,-3,1,0)) |
pattern(List(-31,30,-28,27,-26,-25,-13,12,-6,4,-3,1,0)) | pattern(List(-31,29,-28,27,-26,-25 ,-6,-5,4,-3,1,0)) |
pattern(List(-31,-30,-28,-27,-26,-25,-6,-5,4,-3,1,0)) | pattern(List(-31,-30,-29,-28,-27,-26,-6,5,4,-3,1,0)) |
pattern(List(-14,-13,-12,6,5,-4,-3,1,0)) | pattern(List(-31,-29,-28,-26,-25,14,-6,5,4,-3,1,0)) |
pattern(List(-31,29,-28,-26,-25,-13,12,5,4,-3,-2,1,0)) | pattern(List(14,6,5,-4,-3,-2,1,0)) |
pattern(List(-14,-13,5,-4,-3,-2,1,0)) | pattern(List(-12,-6,-5,4,-3,1,0)) | pattern(List(-13,12,6,5,-3,-2,1,0)) |
pattern(List(-31,-30,-29,-28,-27,-26,-25,-6,4,-3,1,0)) |
pattern(List(-31,-29,-28,-27,-26,-25,-14,-13,-12,-6,-3,-2,1,0)) |
pattern(List(-31,-29,-28,-27,-26,-25,14,-13,12,-6,4,-3,1,0)) |
pattern(List(-31,-30,-29,-28,-27,-26,-6,5,4,-3,1,0)) |
pattern(List(-14,-13,-12,6,5,-4,-3,1,0)) |
pattern(List(14,6,5,-4,-3,-2,1,0)) |
pattern(List(-12,-6,-5,4,-3,1,0)) |
pattern(List(-14,-13,5,-4,-3,-2,1,0)) |
pattern(List(12,6,5,4,-3,-2,1,0)) |
pattern(List(-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15,-14,-13,-11,-10,-9,-8,-7,-6,-5,-4,3,2,1,0)) |
pattern(List(-31,-30,-29,-28,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,3,2,1,0)) |
pattern(List(13,6,5,4,-3,-2,1,0)) | pattern(List(6,5,-4,3,2,1,0)) | pattern(List(-14,-12,-6,-4,-3,-2,1,0)) |
pattern(List(-13,-6,-5,-4,-3,-2,1,0)) | pattern(List(13,-6,-5,4,-3,1,0)) | pattern(List(-6,4,-3,2,1,0))
}
object dec_dec extends App {
(new chisel3.stage.ChiselStage).emitVerilog(new dec_dec_ctl())
pattern(List(13,6,5,4,-3,-2,1,0)) |
pattern(List(-13,-6,-5,-4,-3,-2,1,0)) |
pattern(List(6,5,-4,3,2,1,0)) |
pattern(List(13,-6,-5,4,-3,1,0)) |
pattern(List(-14,-12,-6,-4,-3,-2,1,0)) |
pattern(List(-6,4,-3,2,1,0))
}

View File

@ -17,17 +17,10 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val dctl_dma = new dctl_dma //connection with dma
val dec_aln = Flipped(new aln_dec) //connection with aligner
val dbg_dctl = new dbg_dctl() //connection with dbg
val dec_tlu_trace_disable = Input(Bool())
val dec_debug_valid_d = Input(Bool())
val dec_tlu_flush_extint = Input(Bool())
val dec_tlu_force_halt = Input(Bool()) // invalidate nonblock load cam on a force halt event
val dec_i0_inst_wb = Output(UInt(32.W)) // 32b instruction at wb+1 for trace encoder
val dec_i0_pc_wb = Output(UInt(31.W)) // 31b pc at wb+1 for trace encoder
val dec_i0_inst_wb1 = Output(UInt(32.W)) // 32b instruction at wb+1 for trace encoder
val dec_i0_pc_wb1 = Output(UInt(31.W)) // 31b pc at wb+1 for trace encoder
val dec_i0_trigger_match_d = Input(UInt(4.W)) // i0 decode trigger matches
val dec_tlu_wr_pause_r = Input(Bool()) // pause instruction at r
val dec_tlu_pipelining_disable = Input(Bool()) // pipeline disable - presync, i0 decode only
@ -37,19 +30,14 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val dec_tlu_flush_leak_one_r = Input(Bool()) // leak1 instruction
val dec_debug_fence_d = Input(Bool()) // debug fence instruction
val dec_i0_icaf_d = Input(Bool()) // icache access fault
val dec_i0_icaf_second_d = Input(Bool()) // i0 instruction access fault at decode for f1 fetch group
val dec_i0_icaf_f1_d = Input(Bool()) // i0 instruction access fault at decode for f1 fetch group
val dec_i0_icaf_type_d = Input(UInt(2.W)) // i0 instruction access fault type
val dec_i0_dbecc_d = Input(Bool()) // icache/iccm double-bit error
val dec_i0_brp = Flipped(Valid(new br_pkt_t)) // branch packet
val dec_i0_bp_index = Input(UInt(((BTB_ADDR_HI-BTB_ADDR_LO)+1).W)) // i0 branch index
val dec_i0_bp_fghr = Input(UInt(BHT_GHR_SIZE.W)) // BP FGHR
val dec_i0_bp_btag = Input(UInt(BTB_BTAG_SIZE.W)) // BP tag
val dec_i0_bp_fa_index = Input(UInt(log2Ceil(BTB_SIZE).W)) // Fully associt btb index
// val dec_i0_pc_d = Input(UInt(31.W)) // pc
val dec_i0_pc_d = Input(UInt(31.W)) // pc
val lsu_idle_any = Input(Bool()) // lsu idle: if fence instr & !!!!!!!!!!!!!!!!!!!!!!!!!lsu_idle then stall decode
val lsu_load_stall_any = Input(Bool()) // stall any load at decode
val lsu_store_stall_any = Input(Bool()) // stall any store at decode6
@ -69,21 +57,14 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val exu_flush_final = Input(Bool()) // lower flush or i0 flush at X or D
val dec_i0_instr_d = Input(UInt(32.W)) // inst at decode
val dec_ib0_valid_d = Input(Bool()) // inst valid at decode
val active_clk = Input(Clock()) // Clock only while core active. Through two clock headers. For flops without second clock header built in.
val free_l2clk = Input(Clock()) // Clock always. Through one clock header. For flops with second header built in.
val clk_override = Input(Bool()) // Override non-functional clock gating
val free_clk = Input(Clock())
val active_clk = Input(Clock()) // clk except for halt / pause
val clk_override = Input(Bool()) // test stuff
val dec_i0_rs1_d = Output(UInt(5.W)) // rs1 logical source
val dec_i0_rs2_d = Output(UInt(5.W))
val dec_i0_waddr_r = Output(UInt(5.W)) // i0 logical source to write to gpr's
val dec_i0_wen_r = Output(Bool()) // i0 write enable
val dec_i0_wdata_r = Output(UInt(32.W)) // i0 write data
// val dec_i0_branch_d = Output(Bool()) // Branch in D-stage
// val dec_i0_result_r = Output(UInt(32.W)) // Result R-stage
// val dec_qual_lsu_d = Output(Bool())// LSU instruction at D. Use to quiet LSU operands
val lsu_p = Valid(new lsu_pkt_t) // load/store packet
val div_waddr_wb = Output(UInt(5.W)) // DIV write address to GPR
val dec_lsu_valid_raw_d = Output(Bool())
@ -99,9 +80,6 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val dec_tlu_packet_r = Output(new trap_pkt_t) // trap packet
val dec_tlu_i0_pc_r = Output(UInt(31.W)) // i0 trap pc
val dec_illegal_inst = Output(UInt(32.W)) // illegal inst
val dec_fa_error_index = Output(UInt(log2Ceil(BTB_SIZE).W)) // Fully associt btb error index
val dec_pmu_instr_decoded = Output(Bool()) // number of instructions decode this cycle encoded
val dec_pmu_decode_stall = Output(Bool()) // decode is stalled
val dec_pmu_presync_stall = Output(Bool()) // decode has presync stall
@ -112,8 +90,7 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val dec_pause_state_cg = Output(Bool()) // pause state for clock-gating
val dec_div_active = Output(Bool()) // non-block divide is active
val scan_mode = Input(Bool())
val dec_i0_decode_d = Output(Bool())
})
})
//packets zero initialization
io.decode_exu.mul_p := 0.U.asTypeOf(io.decode_exu.mul_p)
// Vals defined
@ -196,88 +173,54 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val i0_immed_d = WireInit(UInt(32.W), 0.U)
val i0_result_x = WireInit(UInt(32.W), 0.U)
val i0_result_r = WireInit(UInt(32.W), 0.U)
val i0_br_error_all = WireInit(Bool(),0.B)
val i0_brp_valid = WireInit(Bool(),0.B)
val btb_error_found_f = WireInit(Bool(),0.B)
val fa_error_index_ns = WireInit(Bool(),0.B)
val btb_error_found = WireInit(Bool(),0.B)
val div_active_in = WireInit(Bool(),0.B)
//////////////////////////////////////////////////////////////////////
// Start - Data gating {{
val data_gate_en = (io.dec_tlu_wr_pause_r ^ tlu_wr_pause_r1 ) | // replaces free_clk
(tlu_wr_pause_r1 ^ tlu_wr_pause_r2 ) | // replaces free_clk
(io.dec_tlu_flush_extint ^ io.decode_exu.dec_extint_stall) |
(leak1_i1_stall_in ^ leak1_i1_stall ) | // replaces free_clk
(leak1_i0_stall_in ^ leak1_i0_stall ) | // replaces free_clk
(pause_state_in ^ pause_state ) | // replaces free_clk
(ps_stall_in ^ postsync_stall ) | // replaces free_clk
(io.exu_flush_final ^ flush_final_r ) | // replaces free_clk
(illegal_lockout_in ^ illegal_lockout ) // replaces active_clk
leak1_i1_stall := rvdffie(leak1_i1_stall_in, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
leak1_i0_stall := rvdffie(leak1_i0_stall_in, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
io.decode_exu.dec_extint_stall := rvdffie(io.dec_tlu_flush_extint, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
pause_state := rvdffie(pause_state_in, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
tlu_wr_pause_r1 := rvdffie(io.dec_tlu_wr_pause_r, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
tlu_wr_pause_r2 := rvdffie(tlu_wr_pause_r1, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
illegal_lockout := rvdffie(illegal_lockout_in, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
postsync_stall := rvdffie(ps_stall_in, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
val lsu_trigger_match_r = rvdffie(io.lsu_trigger_match_m, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
val lsu_pmu_misaligned_r = rvdffie(io.lsu_pmu_misaligned_m, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
io.dec_div_active := rvdffie(div_active_in, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
flush_final_r := rvdffie(io.exu_flush_final, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
val debug_valid_x = rvdffie(io.dec_debug_valid_d, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
val i0_icaf_d = io.dec_i0_icaf_d | io.dec_i0_dbecc_d
if(BTB_ENABLE){
i0_brp_valid := io.dec_i0_brp.valid & !leak1_mode & !i0_icaf_d
io.decode_exu.dec_i0_predict_p_d.bits.misp := 0.U
io.decode_exu.dec_i0_predict_p_d.bits.ataken := 0.U
io.decode_exu.dec_i0_predict_p_d.bits.boffset := 0.U
io.decode_exu.dec_i0_predict_p_d.bits.pcall := i0_pcall // don't mark as pcall if branch error
io.decode_exu.dec_i0_predict_p_d.bits.pja := i0_pja
io.decode_exu.dec_i0_predict_p_d.bits.pret := i0_pret
io.decode_exu.dec_i0_predict_p_d.bits.prett := io.dec_i0_brp.bits.prett
io.decode_exu.dec_i0_predict_p_d.bits.pc4 := io.dec_i0_pc4_d
io.decode_exu.dec_i0_predict_p_d.bits.hist := io.dec_i0_brp.bits.hist
io.decode_exu.dec_i0_predict_p_d.valid := i0_brp_valid & i0_legal_decode_d
val i0_notbr_error = i0_brp_valid & !(i0_dp_raw.condbr | i0_pcall_raw | i0_pja_raw | i0_pret_raw)
val data_gate_clk = rvclkhdr(clock,data_gate_en.asBool(),io.scan_mode)
// End - Data gating
// no toffset error for a pret
val i0_br_toffset_error = i0_brp_valid & io.dec_i0_brp.bits.hist(1) & (io.dec_i0_brp.bits.toffset =/= i0_br_offset) & !i0_pret_raw
val i0_ret_error = i0_brp_valid & (io.dec_i0_brp.bits.ret ^ i0_pret_raw)
val i0_br_error = io.dec_i0_brp.bits.br_error | i0_notbr_error | i0_br_toffset_error | i0_ret_error
io.decode_exu.dec_i0_predict_p_d.bits.br_error := i0_br_error & i0_legal_decode_d & !leak1_mode
io.decode_exu.dec_i0_predict_p_d.bits.br_start_error := io.dec_i0_brp.bits.br_start_error & i0_legal_decode_d & !leak1_mode
io.decode_exu.i0_predict_index_d := io.dec_i0_bp_index
io.decode_exu.i0_predict_btag_d := io.dec_i0_bp_btag
i0_br_error_all := (i0_br_error | io.dec_i0_brp.bits.br_start_error) & !leak1_mode
io.decode_exu.dec_i0_predict_p_d.bits.toffset := i0_br_offset
io.decode_exu.i0_predict_fghr_d := io.dec_i0_bp_fghr
io.decode_exu.dec_i0_predict_p_d.bits.way := io.dec_i0_brp.bits.way
if(BTB_FULLYA){
io.dec_fa_error_index := withClock(io.active_clk){RegNext(fa_error_index_ns,0.U)}
val btb_error_found_f = withClock(io.active_clk){RegNext(btb_error_found,0.B)}
btb_error_found := (i0_br_error_all | btb_error_found_f) & ~io.dec_tlu_flush_lower_r
fa_error_index_ns := Mux(i0_br_error_all & ~btb_error_found_f, io.dec_i0_bp_fa_index , io.dec_fa_error_index)
}else{
io.dec_fa_error_index := 0.U
}
}else{
io.decode_exu.dec_i0_predict_p_d := 0.U
io.decode_exu.dec_i0_predict_p_d.bits.pcall := i0_pcall // don't mark as pcall if branch error
io.decode_exu.dec_i0_predict_p_d.bits.pja := i0_pja
io.decode_exu.dec_i0_predict_p_d.bits.pret := i0_pret
io.decode_exu.dec_i0_predict_p_d.bits.pc4 := io.dec_i0_pc4_d
i0_br_error_all := 0.U
io.decode_exu.i0_predict_index_d := 0.U
io.decode_exu.i0_predict_btag_d := 0.U
io.decode_exu.i0_predict_fghr_d := 0.U
i0_brp_valid := 0.U
}
val i0_brp_valid = io.dec_i0_brp.valid & !leak1_mode
io.decode_exu.dec_i0_predict_p_d.bits.misp := 0.U
io.decode_exu.dec_i0_predict_p_d.bits.ataken := 0.U
io.decode_exu.dec_i0_predict_p_d.bits.boffset := 0.U
io.decode_exu.dec_i0_predict_p_d.bits.pcall := i0_pcall // don't mark as pcall if branch error
io.decode_exu.dec_i0_predict_p_d.bits.pja := i0_pja
io.decode_exu.dec_i0_predict_p_d.bits.pret := i0_pret
io.decode_exu.dec_i0_predict_p_d.bits.prett := io.dec_i0_brp.bits.prett
io.decode_exu.dec_i0_predict_p_d.bits.pc4 := io.dec_i0_pc4_d
io.decode_exu.dec_i0_predict_p_d.bits.hist := io.dec_i0_brp.bits.hist
io.decode_exu.dec_i0_predict_p_d.valid := i0_brp_valid & i0_legal_decode_d
val i0_notbr_error = i0_brp_valid & !(i0_dp_raw.condbr | i0_pcall_raw | i0_pja_raw | i0_pret_raw)
// no toffset error for a pret
val i0_br_toffset_error = i0_brp_valid & io.dec_i0_brp.bits.hist(1) & (io.dec_i0_brp.bits.toffset =/= i0_br_offset) & !i0_pret_raw
val i0_ret_error = i0_brp_valid & io.dec_i0_brp.bits.ret & !i0_pret_raw;
val i0_br_error = io.dec_i0_brp.bits.br_error | i0_notbr_error | i0_br_toffset_error | i0_ret_error
io.decode_exu.dec_i0_predict_p_d.bits.br_error := i0_br_error & i0_legal_decode_d & !leak1_mode
io.decode_exu.dec_i0_predict_p_d.bits.br_start_error := io.dec_i0_brp.bits.br_start_error & i0_legal_decode_d & !leak1_mode
io.decode_exu.i0_predict_index_d := io.dec_i0_bp_index
io.decode_exu.i0_predict_btag_d := io.dec_i0_bp_btag
val i0_br_error_all = (i0_br_error | io.dec_i0_brp.bits.br_start_error) & !leak1_mode
io.decode_exu.dec_i0_predict_p_d.bits.toffset := i0_br_offset
io.decode_exu.i0_predict_fghr_d := io.dec_i0_bp_fghr
io.decode_exu.dec_i0_predict_p_d.bits.way := io.dec_i0_brp.bits.way
// end
// on br error turn anything into a nop
// on i0 instruction fetch access fault turn anything into a nop
// nop => alu rs1 imm12 rd lor
val i0_instr_error = i0_icaf_d
val i0_icaf_d = io.dec_i0_icaf_d | io.dec_i0_dbecc_d
val i0_instr_error = i0_icaf_d;
i0_dp := i0_dp_raw
when((i0_br_error_all | i0_instr_error).asBool){
i0_dp := 0.U.asTypeOf(i0_dp)
@ -293,7 +236,7 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
io.decode_exu.dec_i0_select_pc_d := i0_dp.pc
// branches that can be predicted
val i0_predict_br = i0_dp.condbr | i0_pcall | i0_pja | i0_pret
val i0_predict_br = i0_dp.condbr | i0_pcall | i0_pja | i0_pret;
val i0_predict_nt = !(io.dec_i0_brp.bits.hist(1) & i0_brp_valid) & i0_predict_br
val i0_predict_t = (io.dec_i0_brp.bits.hist(1) & i0_brp_valid) & i0_predict_br
val i0_ap_pc2 = !io.dec_i0_pc4_d
@ -301,50 +244,24 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
io.decode_exu.i0_ap.predict_nt := i0_predict_nt
io.decode_exu.i0_ap.predict_t := i0_predict_t
io.decode_exu.i0_ap.add := i0_dp.add
io.decode_exu.i0_ap.sub := i0_dp.sub
io.decode_exu.i0_ap.land := i0_dp.land
io.decode_exu.i0_ap.lor := i0_dp.lor
io.decode_exu.i0_ap.lxor := i0_dp.lxor
io.decode_exu.i0_ap.sll := i0_dp.sll
io.decode_exu.i0_ap.srl := i0_dp.srl
io.decode_exu.i0_ap.sra := i0_dp.sra
io.decode_exu.i0_ap.slt := i0_dp.slt
io.decode_exu.i0_ap.unsign := i0_dp.unsign
io.decode_exu.i0_ap.beq := i0_dp.beq
io.decode_exu.i0_ap.bne := i0_dp.bne
io.decode_exu.i0_ap.blt := i0_dp.blt
io.decode_exu.i0_ap.bge := i0_dp.bge
io.decode_exu.i0_ap.clz := i0_dp.clz
io.decode_exu.i0_ap.ctz := i0_dp.ctz
io.decode_exu.i0_ap.pcnt := i0_dp.pcnt
io.decode_exu.i0_ap.sext_b := i0_dp.sext_b
io.decode_exu.i0_ap.sext_h := i0_dp.sext_h
io.decode_exu.i0_ap.sh1add := i0_dp.sh1add
io.decode_exu.i0_ap.sh2add := i0_dp.sh2add
io.decode_exu.i0_ap.sh3add := i0_dp.sh3add
io.decode_exu.i0_ap.zba := i0_dp.zba
io.decode_exu.i0_ap.slo := i0_dp.slo
io.decode_exu.i0_ap.sro := i0_dp.sro
io.decode_exu.i0_ap.min := i0_dp.min
io.decode_exu.i0_ap.max := i0_dp.max
io.decode_exu.i0_ap.pack := i0_dp.pack
io.decode_exu.i0_ap.packu := i0_dp.packu
io.decode_exu.i0_ap.packh := i0_dp.packh
io.decode_exu.i0_ap.rol := i0_dp.rol
io.decode_exu.i0_ap.ror := i0_dp.ror
io.decode_exu.i0_ap.grev := i0_dp.grev
io.decode_exu.i0_ap.gorc := i0_dp.gorc
io.decode_exu.i0_ap.zbb := i0_dp.zbb
io.decode_exu.i0_ap.sbset := i0_dp.sbset
io.decode_exu.i0_ap.sbclr := i0_dp.sbclr
io.decode_exu.i0_ap.sbinv := i0_dp.sbinv
io.decode_exu.i0_ap.sbext := i0_dp.sbext
io.decode_exu.i0_ap.csr_write := i0_csr_write_only_d
io.decode_exu.i0_ap.csr_imm := i0_dp.csr_imm
io.decode_exu.i0_ap.jal := i0_jal
io.decode_exu.i0_ap.add := i0_dp.add
io.decode_exu.i0_ap.sub := i0_dp.sub
io.decode_exu.i0_ap.land := i0_dp.land
io.decode_exu.i0_ap.lor := i0_dp.lor
io.decode_exu.i0_ap.lxor := i0_dp.lxor
io.decode_exu.i0_ap.sll := i0_dp.sll
io.decode_exu.i0_ap.srl := i0_dp.srl
io.decode_exu.i0_ap.sra := i0_dp.sra
io.decode_exu.i0_ap.slt := i0_dp.slt
io.decode_exu.i0_ap.unsign := i0_dp.unsign
io.decode_exu.i0_ap.beq := i0_dp.beq
io.decode_exu.i0_ap.bne := i0_dp.bne
io.decode_exu.i0_ap.blt := i0_dp.blt
io.decode_exu.i0_ap.bge := i0_dp.bge
io.decode_exu.i0_ap.csr_write := i0_csr_write_only_d
io.decode_exu.i0_ap.csr_imm := i0_dp.csr_imm
io.decode_exu.i0_ap.jal := i0_jal
// non block load cam logic
// val found=Wire(UInt(1.W))
cam_wen := Mux1H((0 until LSU_NUM_NBLOAD).map(i=>(0 to i).map(j=> if(i==j) !cam(j).valid else cam(j).valid).reduce(_.asBool&_.asBool).asBool -> (cam_write << i)))
@ -386,12 +303,12 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
when(nonblock_load_valid_m_delay===1.U && (io.dctl_busbuff.lsu_nonblock_load_inv_tag_r === cam(i).bits.tag) && cam(i).valid===1.U){
cam_in(i).bits.wb := 1.U
}
// force debug halt forces cam valids to 0 highest priority
// force debug halt forces cam valids to 0; highest priority
when(io.dec_tlu_force_halt){
cam_in(i).valid := 0.U
}
cam_raw(i):=rvdffie(cam_in(i),clock,reset.asAsyncReset(),io.scan_mode)
cam_raw(i):=withClock(io.free_clk){RegNext(cam_in(i),0.U.asTypeOf(cam(0)))}
nonblock_load_write(i) := (load_data_tag === cam_raw(i).bits.tag) & cam_raw(i).valid
}
@ -430,7 +347,6 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
( csr_read & csr_write).asBool -> CSRRW,
(!csr_read & csr_write).asBool -> CSRWRITE,
( csr_read & !csr_write).asBool -> CSRREAD,
(i0_dp.zbb | i0_dp.zbs | i0_dp.zbe | i0_dp.zbc | i0_dp.zbp | i0_dp.zbr | i0_dp.zbf | i0_dp.zba) -> BITMANIPU,
i0_dp.pm_alu -> ALU,
i0_dp.store -> STORE,
i0_dp.load -> LOAD,
@ -445,8 +361,10 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
// can't make this clock active_clock
leak1_i1_stall_in := (io.dec_tlu_flush_leak_one_r | (leak1_i1_stall & !io.dec_tlu_flush_lower_r))
leak1_i1_stall := withClock(data_gate_clk){RegNext(leak1_i1_stall_in,0.U)}
leak1_mode := leak1_i1_stall
leak1_i0_stall_in := ((io.dec_i0_decode_d & leak1_i1_stall) | (leak1_i0_stall & !io.dec_tlu_flush_lower_r))
leak1_i0_stall_in := ((io.dec_aln.dec_i0_decode_d & leak1_i1_stall) | (leak1_i0_stall & !io.dec_tlu_flush_lower_r))
leak1_i0_stall := withClock(data_gate_clk){RegNext(leak1_i0_stall_in,0.U)}
// 12b jal's can be predicted - these are calls
@ -474,23 +392,8 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
io.decode_exu.mul_p.bits.rs1_sign := i0_dp.rs1_sign
io.decode_exu.mul_p.bits.rs2_sign := i0_dp.rs2_sign
io.decode_exu.mul_p.bits.low := i0_dp.low
io.decode_exu.mul_p.bits.bext := i0_dp.bext
io.decode_exu.mul_p.bits.bdep := i0_dp.bdep
io.decode_exu.mul_p.bits.clmul := i0_dp.clmul
io.decode_exu.mul_p.bits.clmulh := i0_dp.clmulh
io.decode_exu.mul_p.bits.clmulr := i0_dp.clmulr
io.decode_exu.mul_p.bits.grev := i0_dp.grev
io.decode_exu.mul_p.bits.gorc := i0_dp.gorc
io.decode_exu.mul_p.bits.shfl := i0_dp.shfl
io.decode_exu.mul_p.bits.unshfl := i0_dp.unshfl
io.decode_exu.mul_p.bits.crc32_b := i0_dp.crc32_b
io.decode_exu.mul_p.bits.crc32_h := i0_dp.crc32_h
io.decode_exu.mul_p.bits.crc32_w := i0_dp.crc32_w
io.decode_exu.mul_p.bits.crc32c_b := i0_dp.crc32c_b
io.decode_exu.mul_p.bits.crc32c_h := i0_dp.crc32c_h
io.decode_exu.mul_p.bits.crc32c_w := i0_dp.crc32c_w
io.decode_exu.mul_p.bits.bfp := i0_dp.bfp
io.decode_exu.dec_extint_stall := withClock(data_gate_clk){RegNext(io.dec_tlu_flush_extint,0.U)}
io.lsu_p := 0.U.asTypeOf(io.lsu_p)
when (io.decode_exu.dec_extint_stall){
@ -498,8 +401,6 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
io.lsu_p.bits.word := 1.U(1.W)
io.lsu_p.bits.fast_int := 1.U(1.W)
io.lsu_p.valid := 1.U(1.W)
}.otherwise {
io.lsu_p.valid := lsu_decode_d
io.lsu_p.bits.load := i0_dp.load
@ -507,7 +408,6 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
io.lsu_p.bits.by := i0_dp.by
io.lsu_p.bits.half := i0_dp.half
io.lsu_p.bits.word := i0_dp.word
io.lsu_p.bits.stack := (i0r.rs1 === 2.U(5.W)) // stack reference
io.lsu_p.bits.load_ldst_bypass_d := load_ldst_bypass_d
io.lsu_p.bits.store_data_bypass_d := store_data_bypass_d
io.lsu_p.bits.store_data_bypass_m := store_data_bypass_m
@ -515,8 +415,8 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
}
//////////////////////////////////////
io.dec_alu.dec_csr_ren_d := i0_dp.csr_read & io.dec_ib0_valid_d//H: ing csr read enable signal decoded from decode_ctl going as input to EXU
csr_ren_qual_d := i0_dp.csr_read & i0_legal_decode_d.asBool //csr_ren_qual_d ed as csr_read above
io.dec_alu.dec_csr_ren_d := i0_dp.csr_read //H: assigning csr read enable signal decoded from decode_ctl going as input to EXU
csr_ren_qual_d := i0_dp.csr_read & i0_legal_decode_d.asBool //csr_ren_qual_d assigned as csr_read above
val i0_csr_write = i0_dp.csr_write & !io.dec_debug_fence_d
val csr_clr_d = i0_dp.csr_clr & i0_legal_decode_d.asBool
@ -524,19 +424,18 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val csr_write_d = i0_csr_write & i0_legal_decode_d.asBool
i0_csr_write_only_d := i0_csr_write & !i0_dp.csr_read
io.dec_csr_wen_unq_d := (i0_dp.csr_clr | i0_dp.csr_set | i0_csr_write) & io.dec_ib0_valid_d // for csr legal, can't write read-only csr
//dec_csr_wen_unq_d ed as csr_write above
val any_csr_d = i0_dp.csr_read | i0_csr_write
io.dec_csr_any_unq_d := any_csr_d & io.dec_ib0_valid_d
io.dec_csr_rdaddr_d := Fill(12,io.dec_csr_any_unq_d) & i0(31,20)
io.dec_csr_wraddr_r := Fill(12,(r_d.bits.csrwen & r_d.valid)) & r_d.bits.csrwaddr //r_d is a dest_pkt
io.dec_csr_wen_unq_d := (i0_dp.csr_clr | i0_dp.csr_set | i0_csr_write) // for csr legal, can't write read-only csr
//dec_csr_wen_unq_d assigned as csr_write above
io.dec_csr_rdaddr_d := i0(31,20)
io.dec_csr_wraddr_r := r_d.bits.csrwaddr //r_d is a dest_pkt
// make sure csr doesn't write same cycle as dec_tlu_flush_lower_wb
// also use valid so it's flushable
io.dec_csr_wen_r := r_d.bits.csrwen & r_d.valid & !io.dec_tlu_i0_kill_writeb_r
io.dec_csr_wen_r := r_d.bits.csrwen & r_d.valid & !io.dec_tlu_i0_kill_writeb_r;
// If we are writing MIE or MSTATUS, hold off the external interrupt for a cycle on the write.
io.dec_csr_stall_int_ff := ((r_d.bits.csrwaddr === "h300".U) | (r_d.bits.csrwaddr === "h304".U)) & r_d.bits.csrwen & r_d.valid & !io.dec_tlu_i0_kill_writeb_wb
io.dec_csr_stall_int_ff := ((r_d.bits.csrwaddr === "h300".U) | (r_d.bits.csrwaddr === "h304".U)) & r_d.bits.csrwen & r_d.valid & !io.dec_tlu_i0_kill_writeb_wb;
val csr_read_x = withClock(io.active_clk){RegNext(csr_ren_qual_d,init=0.B)}
val csr_clr_x = withClock(io.active_clk){RegNext(csr_clr_d, init=0.B)}
@ -545,8 +444,8 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val csr_imm_x = withClock(io.active_clk){RegNext(i0_dp.csr_imm, init=0.U)}
// perform the update operation if any
val csrimm_x = rvdffe(i0(19,15),i0_x_data_en & any_csr_d.asBool,clock,io.scan_mode)
val csr_rddata_x = rvdffe(io.dec_csr_rddata_d,i0_x_data_en & any_csr_d.asBool,clock,io.scan_mode)
val csrimm_x = rvdffe(i0(19,15),i0_x_data_en.asBool,clock,io.scan_mode)
val csr_rddata_x = rvdffe(io.dec_csr_rddata_d,i0_x_data_en.asBool,clock,io.scan_mode)
val csr_mask_x = Mux1H(Seq(
csr_imm_x.asBool -> Cat(repl(27,0.U),csrimm_x(4,0)),
@ -559,7 +458,10 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
// pause instruction
val clear_pause = (io.dec_tlu_flush_lower_r & !io.dec_tlu_flush_pause_r) | (pause_state & (write_csr_data === Cat(Fill(31,0.U),write_csr_data(0)))) // if 0 or 1 then exit pause state - 1 cycle pause
pause_state_in := (io.dec_tlu_wr_pause_r | pause_state) & !clear_pause
pause_state := withClock(data_gate_clk){RegNext(pause_state_in, 0.U)}
io.dec_pause_state := pause_state
tlu_wr_pause_r1 := withClock(data_gate_clk){RegNext(io.dec_tlu_wr_pause_r, 0.U)}
tlu_wr_pause_r2 := withClock(data_gate_clk){RegNext(tlu_wr_pause_r1, 0.U)}
//pause for clock gating
io.dec_pause_state_cg := (pause_state & (!tlu_wr_pause_r1 && !tlu_wr_pause_r2))
// end pause
@ -567,15 +469,15 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val write_csr_data_in = Mux(pause_state,(write_csr_data - 1.U(32.W)),
Mux(io.dec_tlu_wr_pause_r,io.dec_csr_wrdata_r,write_csr_data_x))
val csr_data_wen = ((csr_clr_x | csr_set_x | csr_write_x) & csr_read_x) | io.dec_tlu_wr_pause_r | pause_state
write_csr_data := rvdffe(write_csr_data_in,csr_data_wen,io.free_l2clk,io.scan_mode)
write_csr_data := rvdffe(write_csr_data_in,csr_data_wen,clock,io.scan_mode)
// will hold until write-back at which time the CSR will be updated while GPR is possibly written with prior CSR
val pause_stall = pause_state
// for csr write only data is produced by the alu
io.dec_csr_wrdata_r := Mux((r_d.bits.csrwonly & r_d.valid).asBool,i0_result_corr_r,write_csr_data)
io.dec_csr_wrdata_r := Mux(r_d.bits.csrwonly.asBool,i0_result_corr_r,write_csr_data)
val prior_csr_write = x_d.bits.csrwonly | r_d.bits.csrwonly | wbd.bits.csrwonly
val prior_csr_write = x_d.bits.csrwonly | r_d.bits.csrwonly | wbd.bits.csrwonly;
val debug_fence_i = io.dec_debug_fence_d & io.dbg_dctl.dbg_cmd_wrdata(0)
val debug_fence_raw = io.dec_debug_fence_d & io.dbg_dctl.dbg_cmd_wrdata(1)
@ -586,15 +488,18 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
// some CSR writes need to be postsync'd
val i0_postsync = i0_dp.postsync | io.dec_tlu_postsync_d | debug_fence_i | (i0_csr_write_only_d & (i0(31,20) === "h7c2".U))
val bitmanip_legal = WireInit(Bool(),0.B)
val i0_legal = i0_dp.legal & (!any_csr_d | io.dec_csr_legal_d) & bitmanip_legal
val any_csr_d = i0_dp.csr_read | i0_csr_write
io.dec_csr_any_unq_d := any_csr_d
val i0_legal = i0_dp.legal & (!any_csr_d | io.dec_csr_legal_d)
val i0_inst_d = Mux(io.dec_i0_pc4_d,i0,Cat(repl(16,0.U), io.dec_aln.ifu_i0_cinst))
// illegal inst handling
val shift_illegal = io.dec_i0_decode_d & !i0_legal//lm: valid but not legal
val shift_illegal = io.dec_aln.dec_i0_decode_d & !i0_legal//lm: valid but not legal
val illegal_inst_en = shift_illegal & !illegal_lockout
io.dec_illegal_inst := rvdffe(i0_inst_d,illegal_inst_en,clock,io.scan_mode)
illegal_lockout_in := (shift_illegal | illegal_lockout) & !flush_final_r
illegal_lockout := withClock(data_gate_clk){RegNext(illegal_lockout_in, 0.U)}
val i0_div_prior_div_stall = i0_dp.div & io.dec_div_active
//stalls signals
val i0_block_raw_d = (i0_dp.csr_read & prior_csr_write) | io.decode_exu.dec_extint_stall | pause_stall |
@ -608,15 +513,15 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val i0_exublock_d = i0_block_raw_d
//decode valid
io.dec_i0_decode_d := io.dec_ib0_valid_d & !i0_block_d & !io.dec_tlu_flush_lower_r & !flush_final_r
io.dec_aln.dec_i0_decode_d := io.dec_ib0_valid_d & !i0_block_d & !io.dec_tlu_flush_lower_r & !flush_final_r
val i0_exudecode_d = io.dec_ib0_valid_d & !i0_exublock_d & !io.dec_tlu_flush_lower_r & !flush_final_r
val i0_exulegal_decode_d = i0_exudecode_d & i0_legal
// performance monitor signals
io.dec_pmu_instr_decoded := io.dec_i0_decode_d
io.dec_pmu_decode_stall := io.dec_ib0_valid_d & !io.dec_i0_decode_d
io.dec_pmu_postsync_stall := postsync_stall.asBool & io.dec_ib0_valid_d
io.dec_pmu_presync_stall := presync_stall.asBool & io.dec_ib0_valid_d
io.dec_pmu_instr_decoded := io.dec_aln.dec_i0_decode_d
io.dec_pmu_decode_stall := io.dec_ib0_valid_d & !io.dec_aln.dec_i0_decode_d
io.dec_pmu_postsync_stall := postsync_stall.asBool
io.dec_pmu_presync_stall := presync_stall.asBool
val prior_inflight_x = x_d.valid
val prior_inflight_wb = r_d.valid
@ -624,22 +529,22 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val prior_inflight_eff = Mux(i0_dp.div,prior_inflight_x,prior_inflight)
presync_stall := (i0_presync & prior_inflight_eff)
postsync_stall := withClock(data_gate_clk){RegNext(ps_stall_in, 0.U)}
// illegals will postsync
ps_stall_in := (io.dec_i0_decode_d & (i0_postsync | !i0_legal) ) | ( postsync_stall & prior_inflight_x)
ps_stall_in := (io.dec_aln.dec_i0_decode_d & (i0_postsync | !i0_legal) ) | ( postsync_stall & prior_inflight_x)
io.dec_alu.dec_i0_alu_decode_d := i0_exulegal_decode_d & i0_dp.alu
io.decode_exu.dec_i0_branch_d := i0_dp.condbr | i0_dp.jal | i0_br_error_all
lsu_decode_d := i0_legal_decode_d & i0_dp.lsu
mul_decode_d := i0_exulegal_decode_d & i0_dp.mul
div_decode_d := i0_exulegal_decode_d & i0_dp.div
io.decode_exu.dec_qual_lsu_d := i0_dp.lsu
io.dec_tlu_i0_valid_r := r_d.valid & !io.dec_tlu_flush_lower_wb
//traps for TLU (tlu stuff)
d_t.legal := i0_legal_decode_d
d_t.icaf := i0_icaf_d & i0_legal_decode_d // dbecc is icaf exception
d_t.icaf_second := io.dec_i0_icaf_second_d & i0_legal_decode_d // this includes icaf and dbecc
d_t.icaf_f1 := io.dec_i0_icaf_f1_d & i0_legal_decode_d // this includes icaf and dbecc
d_t.icaf_type := io.dec_i0_icaf_type_d
d_t.fence_i := (i0_dp.fence_i | debug_fence_i) & i0_legal_decode_d
@ -649,15 +554,17 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
d_t.pmu_divide := 0.U(1.W)
d_t.pmu_lsu_misaligned := 0.U(1.W)
d_t.i0trigger := io.dec_i0_trigger_match_d & repl(4,io.dec_i0_decode_d)
d_t.i0trigger := io.dec_i0_trigger_match_d & repl(4,io.dec_aln.dec_i0_decode_d)
x_t := rvdfflie(d_t,clock,reset.asAsyncReset,i0_x_ctl_en.asBool,io.scan_mode, elements = 3)
x_t := rvdffe(d_t,i0_x_ctl_en.asBool,clock,io.scan_mode)
x_t_in := x_t
x_t_in.i0trigger := x_t.i0trigger & ~(repl(4,io.dec_tlu_flush_lower_wb))
r_t := rvdfflie(x_t_in,clock,reset.asAsyncReset,i0_x_ctl_en.asBool,io.scan_mode, elements = 3)
r_t := rvdffe(x_t_in,i0_x_ctl_en.asBool,clock,io.scan_mode)
val lsu_trigger_match_r = RegNext(io.lsu_trigger_match_m, 0.U)
val lsu_pmu_misaligned_r = RegNext(io.lsu_pmu_misaligned_m, 0.U)
r_t_in := r_t
@ -670,10 +577,11 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
io.dec_tlu_packet_r.pmu_divide := r_d.bits.i0div & r_d.valid
// end tlu stuff
flush_final_r := withClock(data_gate_clk){RegNext(io.exu_flush_final, 0.U)}
io.dec_i0_decode_d := io.dec_ib0_valid_d & !i0_block_d & !io.dec_tlu_flush_lower_r & !flush_final_r
io.dec_aln.dec_i0_decode_d := io.dec_ib0_valid_d & !i0_block_d & !io.dec_tlu_flush_lower_r & !flush_final_r
i0r.rs1 := i0(19,15) //H: ing reg packets the instructions bits
i0r.rs1 := i0(19,15) //H: assigning reg packets the instructions bits
i0r.rs2 := i0(24,20)
i0r.rd := i0(11,7)
@ -686,74 +594,18 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val i0_jalimm20 = i0_dp.jal & i0_dp.imm20 // H:jal (used at line 915)
val i0_uiimm20 = !i0_dp.jal & i0_dp.imm20
// io.decode_exu.dec_i0_immed_d := Mux1H(Seq(
// i0_dp.csr_read -> io.dec_csr_rddata_d,
// !i0_dp.csr_read -> i0_immed_d))
io.decode_exu.dec_i0_immed_d := Mux1H(Seq(
i0_dp.csr_read -> io.dec_csr_rddata_d,
!i0_dp.csr_read -> i0_immed_d))
i0_immed_d := Mux1H(Seq(
i0_dp.imm12 -> Cat(repl(20,i0(31)),i0(31,20)), // jalr
i0_dp.shimm5 -> Cat(repl(27,0.U),i0(24,20)),
i0_jalimm20 -> Cat(repl(12,i0(31)),i0(19,12),i0(20),i0(30,21),0.U),
i0_uiimm20 -> Cat(i0(31,12),repl(12,0.U)),
(i0_csr_write_only_d & i0_dp.csr_imm).asBool -> Cat(repl(27,0.U),i0(19,15)))) // for csr's that only write
val bitmanip_zbb_legal = WireInit(Bool(),0.B)
val bitmanip_zbs_legal = WireInit(Bool(),0.B)
val bitmanip_zbe_legal = WireInit(Bool(),0.B)
val bitmanip_zbc_legal = WireInit(Bool(),0.B)
val bitmanip_zbp_legal = WireInit(Bool(),0.B)
val bitmanip_zbr_legal = WireInit(Bool(),0.B)
val bitmanip_zbf_legal = WireInit(Bool(),0.B)
val bitmanip_zba_legal = WireInit(Bool(),0.B)
val bitmanip_zbb_zbp_legal = WireInit(Bool(),0.B)
if (BITMANIP_ZBB == 1)
bitmanip_zbb_legal := 1.B
else
bitmanip_zbb_legal := !(i0_dp.zbb & !i0_dp.zbp)
if (BITMANIP_ZBS == 1)
bitmanip_zbs_legal := 1.B
else
bitmanip_zbs_legal := !i0_dp.zbs
if (BITMANIP_ZBE == 1)
bitmanip_zbe_legal := 1.B
else
bitmanip_zbe_legal := !i0_dp.zbe
if (BITMANIP_ZBC == 1)
bitmanip_zbc_legal := 1.B
else
bitmanip_zbc_legal := !i0_dp.zbc
if (BITMANIP_ZBP == 1)
bitmanip_zbp_legal := 1.B
else
bitmanip_zbp_legal := !(i0_dp.zbp & !i0_dp.zbb)
if (BITMANIP_ZBR == 1)
bitmanip_zbr_legal := 1.B
else
bitmanip_zbr_legal := !i0_dp.zbr
if (BITMANIP_ZBF == 1)
bitmanip_zbf_legal := 1.B
else
bitmanip_zbf_legal := !i0_dp.zbf
if (BITMANIP_ZBA == 1)
bitmanip_zba_legal := 1.B
else
bitmanip_zba_legal := !i0_dp.zba
if ( (BITMANIP_ZBB == 1) | (BITMANIP_ZBP == 1) )
bitmanip_zbb_zbp_legal := 1.B
else
bitmanip_zbb_zbp_legal := !(i0_dp.zbb & i0_dp.zbp)
bitmanip_legal := bitmanip_zbb_legal & bitmanip_zbs_legal & bitmanip_zbe_legal & bitmanip_zbc_legal & bitmanip_zbp_legal & bitmanip_zbr_legal & bitmanip_zbf_legal & bitmanip_zba_legal & bitmanip_zbb_zbp_legal
i0_legal_decode_d := io.dec_i0_decode_d & i0_legal
i0_legal_decode_d := io.dec_aln.dec_i0_decode_d & i0_legal
i0_d_c.mul := i0_dp.mul & i0_legal_decode_d
i0_d_c.load := i0_dp.load & i0_legal_decode_d
@ -761,7 +613,7 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val i0_x_c = withClock(io.active_clk){RegEnable(i0_d_c,0.U.asTypeOf(i0_d_c), i0_x_ctl_en.asBool)}
val i0_r_c = withClock(io.active_clk){RegEnable(i0_x_c,0.U.asTypeOf(i0_x_c), i0_r_ctl_en.asBool)}
i0_pipe_en := Cat(io.dec_i0_decode_d,withClock(io.active_clk){RegNext(i0_pipe_en(3,1), init=0.U)})
i0_pipe_en := Cat(io.dec_aln.dec_i0_decode_d,withClock(io.active_clk){RegNext(i0_pipe_en(3,1), init=0.U)})
i0_x_ctl_en := (i0_pipe_en(3,2).orR | io.clk_override)
i0_r_ctl_en := (i0_pipe_en(2,1).orR | io.clk_override)
@ -769,29 +621,30 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
i0_x_data_en := ( i0_pipe_en(3) | io.clk_override)
i0_r_data_en := ( i0_pipe_en(2) | io.clk_override)
i0_wb_data_en := ( i0_pipe_en(1) | io.clk_override)
i0_wb1_data_en := ( i0_pipe_en(0) | io.clk_override)
io.decode_exu.dec_data_en := Cat(i0_x_data_en, i0_r_data_en)
io.decode_exu.dec_ctl_en := Cat(i0_x_ctl_en, i0_r_ctl_en)
d_d.bits.i0rd := i0r.rd
d_d.bits.i0v := i0_rd_en_d & i0_legal_decode_d
d_d.valid := io.dec_i0_decode_d // has flush_final_r
d_d.valid := io.dec_aln.dec_i0_decode_d // has flush_final_r
d_d.bits.i0load := i0_dp.load & i0_legal_decode_d
d_d.bits.i0store := i0_dp.store & i0_legal_decode_d
d_d.bits.i0div := i0_dp.div & i0_legal_decode_d
d_d.bits.csrwen := io.dec_csr_wen_unq_d & i0_legal_decode_d
d_d.bits.csrwonly := i0_csr_write_only_d & io.dec_i0_decode_d
d_d.bits.csrwaddr := Mux(d_d.bits.csrwen, i0(31,20), 0.U)
d_d.bits.csrwonly := i0_csr_write_only_d & io.dec_aln.dec_i0_decode_d
d_d.bits.csrwaddr := i0(31,20)
x_d := rvdfflie(d_d,clock,reset.asAsyncReset(), i0_x_ctl_en.asBool,io.scan_mode,elements = 4)
x_d := rvdffe(d_d, i0_x_ctl_en.asBool,clock,io.scan_mode)
val x_d_in = Wire(Valid(new dest_pkt_t))
x_d_in := x_d
x_d_in.bits.i0v := x_d.bits.i0v & !io.dec_tlu_flush_lower_wb & !io.dec_tlu_flush_lower_r
x_d_in.valid := x_d.valid & !io.dec_tlu_flush_lower_wb & !io.dec_tlu_flush_lower_r
r_d := rvdfflie(x_d_in,clock,reset.asAsyncReset(),i0_r_ctl_en.asBool,io.scan_mode, elements = 4)
r_d := rvdffe(x_d_in,i0_r_ctl_en.asBool,clock,io.scan_mode)
r_d_in := r_d
r_d_in.bits.i0rd := r_d.bits.i0rd
@ -800,15 +653,14 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
r_d_in.bits.i0load := r_d.bits.i0load & !io.dec_tlu_flush_lower_wb
r_d_in.bits.i0store := r_d.bits.i0store & !io.dec_tlu_flush_lower_wb
wbd := rvdfflie(r_d_in,clock,reset.asAsyncReset(),i0_wb_ctl_en.asBool,io.scan_mode, elements = 4)
wbd := rvdffe(r_d_in,i0_wb_ctl_en.asBool,clock,io.scan_mode)
io.dec_i0_waddr_r := r_d_in.bits.i0rd
i0_wen_r := r_d_in.bits.i0v & !io.dec_tlu_i0_kill_writeb_r
io.dec_i0_wen_r := i0_wen_r & !r_d_in.bits.i0div & !i0_load_kill_wen_r // don't write a nonblock load 1st time down the pipe
io.dec_i0_wdata_r := i0_result_corr_r
val i0_result_r_raw = rvdffe(i0_result_x,(i0_r_data_en & (x_d.bits.i0v | x_d.bits.csrwen | debug_valid_x)) === 1.B,clock,io.scan_mode)
val i0_result_r_raw = rvdffe(i0_result_x,i0_r_data_en.asBool,clock,io.scan_mode)
if ( LOAD_TO_USE_PLUS1) {
i0_result_x := io.decode_exu.exu_i0_result_x
i0_result_r := Mux((r_d.bits.i0v & r_d.bits.i0load).asBool,io.lsu_result_m, i0_result_r_raw)
@ -842,32 +694,31 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
io.dec_div.dec_div_cancel := nonblock_div_cancel.asBool
val i0_div_decode_d = i0_legal_decode_d & i0_dp.div
div_active_in := i0_div_decode_d | (io.dec_div_active & !io.exu_div_wren & !nonblock_div_cancel)
val div_active_in = i0_div_decode_d | (io.dec_div_active & !io.exu_div_wren & !nonblock_div_cancel)
// io.dec_div_active := withClock(io.free_l2clk){RegNext(div_active_in, 0.U)}
io.dec_div_active := withClock(io.free_clk){RegNext(div_active_in, 0.U)}
// nonblocking div scheme
i0_nonblock_div_stall := (io.decode_exu.dec_i0_rs1_en_d & io.dec_div_active & (io.div_waddr_wb === i0r.rs1)) |
(io.decode_exu.dec_i0_rs2_en_d & io.dec_div_active & (io.div_waddr_wb === i0r.rs2))
io.div_waddr_wb := RegEnable(i0r.rd,0.U,i0_div_decode_d.asBool)
///div end
//for tracing instruction
val i0_wb_en = i0_wb_data_en
val trace_enable = ~io.dec_tlu_trace_disable
val i0_wb1_en = i0_wb1_data_en
io.div_waddr_wb := rvdffe(i0r.rd,i0_div_decode_d.asBool(),clock,io.scan_mode)
val i0_inst_x = rvdffe(i0_inst_d,(i0_x_data_en & trace_enable),clock,io.scan_mode)
val i0_inst_r = rvdffe(i0_inst_x,(i0_r_data_en & trace_enable),clock,io.scan_mode)
val div_inst = rvdffe(i0_inst_d(24,7),i0_div_decode_d.asBool,clock,io.scan_mode)
val i0_inst_x = rvdffe(i0_inst_d,i0_x_data_en.asBool,clock,io.scan_mode)
val i0_inst_r = rvdffe(i0_inst_x,i0_r_data_en.asBool,clock,io.scan_mode)
val i0_inst_wb_in = i0_inst_r
val i0_inst_wb = rvdffe(i0_inst_wb_in,(i0_wb_en & trace_enable),clock,io.scan_mode)
val i0_pc_wb = rvdffe(io.dec_tlu_i0_pc_r,(i0_wb_en & trace_enable),clock,io.scan_mode)
val i0_inst_wb = rvdffe(i0_inst_wb_in,i0_wb_en.asBool,clock,io.scan_mode)
io.dec_i0_inst_wb1 := rvdffe(i0_inst_wb,i0_wb1_en.asBool,clock,io.scan_mode)
val i0_pc_wb = rvdffe(io.dec_tlu_i0_pc_r,i0_wb_en.asBool,clock,io.scan_mode)
io.dec_i0_inst_wb := i0_inst_wb
io.dec_i0_pc_wb := i0_pc_wb
val dec_i0_pc_r = rvdffpcie(io.dec_alu.exu_i0_pc_x,i0_r_data_en.asBool,reset.asAsyncReset(),clock,io.scan_mode)
io.dec_i0_pc_wb1 := rvdffe(i0_pc_wb,i0_wb1_en.asBool,clock,io.scan_mode)
val dec_i0_pc_r = rvdffe(io.dec_alu.exu_i0_pc_x,i0_r_data_en.asBool,clock,io.scan_mode)
io.dec_tlu_i0_pc_r := dec_i0_pc_r
@ -913,13 +764,22 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
i0_rs2bypass := Cat((i0_rs2_depth_d(0) & (i0_rs2_class_d.alu | i0_rs2_class_d.mul)),(i0_rs2_depth_d(0) & (i0_rs2_class_d.load)),(i0_rs2_depth_d(1) & (i0_rs2_class_d.alu | i0_rs2_class_d.mul | i0_rs2_class_d.load)))
io.decode_exu.dec_i0_rs1_bypass_en_d := Cat(!i0_rs1bypass(0) & !i0_rs1bypass(1) & !i0_rs1bypass(2) & i0_rs1_nonblock_load_bypass_en_d,i0_rs1bypass(2),i0_rs1bypass(1),i0_rs1bypass(0) )
io.decode_exu.dec_i0_rs2_bypass_en_d := Cat(!i0_rs2bypass(0) & !i0_rs2bypass(1) & !i0_rs2bypass(2) & i0_rs2_nonblock_load_bypass_en_d,i0_rs2bypass(2),i0_rs2bypass(1),i0_rs2bypass(0) )
io.decode_exu.dec_i0_rs1_bypass_en_d := Cat(i0_rs1bypass(2),(i0_rs1bypass(1) | i0_rs1bypass(0) | (!i0_rs1bypass(2) & i0_rs1_nonblock_load_bypass_en_d)))
io.decode_exu.dec_i0_rs2_bypass_en_d := Cat(i0_rs2bypass(2),(i0_rs2bypass(1) | i0_rs2bypass(0) | (!i0_rs2bypass(2) & i0_rs2_nonblock_load_bypass_en_d)))
io.decode_exu.dec_i0_result_r := i0_result_r
io.decode_exu.dec_i0_rs1_bypass_data_d := Mux1H(Seq(
i0_rs1bypass(1).asBool -> io.lsu_result_m,
i0_rs1bypass(0).asBool -> i0_result_r,
(!i0_rs1bypass(1) & !i0_rs1bypass(0) & i0_rs1_nonblock_load_bypass_en_d).asBool -> io.dctl_busbuff.lsu_nonblock_load_data,
))
io.decode_exu.dec_i0_rs2_bypass_data_d := Mux1H(Seq(
i0_rs2bypass(1).asBool -> io.lsu_result_m,
i0_rs2bypass(0).asBool -> i0_result_r,
(!i0_rs2bypass(1) & !i0_rs2bypass(0) & i0_rs2_nonblock_load_bypass_en_d).asBool -> io.dctl_busbuff.lsu_nonblock_load_data,
))
io.dec_lsu_valid_raw_d := ((io.dec_ib0_valid_d & (i0_dp_raw.load | i0_dp_raw.store) & !io.dctl_dma.dma_dccm_stall_any & !i0_block_raw_d) | io.decode_exu.dec_extint_stall)
io.dec_lsu_offset_d := Mux1H(Seq(
(!io.decode_exu.dec_extint_stall & i0_dp.lsu & i0_dp.load).asBool -> i0(31,20),
(!io.decode_exu.dec_extint_stall & i0_dp.lsu & i0_dp.store).asBool -> Cat(i0(31,25),i0(11,7))))
}
}

View File

@ -47,20 +47,20 @@ class dec_gpr_ctl extends Module with lib with RequireAsyncReset{
gpr_in(0):=0.U
io.gpr_exu.gpr_i0_rs1_d:=0.U
io.gpr_exu.gpr_i0_rs2_d:=0.U
// GPR Write logic
for (j <-1 until 32){
w0v(j) := io.wen0 & (io.waddr0===j.asUInt)
w1v(j) := io.wen1 & (io.waddr1===j.asUInt)
w2v(j) := io.wen2 & (io.waddr2===j.asUInt)
gpr_in(j) := (Fill(32,w0v(j)) & io.wd0) | (Fill(32,w1v(j)) & io.wd1) | (Fill(32,w2v(j)) & io.wd2)
}
// GPR Write logic
for (j <-1 until 32){
w0v(j) := io.wen0 & (io.waddr0===j.asUInt)
w1v(j) := io.wen1 & (io.waddr1===j.asUInt)
w2v(j) := io.wen2 & (io.waddr2===j.asUInt)
gpr_in(j) := (Fill(32,w0v(j)) & io.wd0) | (Fill(32,w1v(j)) & io.wd1) | (Fill(32,w2v(j)) & io.wd2)
}
gpr_wr_en:= (w0v.reverse).reduceRight(Cat(_,_)) | (w1v.reverse).reduceRight(Cat(_,_)) | (w2v.reverse).reduceRight(Cat(_,_))
// GPR Write Enables for power savings
for (j <-1 until 32){
gpr_out(j):=rvdffe(gpr_in(j),gpr_wr_en(j),clock,io.scan_mode)
}
// GPR Read logic
for (j <-1 until 32){
gpr_out(j):=rvdffe(gpr_in(j),gpr_wr_en(j),clock,io.scan_mode)
}
// GPR Read logic
io.gpr_exu.gpr_i0_rs1_d:=Mux1H((1 until 32).map(i => (io.raddr0===i.U).asBool -> gpr_out(i)))
io.gpr_exu.gpr_i0_rs2_d:=Mux1H((1 until 32).map(i => (io.raddr1===i.U).asBool -> gpr_out(i)))
}

View File

@ -10,8 +10,6 @@ class dec_ib_ctl_IO extends Bundle with param{
val ifu_ib = Flipped(new aln_ib)
val ib_exu = Flipped(new ib_exu)
val dbg_ib = new dbg_ib
val dec_debug_valid_d =Output(UInt(1.W))
val dec_ib0_valid_d =Output(UInt(1.W)) // ib0 valid
val dec_i0_icaf_type_d =Output(UInt(2.W)) // i0 instruction access fault type
val dec_i0_instr_d =Output(UInt(32.W)) // i0 inst at decode
@ -20,18 +18,15 @@ class dec_ib_ctl_IO extends Bundle with param{
val dec_i0_bp_index =Output(UInt(((BTB_ADDR_HI-BTB_ADDR_LO)+1).W)) // i0 branch index
val dec_i0_bp_fghr =Output(UInt(BHT_GHR_SIZE.W)) // BP FGHR
val dec_i0_bp_btag =Output(UInt(BTB_BTAG_SIZE.W)) // BP tag
val ifu_i0_fa_index =Input(UInt(log2Ceil(BTB_SIZE).W))
val dec_i0_bp_fa_index =Output(UInt(log2Ceil(BTB_SIZE).W))
val dec_i0_icaf_d =Output(UInt(1.W)) // i0 instruction access fault at decode
val dec_i0_icaf_second_d =Output(UInt(1.W)) // i0 instruction access fault at decode for f1 fetch group
val dec_i0_icaf_f1_d =Output(UInt(1.W)) // i0 instruction access fault at decode for f1 fetch group
val dec_i0_dbecc_d =Output(UInt(1.W)) // i0 double-bit error at decode
val dec_debug_fence_d =Output(UInt(1.W)) // debug fence inst
}
class dec_ib_ctl extends Module with param{
val io=IO(new dec_ib_ctl_IO)
io.dec_i0_icaf_second_d :=io.ifu_ib.ifu_i0_icaf_second
io.dec_i0_icaf_f1_d :=io.ifu_ib.ifu_i0_icaf_f1
io.dec_i0_dbecc_d :=io.ifu_ib.ifu_i0_dbecc
io.dec_i0_icaf_d :=io.ifu_ib.ifu_i0_icaf
io.ib_exu.dec_i0_pc_d :=io.ifu_ib.ifu_i0_pc
@ -41,7 +36,6 @@ class dec_ib_ctl extends Module with param{
io.dec_i0_bp_index :=io.ifu_ib.ifu_i0_bp_index
io.dec_i0_bp_fghr :=io.ifu_ib.ifu_i0_bp_fghr
io.dec_i0_bp_btag :=io.ifu_ib.ifu_i0_bp_btag
io.dec_i0_bp_fa_index := io.ifu_i0_fa_index
// GPR accesses
// put reg to read on rs1
@ -58,7 +52,7 @@ class dec_ib_ctl extends Module with param{
val debug_valid =io.dbg_ib.dbg_cmd_valid & (io.dbg_ib.dbg_cmd_type =/= 2.U)
val debug_read =debug_valid & !io.dbg_ib.dbg_cmd_write
val debug_write =debug_valid & io.dbg_ib.dbg_cmd_write
io.dec_debug_valid_d := debug_valid
val debug_read_gpr = debug_read & (io.dbg_ib.dbg_cmd_type===0.U)
val debug_write_gpr = debug_write & (io.dbg_ib.dbg_cmd_type===0.U)
val debug_read_csr = debug_read & (io.dbg_ib.dbg_cmd_type===1.U)
@ -68,11 +62,11 @@ class dec_ib_ctl extends Module with param{
val dcsr = io.dbg_ib.dbg_cmd_addr(11,0)
val ib0_debug_in =Mux1H(Seq(
debug_read_gpr.asBool -> Cat(Fill(12,0.U(1.W)),dreg,"b110000000110011".U),
debug_write_gpr.asBool -> Cat("b00000000000000000110".U(20.W),dreg,"b0110011".U(7.W)),
debug_read_csr.asBool -> Cat(dcsr,"b00000010000001110011".U(20.W)),
debug_write_csr.asBool -> Cat(dcsr,"b00000001000001110011".U(20.W))
))
debug_read_gpr.asBool -> Cat(Fill(12,0.U(1.W)),dreg,"b110000000110011".U),
debug_write_gpr.asBool -> Cat("b00000000000000000110".U(20.W),dreg,"b0110011".U(7.W)),
debug_read_csr.asBool -> Cat(dcsr,"b00000010000001110011".U(20.W)),
debug_write_csr.asBool -> Cat(dcsr,"b00000001000001110011".U(20.W))
))
// machine is in halted state, pipe empty, write will always happen next cycle
io.ib_exu.dec_debug_wdata_rs1_d := debug_write_gpr | debug_write_csr
@ -83,4 +77,5 @@ class dec_ib_ctl extends Module with param{
io.dec_ib0_valid_d := io.ifu_ib.ifu_i0_valid | debug_valid
io.dec_i0_instr_d := Mux(debug_valid.asBool,ib0_debug_in,io.ifu_ib.ifu_i0_instr)
}

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
import chisel3._
import chisel3.util._
import include._
//import dbg._
import dbg._
import scala.collection._
import lib._
@ -12,89 +12,127 @@ class dma_ctrl extends Module with lib with RequireAsyncReset {
val dma_bus_clk_en = Input(Bool()) // slave bus clock enable
val clk_override = Input(Bool())
val scan_mode = Input(Bool())
val dbg_cmd_size = Input(UInt(2.W))
val dbg_cmd_size = Input(UInt(2.W)) // size of the abstract mem access debug command
val dma_dbg_rddata = Output(UInt(32.W))
val dma_dbg_cmd_done = Output(Bool())
val dma_dbg_cmd_fail = Output(Bool())
val dma_dbg_rddata = Output(UInt(32.W))
val iccm_dma_rvalid = Input(Bool())
val iccm_dma_ecc_error = Input(Bool())
val iccm_dma_rtag = Input(UInt(3.W))
val iccm_dma_rdata = Input(UInt(64.W))
val dma_active = Output(Bool())
val iccm_ready = Input(Bool())
val dbg_dec_dma = new dec_dbg()
val dbg_dma = new dbg_dma()
val dec_dma = Flipped(new dec_dma())
val iccm_dma_rvalid = Input(Bool()) // iccm data valid for DMA read
val iccm_dma_ecc_error = Input(Bool()) // ECC error on DMA read
val iccm_dma_rtag = Input(UInt(3.W)) // Tag of the DMA req
val iccm_dma_rdata = Input(UInt(64.W)) // iccm data for DMA read
val iccm_ready = Input(Bool()) // iccm ready to accept DMA request
// AXI Write Channels
val dma_axi = Flipped(new axi_channels(DMA_BUS_TAG))
val lsu_dma = Flipped(new lsu_dma)
val ifu_dma = Flipped(new ifu_dma)// AXI Write Channel
val dma_axi = Flipped(new axi_channels(DMA_BUS_TAG))
val ifu_dma = Flipped(new ifu_dma)
})
val DEPTH = DMA_BUF_DEPTH
val DEPTH_PTR = log2Ceil(DEPTH)
val DEPTH_PTR = log2Ceil(DMA_BUF_DEPTH)
val NACK_COUNT = 7
val fifo_error = Wire(Vec(DMA_BUF_DEPTH, UInt(2.W)))
val fifo_error_bus = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
val fifo_done = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
val fifo_addr = Wire(Vec(DMA_BUF_DEPTH, UInt(32.W)))
val fifo_sz = Wire(Vec(DMA_BUF_DEPTH,UInt(3.W)))
val fifo_byteen = Wire(Vec(DMA_BUF_DEPTH,UInt(8.W)))
val fifo_data = Wire(Vec(DMA_BUF_DEPTH,UInt(64.W)))
val fifo_tag = Wire(Vec(DMA_BUF_DEPTH,UInt(DMA_BUS_TAG.W)))
val fifo_mid = Wire(Vec(DMA_BUF_DEPTH,UInt((DMA_BUS_ID:Int).W)))
val fifo_prty = Wire(Vec(DMA_BUF_DEPTH,UInt(DMA_BUS_PRTY.W)))
val fifo_error_en = WireInit(UInt(DMA_BUF_DEPTH.W),0.U)
val fifo_error_in = Wire(Vec(DMA_BUF_DEPTH, UInt(2.W)))
val fifo_data_in = Wire(Vec(DMA_BUF_DEPTH,UInt(64.W)))
val RspPtr = WireInit(UInt((log2Ceil(DMA_BUF_DEPTH)).W), 0.U)
val WrPtr = WireInit(UInt((log2Ceil(DMA_BUF_DEPTH)).W), 0.U)
val RdPtr = WireInit(UInt((log2Ceil(DMA_BUF_DEPTH)).W), 0.U)
val NxtRspPtr = WireInit(UInt((log2Ceil(DMA_BUF_DEPTH)).W), 0.U)
val NxtWrPtr = WireInit(UInt((log2Ceil(DMA_BUF_DEPTH)).W), 0.U)
val NxtRdPtr = WireInit(UInt((log2Ceil(DMA_BUF_DEPTH)).W), 0.U)
val dma_dbg_cmd_error = WireInit(UInt(1.W),0.U)
val dma_dbg_cmd_done_q = WireInit(UInt(1.W), 0.U)
val fifo_empty = WireInit(UInt(1.W), 0.U)
val dma_address_error = WireInit(UInt(1.W), 0.U)
val dma_alignment_error = WireInit(UInt(1.W), 0.U)
val num_fifo_vld = WireInit(UInt(4.W),0.U)
val dma_mem_req = WireInit(UInt(1.W), 0.U)
val dma_mem_addr_int = WireInit(UInt(32.W), 0.U)
val dma_mem_sz_int = WireInit(UInt(3.W), 0.U)
val dma_mem_byteen = WireInit(UInt(8.W), 0.U)
val dma_nack_count = WireInit(UInt(3.W), 0.U)
val dma_nack_count_csr = WireInit(UInt(3.W), 0.U)
val bus_rsp_valid = WireInit(UInt(1.W), 0.U)
val bus_rsp_sent = WireInit(UInt(1.W), 0.U)
val bus_cmd_valid = WireInit(UInt(1.W), 0.U)
val bus_cmd_sent = WireInit(UInt(1.W), 0.U)
val bus_cmd_write = WireInit(UInt(1.W), 0.U)
val bus_cmd_posted_write = WireInit(UInt(1.W), 0.U)
val dma_dbg_mem_wrdata = WireInit(UInt(32.W), 0.U)
val bus_cmd_addr = WireInit(UInt(32.W), 0.U)
val bus_cmd_byteen = WireInit(UInt(8.W), 0.U)
val bus_cmd_sz = WireInit(UInt(3.W), 0.U)
val bus_cmd_write = WireInit(Bool(), false.B)
val bus_cmd_posted_write = WireInit(Bool(), false.B)
// Clock Gating logic
val bus_cmd_valid = WireInit(Bool(),0.B)
val bus_rsp_valid = WireInit(Bool(),0.B)
val dma_dbg_cmd_done_q = WireInit(Bool(),0.B)
val fifo_valid = WireInit(UInt(DEPTH.W),0.U)
val dma_buffer_c1_clken = (bus_cmd_valid & io.dma_bus_clk_en) | io.dbg_dec_dma.dbg_ib.dbg_cmd_valid | io.clk_override
val dma_free_clken = (bus_cmd_valid | bus_rsp_valid | io.dbg_dec_dma.dbg_ib.dbg_cmd_valid | io.dma_dbg_cmd_done | dma_dbg_cmd_done_q | (fifo_valid.orR) | io.clk_override)
val dma_buffer_c1_clk = rvoclkhdr(clock,dma_buffer_c1_clken,io.scan_mode)
val dma_free_clk = rvoclkhdr(clock,dma_free_clken,io.scan_mode)
val bus_cmd_addr = WireInit(UInt(32.W), 0.U)
val fifo_addr_in = Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid, io.dbg_dec_dma.dbg_ib.dbg_cmd_addr, bus_cmd_addr)
val fifo_byteen_in = Fill(8,!io.dbg_dec_dma.dbg_ib.dbg_cmd_valid) & bus_cmd_byteen // Byte enable is used only for bus requests//Mux(io.dbg_cmd_valid, 0.U, bus_cmd_byteen)
val fifo_sz_in = Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid, Cat(0.U,io.dbg_cmd_size), bus_cmd_sz)
val fifo_write_in = Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid, io.dbg_dec_dma.dbg_ib.dbg_cmd_write, bus_cmd_write)
val fifo_posted_write_in = !io.dbg_dec_dma.dbg_ib.dbg_cmd_valid & bus_cmd_posted_write
val fifo_dbg_in = io.dbg_dec_dma.dbg_ib.dbg_cmd_valid
val bus_cmd_sent = WireInit(Bool(), false.B)
val WrPtr = WireInit(UInt(DEPTH_PTR.W), 0.U)
val RdPtr = WireInit(UInt(DEPTH_PTR.W), 0.U)
val dma_address_error = WireInit(Bool(), false.B)
val dma_alignment_error = WireInit(Bool(), false.B)
val bus_cmd_wdata = WireInit(UInt(64.W), 0.U)
val bus_cmd_tag = WireInit(UInt(DMA_BUS_TAG.W), 0.U)
val bus_cmd_mid = WireInit(UInt((DMA_BUS_ID:Int).W), 0.U)
val bus_cmd_prty = WireInit(UInt(DMA_BUS_PRTY.W), 0.U)
val bus_posted_write_done = WireInit(UInt(1.W), 0.U)
val fifo_full_spec_bus = WireInit(UInt(1.W), 0.U)
val dbg_dma_bubble_bus = WireInit(UInt(1.W), 0.U)
val axi_mstr_priority = WireInit(UInt(1.W), 0.U)
val axi_mstr_sel = WireInit(UInt(1.W), 0.U)
val axi_rsp_sent = WireInit(UInt(1.W), 0.U)
// val fifo_cmd_en = (0 until DEPTH).map(i=>((bus_cmd_sent & io.dma_bus_clk_en) | (io.dbg_cmd_valid & io.dbg_cmd_type(1))) & (WrPtr === i.U).asUInt()).reverse.reduce(Cat(_,_))
//
// val fifo_data_en = (0 until DEPTH).map(i => ((((bus_cmd_sent & fifo_write_in & io.dma_bus_clk_en) | (io.dbg_cmd_valid & io.dbg_cmd_type(1) & io.dbg_cmd_write)) &
// (i.U === WrPtr)) | ((dma_address_error | dma_alignment_error) & (i.U === RdPtr)) |
// (io.dccm_dma_rvalid & (i.U === io.dccm_dma_rtag)) |
// (io.iccm_dma_rvalid & (i.U === io.iccm_dma_rtag))).asUInt).reverse.reduce(Cat(_,_))
//
// val fifo_pend_en = (0 until DEPTH).map(i => ((io.dma_dccm_req | io.dma_iccm_req) & !io.dma_mem_write & (i.U === RdPtr)).asUInt).reverse.reduce(Cat(_,_))
//
// val dma_dbg_cmd_error = WireInit(Bool(), false.B)
//
// val fifo_error_en = (0 until DEPTH).map(i => (((dma_address_error.asBool | dma_alignment_error.asBool | dma_dbg_cmd_error) &
// (i.U === RdPtr)) | ((io.dccm_dma_rvalid & io.dccm_dma_ecc_error) & (i.U === io.dccm_dma_rtag)) |
// ((io.iccm_dma_rvalid & io.iccm_dma_ecc_error) & (i.U === io.iccm_dma_rtag))).asUInt).reverse.reduce(Cat(_,_))
// val fifo_error_in = Wire(Vec(DEPTH, UInt(2.W)))
// val fifo_error = Wire(Vec(DEPTH, UInt(2.W)))
// val fifo_error_bus_en = (0 until DMA_BUF_DEPTH).map(i=>(((fifo_error_in(i).orR & fifo_error_en(i)) | fifo_error(i).orR) & io.dma_bus_clk_en).asUInt).reverse.reduce(Cat(_,_))
// val fifo_done_en = (0 until DMA_BUF_DEPTH).map(i=>(((fifo_error(i).orR | fifo_error_en(i) | ((io.dma_dccm_req | io.dma_iccm_req) & io.dma_mem_write)) & (i.U === RdPtr)) |
// (io.dccm_dma_rvalid & (i.U === io.dccm_dma_rtag)) | (io.iccm_dma_rvalid & (i.U === io.iccm_dma_rtag))).asUInt).reverse.reduce(Cat(_,_))
// val fifo_done = WireInit(UInt(DEPTH.W), 0.U)
// val fifo_done_bus_en = (0 until DMA_BUF_DEPTH).map(i => ((fifo_done_en(i) | fifo_done(i)) & io.dma_bus_clk_en).asUInt).reverse.reduce(Cat(_,_))
// val bus_rsp_sent = WireInit(Bool(), false.B)
// val bus_posted_write_done = WireInit(Bool(), false.B)
// val RspPtr = WireInit(UInt(DEPTH_PTR.W), 0.U)
// val fifo_reset = (0 until DMA_BUF_DEPTH).map(i=>((((bus_rsp_sent | bus_posted_write_done) & io.dma_bus_clk_en) | io.dma_dbg_cmd_done) & (i.U === RspPtr)).asUInt()).reverse.reduce(Cat(_,_))
// fifo_error_in := (0 until DMA_BUF_DEPTH).map(i=>Mux(io.dccm_dma_rvalid & (io.dccm_dma_rtag===i.U), Cat(0.U(1.W),io.dccm_dma_ecc_error), Mux(io.iccm_dma_rvalid & (io.iccm_dma_rtag===i.U), Cat(0.U(1.W),io.iccm_dma_ecc_error), Cat(dma_address_error | dma_alignment_error | dma_dbg_cmd_error, dma_alignment_error))))
val fifo_cmd_en = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
val fifo_data_en = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
@ -109,17 +147,65 @@ class dma_ctrl extends Module with lib with RequireAsyncReset {
val fifo_reset = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
val fifo_error_en = WireInit(UInt(DMA_BUF_DEPTH.W),0.U)
val dma_dbg_cmd_error = WireInit(UInt(1.W),0.U)
val fifo_error_in = Wire(Vec(DMA_BUF_DEPTH, UInt(2.W)))
val RspPtr = WireInit(UInt((log2Ceil(DMA_BUF_DEPTH)).W), 0.U)
val bus_posted_write_done = WireInit(UInt(1.W), 0.U)
val bus_rsp_sent = WireInit(UInt(1.W), 0.U)
val fifo_error = Wire(Vec(DMA_BUF_DEPTH, UInt(2.W)))
val fifo_done = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
val fifo_valid = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
val fifo_rpend = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
val fifo_done_bus = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
val fifo_write = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
val fifo_posted_write = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
val fifo_dbg = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
val wrbuf_vld = WireInit(UInt(1.W), 0.U)
val wrbuf_data_vld = WireInit(UInt(1.W), 0.U)
val rdbuf_vld = WireInit(UInt(1.W), 0.U)
val dma_free_clk = Wire(Clock())
val dma_bus_clk = Wire(Clock())
val dma_buffer_c1_clk = Wire(Clock())
val fifo_byteen_in = WireInit(UInt(8.W), 0.U)
//------------------------LOGIC STARTS HERE---------------------------------
// DCCM Address check
val (dma_mem_addr_in_dccm,dma_mem_addr_in_dccm_region_nc) = rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(DCCM_SADR).U,DCCM_SIZE)
// PIC memory address check
val (dma_mem_addr_in_pic,dma_mem_addr_in_pic_region_nc) = rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(PIC_BASE_ADDR).U,PIC_SIZE)
// ICCM Address check
val (dma_mem_addr_in_iccm,dma_mem_addr_in_iccm_region_nc) = if(ICCM_ENABLE) rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(ICCM_SADR).U,ICCM_SIZE) else (0.U,0.U)
// FIFO inputs
val fifo_addr_in = Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid.asBool, io.dbg_dec_dma.dbg_ib.dbg_cmd_addr(31,0), bus_cmd_addr(31,0))
fifo_byteen_in := Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid.asBool, "h0f".U << (4.U * io.dbg_dec_dma.dbg_ib.dbg_cmd_addr(2)), bus_cmd_byteen(7,0))
val fifo_sz_in = Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid.asBool, Cat(0.U, io.dbg_cmd_size(1,0)), bus_cmd_sz(2,0))
val fifo_write_in = Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid.asBool, io.dbg_dec_dma.dbg_ib.dbg_cmd_write, bus_cmd_write)
val fifo_posted_write_in = !io.dbg_dec_dma.dbg_ib.dbg_cmd_valid & bus_cmd_posted_write
val fifo_dbg_in = io.dbg_dec_dma.dbg_ib.dbg_cmd_valid
fifo_cmd_en := (0 until DMA_BUF_DEPTH).map(i => (((bus_cmd_sent.asBool & io.dma_bus_clk_en) | (io.dbg_dec_dma.dbg_ib.dbg_cmd_valid & io.dbg_dec_dma.dbg_ib.dbg_cmd_type(1).asBool)) & (i.U === WrPtr)).asUInt).reverse.reduce(Cat(_,_))
fifo_data_en := (0 until DMA_BUF_DEPTH).map(i => (((bus_cmd_sent & fifo_write_in & io.dma_bus_clk_en) | (io.dbg_dec_dma.dbg_ib.dbg_cmd_valid & io.dbg_dec_dma.dbg_ib.dbg_cmd_type(1) & io.dbg_dec_dma.dbg_ib.dbg_cmd_write)) & (i.U === WrPtr).asUInt()) | ((dma_address_error | dma_alignment_error) & (i.U === RdPtr).asUInt()) | (io.lsu_dma.dma_dccm_ctl.dccm_dma_rvalid & (i.U === io.lsu_dma.dma_dccm_ctl.dccm_dma_rtag).asUInt()) | (io.iccm_dma_rvalid & (i.U === io.iccm_dma_rtag).asUInt())).reverse.reduce(Cat(_,_))
fifo_data_en := (0 until DMA_BUF_DEPTH).map(i => (((bus_cmd_sent & fifo_write_in & io.dma_bus_clk_en) | (io.dbg_dec_dma.dbg_ib.dbg_cmd_valid & io.dbg_dec_dma.dbg_ib.dbg_cmd_type(1) & io.dbg_dec_dma.dbg_ib.dbg_cmd_write)) & (i.U === WrPtr)) | ((dma_address_error | dma_alignment_error) & (i.U === RdPtr)) | (io.lsu_dma.dma_dccm_ctl.dccm_dma_rvalid & (i.U === io.lsu_dma.dma_dccm_ctl.dccm_dma_rtag)) | (io.iccm_dma_rvalid & (i.U === io.iccm_dma_rtag))).reverse.reduce(Cat(_,_))
fifo_pend_en := (0 until DMA_BUF_DEPTH).map(i => ((io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req) & !io.lsu_dma.dma_lsc_ctl.dma_mem_write & (i.U === RdPtr)).asUInt).reverse.reduce(Cat(_,_))
@ -135,69 +221,87 @@ class dma_ctrl extends Module with lib with RequireAsyncReset {
(0 until DMA_BUF_DEPTH).map(i => fifo_error_in(i) := (Mux(io.lsu_dma.dma_dccm_ctl.dccm_dma_rvalid & (i.U === io.lsu_dma.dma_dccm_ctl.dccm_dma_rtag), Cat(0.U, io.lsu_dma.dma_dccm_ctl.dccm_dma_ecc_error), Mux(io.iccm_dma_rvalid & (i.U === io.iccm_dma_rtag), (Cat(0.U, io.iccm_dma_ecc_error)), (Cat((dma_address_error | dma_alignment_error | dma_dbg_cmd_error), dma_alignment_error))))))
val fifo_addr = Wire(Vec(DEPTH,UInt(32.W)))
val bus_cmd_wdata = WireInit(UInt(64.W), 0.U)
val fifo_data_in = VecInit.tabulate(DMA_BUF_DEPTH)(i =>(Mux(fifo_error_en(i) & (fifo_error_in(i).orR), Cat(Fill(32, 0.U), fifo_addr(i)), Mux(io.lsu_dma.dma_dccm_ctl.dccm_dma_rvalid & (i.U === io.lsu_dma.dma_dccm_ctl.dccm_dma_rtag), io.lsu_dma.dma_dccm_ctl.dccm_dma_rdata, Mux(io.iccm_dma_rvalid & (i.U === io.iccm_dma_rtag), io.iccm_dma_rdata, Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid, Fill(2, dma_dbg_mem_wrdata), bus_cmd_wdata(63,0)))))))
(0 until DMA_BUF_DEPTH).map(i => fifo_data_in(i) := (Mux(fifo_error_en(i) & (fifo_error_in(i).orR), Cat(Fill(32, 0.U), fifo_addr(i)), Mux(io.lsu_dma.dma_dccm_ctl.dccm_dma_rvalid & (i.U === io.lsu_dma.dma_dccm_ctl.dccm_dma_rtag), io.lsu_dma.dma_dccm_ctl.dccm_dma_rdata, Mux(io.iccm_dma_rvalid & (i.U === io.iccm_dma_rtag), io.iccm_dma_rdata, Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid, Fill(2, io.dbg_dec_dma.dbg_dctl.dbg_cmd_wrdata), bus_cmd_wdata(63,0)))))))
fifo_valid := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_cmd_en(i), 1.U, fifo_valid(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
(0 until DMA_BUF_DEPTH).map(i => fifo_error(i) := withClock(dma_free_clk) {RegNext(Mux(fifo_error_en(i).asBool(),fifo_error_in(i) , fifo_error(i)) & Fill(fifo_error_in(i).getWidth , !fifo_reset(i)), 0.U)})
val fifo_error_bus = WireInit(UInt(DEPTH.W), 0.U)
val fifo_rpend = WireInit(UInt(DEPTH.W), 0.U)
fifo_error_bus := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_error_bus_en(i), 1.U, fifo_error_bus(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
fifo_rpend := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_pend_en(i), 1.U, fifo_rpend(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
fifo_done := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_done_en(i), 1.U, fifo_done(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
val fifo_done_bus = WireInit(UInt(DEPTH.W), 0.U)
fifo_done_bus := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_done_bus_en(i), 1.U, fifo_done_bus(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
(0 until DMA_BUF_DEPTH).map(i => fifo_addr(i) := rvdffe(fifo_addr_in, fifo_cmd_en(i), clock, io.scan_mode))
val fifo_sz = VecInit.tabulate(DMA_BUF_DEPTH)(i => withClock(dma_buffer_c1_clk) {RegEnable(fifo_sz_in(2,0), 0.U, fifo_cmd_en(i))})
val fifo_byteen = VecInit.tabulate(DMA_BUF_DEPTH)(i =>withClock(dma_buffer_c1_clk) {RegEnable(fifo_byteen_in(7,0), 0.U, fifo_cmd_en(i).asBool())})
val fifo_write = (0 until DMA_BUF_DEPTH).map(i => (withClock(dma_buffer_c1_clk) {RegEnable(fifo_write_in, 0.U, fifo_cmd_en(i))})).reverse.reduce(Cat(_,_))
val fifo_posted_write = (0 until DMA_BUF_DEPTH).map(i => (withClock(dma_buffer_c1_clk) {RegEnable(fifo_posted_write_in, 0.U, fifo_cmd_en(i))})).reverse.reduce(Cat(_,_))
val fifo_dbg = (0 until DMA_BUF_DEPTH).map(i => withClock(dma_buffer_c1_clk) {RegEnable(fifo_dbg_in, 0.U, fifo_cmd_en(i))}).reverse.reduce(Cat(_,_))
val fifo_data = Wire(Vec(DMA_BUF_DEPTH,UInt(64.W)))//VecInit.tabulate(DMA_BUF_DEPTH)(i =>rvdffe(fifo_data_in(i), fifo_data_en(i), clock, io.scan_mode))
(0 until DMA_BUF_DEPTH).map(i => fifo_error(i) := withClock(dma_free_clk) {RegNext(Mux(fifo_error_en(i).asBool(),fifo_error_in(i) , fifo_error(i)) & Fill(fifo_error_in(i).getWidth , !fifo_reset(i)), 0.U)})
fifo_error_bus := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_error_bus_en(i), 1.U, fifo_error_bus(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
fifo_rpend := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_pend_en(i), 1.U, fifo_rpend(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
fifo_done := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_done_en(i), 1.U, fifo_done(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
fifo_done_bus := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_done_bus_en(i), 1.U, fifo_done_bus(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
(0 until DMA_BUF_DEPTH).map(i => fifo_addr(i) := rvdffe(fifo_addr_in, fifo_cmd_en(i), clock, io.scan_mode))
(0 until DMA_BUF_DEPTH).map(i => fifo_sz(i) := withClock(dma_buffer_c1_clk) {RegEnable(fifo_sz_in(2,0), 0.U, fifo_cmd_en(i))})
(0 until DMA_BUF_DEPTH).map(i => fifo_byteen(i) := withClock(dma_buffer_c1_clk) {RegEnable(fifo_byteen_in(7,0), 0.U, fifo_cmd_en(i).asBool())})
fifo_write := (0 until DMA_BUF_DEPTH).map(i => (withClock(dma_buffer_c1_clk) {RegEnable(fifo_write_in, 0.U, fifo_cmd_en(i))})).reverse.reduce(Cat(_,_))
fifo_posted_write := (0 until DMA_BUF_DEPTH).map(i => (withClock(dma_buffer_c1_clk) {RegEnable(fifo_posted_write_in, 0.U, fifo_cmd_en(i))})).reverse.reduce(Cat(_,_))
fifo_dbg := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_buffer_c1_clk) {RegEnable(fifo_dbg_in, 0.U, fifo_cmd_en(i))}).reverse.reduce(Cat(_,_))
(0 until DMA_BUF_DEPTH).map(i => fifo_data(i) := rvdffe(fifo_data_in(i), fifo_data_en(i), clock, io.scan_mode))
val bus_cmd_tag = WireInit(UInt(DMA_BUS_TAG.W),0.U)
val bus_cmd_mid = WireInit(UInt(DMA_BUS_ID.W),0.U)
val bus_cmd_prty = WireInit(UInt(DMA_BUS_PRTY.W),0.U)
val fifo_tag = VecInit.tabulate(DMA_BUF_DEPTH)(i =>withClock(dma_buffer_c1_clk) {RegEnable(bus_cmd_tag, 0.U, fifo_cmd_en(i))})
val fifo_mid = VecInit.tabulate(DMA_BUF_DEPTH)(i =>withClock(dma_buffer_c1_clk) {RegEnable(bus_cmd_mid, 0.U, fifo_cmd_en(i))})
val fifo_prty = VecInit.tabulate(DMA_BUF_DEPTH)(i =>withClock(dma_buffer_c1_clk) {RegEnable(bus_cmd_prty, 0.U, fifo_cmd_en(i))})
(0 until DMA_BUF_DEPTH).map(i => fifo_tag(i) := withClock(dma_buffer_c1_clk) {RegEnable(bus_cmd_tag, 0.U, fifo_cmd_en(i))})
(0 until DMA_BUF_DEPTH).map(i => fifo_mid(i) := withClock(dma_buffer_c1_clk) {RegEnable(bus_cmd_mid, 0.U, fifo_cmd_en(i))})
(0 until DMA_BUF_DEPTH).map(i => fifo_prty(i) := withClock(dma_buffer_c1_clk) {RegEnable(bus_cmd_prty, 0.U, fifo_cmd_en(i))})
// Pointer logic
val NxtWrPtr = Mux((WrPtr === (DEPTH-1).U), 0.U, WrPtr+ 1.U)
val NxtRdPtr = Mux((RdPtr === (DEPTH-1).U), 0.U, RdPtr+ 1.U)
val NxtRspPtr = Mux((RspPtr === (DEPTH-1).U), 0.U, RspPtr + 1.U)
NxtWrPtr := Mux((WrPtr === (DMA_BUF_DEPTH - 1).U).asBool, 0.U, WrPtr + 1.U)
NxtRdPtr := Mux((RdPtr === (DMA_BUF_DEPTH - 1).U).asBool, 0.U, RdPtr + 1.U)
NxtRspPtr := Mux((RspPtr === (DMA_BUF_DEPTH - 1).U).asBool, 0.U, RspPtr + 1.U)
val WrPtrEn = fifo_cmd_en.orR
val RdPtrEn = (io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req | (dma_address_error.asBool | dma_alignment_error.asBool | dma_dbg_cmd_error))
val WrPtrEn = fifo_cmd_en.orR
val RdPtrEn = io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req | (dma_address_error | dma_alignment_error | dma_dbg_cmd_error)
val RspPtrEn = (io.dma_dbg_cmd_done | (bus_rsp_sent | bus_posted_write_done) & io.dma_bus_clk_en)
WrPtr := withClock(dma_free_clk) {
RegEnable(NxtWrPtr, 0.U, WrPtrEn)
}
WrPtr := withClock(dma_free_clk) { RegEnable(NxtWrPtr, 0.U, WrPtrEn) }
RdPtr := withClock(dma_free_clk) { RegEnable(NxtRdPtr, 0.U, RdPtrEn.asBool) }
RspPtr := withClock(dma_free_clk) { RegEnable(NxtRspPtr, 0.U, RspPtrEn.asBool) }
// Miscellaneous signals
val fifo_full_spec_bus = WireInit(Bool(),0.B)
val fifo_full = fifo_full_spec_bus
RdPtr := withClock(dma_free_clk) {
RegEnable(NxtRdPtr, 0.U, RdPtrEn.asBool)
}
val num_fifo_vld = Wire(Vec(DEPTH+1,UInt(4.W)))
val dbg_dma_bubble_bus = WireInit(Bool(),0.B)
num_fifo_vld(0) := Cat(0.U(3.W),bus_cmd_sent) - Cat(0.U(3.W),bus_rsp_sent)
for (i <- 1 to DEPTH) { num_fifo_vld(i):= num_fifo_vld(i-1) + Cat(0.U(3.W),fifo_valid(i-1))}
val fifo_full_spec = (num_fifo_vld(DEPTH) >= DEPTH.U)
val dma_fifo_ready = ~(fifo_full | dbg_dma_bubble_bus)
RspPtr := withClock(dma_free_clk) {
RegEnable(NxtRspPtr, 0.U, RspPtrEn.asBool)
}
// Miscellaneous signal
val fifo_full = fifo_full_spec_bus;
val num_fifo_vld_tmp = WireInit(UInt(4.W),0.U)
val num_fifo_vld_tmp2 = WireInit(UInt(4.W),0.U)
num_fifo_vld_tmp := (Cat(Fill(3, 0.U), bus_cmd_sent)) - (Cat(Fill(3, 0.U), bus_rsp_sent))
num_fifo_vld_tmp2 := (0 until DMA_BUF_DEPTH).map(i => Cat(Fill(3,0.U), fifo_valid(i))).reduce(_+_)
num_fifo_vld := num_fifo_vld_tmp + num_fifo_vld_tmp2
val fifo_full_spec = (num_fifo_vld >= DMA_BUF_DEPTH.asUInt())
val dma_fifo_ready = ~(fifo_full | dbg_dma_bubble_bus)
// Error logic
val dma_mem_addr_in_dccm = WireInit(Bool(),0.B)
val dma_mem_addr_in_iccm = WireInit(Bool(),0.B)
val dma_mem_sz_int = WireInit(UInt(3.W),0.U)
val dma_mem_addr_int = WireInit(UInt(32.W),0.U)
val dma_mem_byteen = WireInit(UInt(8.W),0.U)
dma_address_error := fifo_valid(RdPtr) & ~fifo_done(RdPtr) & ~fifo_dbg(RdPtr) & (~(dma_mem_addr_in_dccm | dma_mem_addr_in_iccm)) // request not for ICCM or DCCM
dma_alignment_error := fifo_valid(RdPtr) & !fifo_done(RdPtr) & !fifo_dbg(RdPtr) & !dma_address_error &
dma_address_error := fifo_valid(RdPtr) & !fifo_done(RdPtr) & !fifo_dbg(RdPtr) & (~(dma_mem_addr_in_dccm | dma_mem_addr_in_iccm)).asUInt // request not for ICCM or DCCM
dma_alignment_error := fifo_valid(RdPtr) & !fifo_done(RdPtr) & !dma_address_error &
(((dma_mem_sz_int(2,0) === 1.U) & dma_mem_addr_int(0)) | // HW size but unaligned
((dma_mem_sz_int(2,0) === 2.U) & (dma_mem_addr_int(1, 0).orR)) | // W size but unaligned
((dma_mem_sz_int(2,0) === 3.U) & (dma_mem_addr_int(2, 0).orR)) | // DW size but unaligned
@ -212,184 +316,185 @@ class dma_ctrl extends Module with lib with RequireAsyncReset {
(dma_mem_addr_int(2,0) === 6.U) -> (dma_mem_byteen(7,6)),
(dma_mem_addr_int(2,0) === 7.U) -> (dma_mem_byteen(7)))) =/= "hf".U)) | // Write byte enables not aligned for word store
(io.lsu_dma.dma_lsc_ctl.dma_mem_write & (dma_mem_sz_int(2, 0) === 3.U) & !((dma_mem_byteen(7,0) === "h0f".U) | (dma_mem_byteen(7,0) === "hf0".U) | (dma_mem_byteen(7,0) === "hff".U)))) // Write byte enables not aligned for dword store
// Used to indicate ready to debug
val fifo_empty = ~(fifo_valid.orR | bus_cmd_sent)
//Dbg outputs
io.dbg_dma.dma_dbg_ready := fifo_empty & io.dbg_dma.dbg_dma_bubble
io.dma_dbg_cmd_done := (fifo_valid(RspPtr) & fifo_dbg(RspPtr) & fifo_done(RspPtr))
io.dma_dbg_cmd_fail := fifo_error(RspPtr).orR
val dma_dbg_sz = fifo_sz(RspPtr)(1,0)
val dma_dbg_addr = fifo_addr(RspPtr)(1,0)
val dma_dbg_mem_rddata = Mux(fifo_addr(RspPtr)(2), fifo_data(RspPtr)(63,32) , fifo_data(RspPtr)(31,0))
io.dma_dbg_rddata := Mux1H(Seq(
(dma_dbg_sz(1,0) === "h0".U(2.W)) -> ((dma_dbg_mem_rddata >> ((8.U)*dma_dbg_addr(1,0))) & "hff".U) ,
(dma_dbg_sz(1,0) === "h1".U(2.W)) -> ((dma_dbg_mem_rddata >> ((16.U)*dma_dbg_addr(1))) & "hffff".U) ,
(dma_dbg_sz(1,0) === "h2".U(2.W)) -> dma_dbg_mem_rddata))
io.dbg_dma.dma_dbg_ready := fifo_empty & dbg_dma_bubble_bus
io.dma_dbg_cmd_done := (fifo_valid(RspPtr) & fifo_dbg(RspPtr) & fifo_done(RspPtr))
io.dma_dbg_rddata := Mux(fifo_addr(RspPtr)(2), fifo_data(RspPtr)(63, 32), fifo_data(RspPtr)(31,0))
io.dma_dbg_cmd_fail := fifo_error(RspPtr).orR
// PIC memory address check
val dma_mem_addr_in_pic = rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(PIC_BASE_ADDR).U,PIC_SIZE)._1
val dma_mem_addr_in_pic_region_nc = rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(PIC_BASE_ADDR).U,PIC_SIZE)._2
dma_dbg_cmd_error := fifo_valid(RdPtr) & ~fifo_done(RdPtr) & fifo_dbg(RdPtr) &
((~(dma_mem_addr_in_dccm | dma_mem_addr_in_iccm | dma_mem_addr_in_pic)) | // Address outside of ICCM/DCCM/PIC
((dma_mem_addr_in_iccm | dma_mem_addr_in_pic) & (dma_mem_sz_int(1,0) =/= 2.U))) // Only word accesses allowed for ICCM/PIC
dma_dbg_mem_wrdata := Mux1H(Seq(
(io.dbg_cmd_size(1,0) === "h0".U(2.W)) -> Fill(4,io.dbg_dec_dma.dbg_dctl.dbg_cmd_wrdata(7,0)) ,
(io.dbg_cmd_size(1,0) === "h1".U(2.W)) -> Fill(2,io.dbg_dec_dma.dbg_dctl.dbg_cmd_wrdata(15,0)),
(io.dbg_cmd_size(1,0) === "h2".U(2.W)) -> io.dbg_dec_dma.dbg_dctl.dbg_cmd_wrdata ))
dma_dbg_cmd_error := fifo_valid(RdPtr) & !fifo_done(RdPtr) & fifo_dbg(RdPtr) & ((~(dma_mem_addr_in_dccm | dma_mem_addr_in_iccm | dma_mem_addr_in_pic)).asBool() | (dma_mem_sz_int(1, 0) =/= 2.U)) // Only word accesses allowed
// Block the decode if fifo full
val dma_mem_req = WireInit(Bool(),0.B)
val dma_nack_count = WireInit(UInt(3.W),0.U)
val dma_nack_count_csr = WireInit(UInt(3.W),0.U)
val dma_nack_count_d = WireInit(UInt(3.W),0.U)
io.dec_dma.dctl_dma.dma_dccm_stall_any := dma_mem_req & (dma_mem_addr_in_dccm | dma_mem_addr_in_pic) & (dma_nack_count >= dma_nack_count_csr)
io.dec_dma.tlu_dma.dma_dccm_stall_any := io.dec_dma.dctl_dma.dma_dccm_stall_any
io.dec_dma.tlu_dma.dma_iccm_stall_any := dma_mem_req & dma_mem_addr_in_iccm & (dma_nack_count >= dma_nack_count_csr)
io.ifu_dma.dma_ifc.dma_iccm_stall_any := io.dec_dma.tlu_dma.dma_iccm_stall_any
// Nack counter, stall the lsu pipe if 7 nacks
dma_nack_count_csr := io.dec_dma.tlu_dma.dec_tlu_dma_qos_prty
dma_nack_count_d := Mux((dma_nack_count >= dma_nack_count_csr), (Fill(3,(!(io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req))) & dma_nack_count),
Mux((dma_mem_req & ~(io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req)), (dma_nack_count + 1.U), 0.U(3.W)))
dma_nack_count := withClock(dma_free_clk){RegEnable(dma_nack_count_d,0.U,dma_mem_req)}
io.dec_dma.tlu_dma.dma_dccm_stall_any := dma_mem_req & (dma_mem_addr_in_dccm | dma_mem_addr_in_pic) & (dma_nack_count >= dma_nack_count_csr)
io.ifu_dma.dma_ifc.dma_iccm_stall_any := dma_mem_req & dma_mem_addr_in_iccm & (dma_nack_count >= dma_nack_count_csr);
io.dec_dma.tlu_dma.dma_iccm_stall_any := io.ifu_dma.dma_ifc.dma_iccm_stall_any
io.dec_dma.dctl_dma.dma_dccm_stall_any := io.dec_dma.tlu_dma.dma_dccm_stall_any
// Used to indicate ready to debug
fifo_empty := ~(fifo_valid.orR)
// Nack counter, stall the lsu pipe if 7 nacks
dma_nack_count_csr := io.dec_dma.tlu_dma.dec_tlu_dma_qos_prty
val dma_nack_count_d = Mux(dma_nack_count >= dma_nack_count_csr, (Fill(3, !(io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req)) & dma_nack_count(2,0)), Mux((dma_mem_req.asBool & !(io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req)), dma_nack_count(2,0) + 1.U, 0.U))
dma_nack_count := withClock(dma_free_clk) {
RegEnable(dma_nack_count_d(2,0), 0.U, dma_mem_req.asBool)
}
// Core outputs
dma_mem_req := fifo_valid(RdPtr) & ~fifo_rpend(RdPtr) & ~fifo_done(RdPtr) & ~(dma_address_error | dma_alignment_error | dma_dbg_cmd_error)
io.lsu_dma.dma_lsc_ctl.dma_dccm_req := dma_mem_req & (dma_mem_addr_in_dccm | dma_mem_addr_in_pic) & io.lsu_dma.dccm_ready
io.ifu_dma.dma_mem_ctl.dma_iccm_req := dma_mem_req & dma_mem_addr_in_iccm & io.iccm_ready
io.lsu_dma.dma_mem_tag := RdPtr
io.ifu_dma.dma_mem_ctl.dma_mem_tag := io.lsu_dma.dma_mem_tag
dma_mem_addr_int := fifo_addr(RdPtr)
dma_mem_sz_int := fifo_sz(RdPtr)
io.lsu_dma.dma_dccm_ctl.dma_mem_addr := Mux((io.lsu_dma.dma_lsc_ctl.dma_mem_write & ~fifo_dbg(RdPtr) & (dma_mem_byteen === "hf0".U(8.W))), Cat(dma_mem_addr_int(31,3),1.U,dma_mem_addr_int(1,0)), dma_mem_addr_int)
io.lsu_dma.dma_lsc_ctl.dma_mem_addr := io.lsu_dma.dma_dccm_ctl.dma_mem_addr
io.ifu_dma.dma_mem_ctl.dma_mem_addr := io.lsu_dma.dma_dccm_ctl.dma_mem_addr
io.lsu_dma.dma_lsc_ctl.dma_mem_sz := Mux(io.lsu_dma.dma_lsc_ctl.dma_mem_write & ~fifo_dbg(RdPtr) & ((dma_mem_byteen === "h0f".U(8.W)) | (dma_mem_byteen === "hf0".U(8.W))), 2.U(3.W), dma_mem_sz_int)
io.ifu_dma.dma_mem_ctl.dma_mem_sz := io.lsu_dma.dma_lsc_ctl.dma_mem_sz
dma_mem_byteen := fifo_byteen(RdPtr)
io.lsu_dma.dma_lsc_ctl.dma_mem_write := fifo_write(RdPtr)
io.ifu_dma.dma_mem_ctl.dma_mem_write := io.lsu_dma.dma_lsc_ctl.dma_mem_write
io.lsu_dma.dma_dccm_ctl.dma_mem_wdata := fifo_data(RdPtr)
io.lsu_dma.dma_lsc_ctl.dma_mem_wdata := io.lsu_dma.dma_dccm_ctl.dma_mem_wdata
io.ifu_dma.dma_mem_ctl.dma_mem_wdata := io.lsu_dma.dma_dccm_ctl.dma_mem_wdata
dma_mem_req := fifo_valid(RdPtr) & !fifo_rpend(RdPtr) & !fifo_done(RdPtr) & !(dma_address_error | dma_alignment_error | dma_dbg_cmd_error)
io.lsu_dma.dma_lsc_ctl.dma_dccm_req := dma_mem_req & (dma_mem_addr_in_dccm | dma_mem_addr_in_pic) & io.lsu_dma.dccm_ready
io.ifu_dma.dma_mem_ctl.dma_iccm_req := dma_mem_req & dma_mem_addr_in_iccm & io.iccm_ready;
io.lsu_dma.dma_mem_tag := RdPtr
dma_mem_addr_int := fifo_addr(RdPtr)
dma_mem_sz_int := fifo_sz(RdPtr)
io.lsu_dma.dma_lsc_ctl.dma_mem_addr := Mux(io.lsu_dma.dma_lsc_ctl.dma_mem_write & (dma_mem_byteen(7,0) === "hf0".U), Cat(dma_mem_addr_int(31, 3), 1.U, dma_mem_addr_int(1, 0)), dma_mem_addr_int(31,0))
io.lsu_dma.dma_lsc_ctl.dma_mem_sz := Mux(io.lsu_dma.dma_lsc_ctl.dma_mem_write & ((dma_mem_byteen(7,0) === "h0f".U) | (dma_mem_byteen(7,0) === "hf0".U)), 2.U, dma_mem_sz_int(2,0))
dma_mem_byteen := fifo_byteen(RdPtr)
io.lsu_dma.dma_lsc_ctl.dma_mem_write := fifo_write(RdPtr)
io.lsu_dma.dma_lsc_ctl.dma_mem_wdata := fifo_data(RdPtr)
// PMU outputs
io.dec_dma.tlu_dma.dma_pmu_dccm_read := io.lsu_dma.dma_lsc_ctl.dma_dccm_req & ~io.lsu_dma.dma_lsc_ctl.dma_mem_write
io.dec_dma.tlu_dma.dma_pmu_dccm_read := io.lsu_dma.dma_lsc_ctl.dma_dccm_req & !io.lsu_dma.dma_lsc_ctl.dma_mem_write
io.dec_dma.tlu_dma.dma_pmu_dccm_write := io.lsu_dma.dma_lsc_ctl.dma_dccm_req & io.lsu_dma.dma_lsc_ctl.dma_mem_write
io.dec_dma.tlu_dma.dma_pmu_any_read := (io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req) & ~io.lsu_dma.dma_lsc_ctl.dma_mem_write
io.dec_dma.tlu_dma.dma_pmu_any_read := (io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req) & !io.lsu_dma.dma_lsc_ctl.dma_mem_write
io.dec_dma.tlu_dma.dma_pmu_any_write := (io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req) & io.lsu_dma.dma_lsc_ctl.dma_mem_write
// Address check dccm
val dma_mem_addr_in_dccm_region_nc = WireInit(Bool(),0.B)
if (DCCM_ENABLE){
dma_mem_addr_in_dccm := rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(DCCM_SADR).U,DCCM_SIZE)._1
dma_mem_addr_in_dccm_region_nc := rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(DCCM_SADR).U,DCCM_SIZE)._2
} else{
dma_mem_addr_in_dccm := 0.U
dma_mem_addr_in_dccm_region_nc := 0.U
}
// Address check iccm
val dma_mem_addr_in_iccm_region_nc = WireInit(Bool(),0.B)
if (ICCM_ENABLE) {
dma_mem_addr_in_iccm := rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(ICCM_SADR).U,ICCM_SIZE)._1
dma_mem_addr_in_iccm_region_nc := rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(ICCM_SADR).U,ICCM_SIZE)._2
}else {
dma_mem_addr_in_iccm := 0.U
dma_mem_addr_in_iccm_region_nc := 0.U
}
val dma_bus_clk = Wire(Clock())
if(RV_FPGA_OPTIMIZE) dma_bus_clk := 0.B.asClock()
else dma_bus_clk := rvclkhdr(clock,io.dma_bus_clk_en,io.scan_mode)// dma_bus_cgc (.en(dma_bus_clk_en), .l1clk(dma_bus_clk), .*)
// Inputs
fifo_full_spec_bus := rvdff_fpga(fifo_full_spec,dma_bus_clk,io.dma_bus_clk_en,clock)
dbg_dma_bubble_bus := rvdff_fpga(io.dbg_dma.dbg_dma_bubble,dma_bus_clk,io.dma_bus_clk_en,clock)
dma_dbg_cmd_done_q := withClock(io.free_clk){ RegNext(io.dma_dbg_cmd_done,0.U)}
fifo_full_spec_bus := withClock(dma_bus_clk) {
RegNext(fifo_full_spec, 0.U)
}
dbg_dma_bubble_bus := withClock(dma_bus_clk) {
RegNext(io.dbg_dma.dbg_dma_bubble, 0.U)
}
dma_dbg_cmd_done_q := withClock(io.free_clk) {
RegNext(io.dma_dbg_cmd_done, 0.U)
}
// Clock Gating logic
val dma_buffer_c1_clken = (bus_cmd_valid & io.dma_bus_clk_en) | io.dbg_dec_dma.dbg_ib.dbg_cmd_valid | io.clk_override
val dma_free_clken = (bus_cmd_valid | bus_rsp_valid | io.dbg_dec_dma.dbg_ib.dbg_cmd_valid | io.dma_dbg_cmd_done | dma_dbg_cmd_done_q | (fifo_valid.orR) | io.clk_override)
dma_buffer_c1_clk := rvclkhdr(clock,dma_buffer_c1_clken.asBool,io.scan_mode)
dma_free_clk := rvclkhdr(clock,dma_free_clken.asBool(),io.scan_mode)
dma_bus_clk := rvclkhdr(clock,io.dma_bus_clk_en,io.scan_mode)
// Write channel buffer
val wrbuf_en = io.dma_axi.aw.valid & io.dma_axi.aw.ready
val wrbuf_data_en = io.dma_axi.w.valid & io.dma_axi.w.ready
val wrbuf_cmd_sent = bus_cmd_sent & bus_cmd_write
val wrbuf_rst = wrbuf_cmd_sent & ~wrbuf_en
val wrbuf_data_rst = wrbuf_cmd_sent & ~wrbuf_data_en
val wrbuf_vld = rvdffsc_fpga(1.B,wrbuf_en,wrbuf_rst,dma_bus_clk,io.dma_bus_clk_en,clock)
val wrbuf_data_vld = rvdffsc_fpga(1.B,wrbuf_data_en,wrbuf_data_rst,dma_bus_clk,io.dma_bus_clk_en,clock)
val wrbuf_tag = rvdffs_fpga(io.dma_axi.aw.bits.id,wrbuf_en,dma_bus_clk,io.dma_bus_clk_en,clock)
val wrbuf_sz = rvdffs_fpga(io.dma_axi.aw.bits.size,wrbuf_en,dma_bus_clk,io.dma_bus_clk_en,clock)
val wrbuf_addr = rvdffe(io.dma_axi.aw.bits.addr,wrbuf_en & io.dma_bus_clk_en,clock,io.scan_mode)
val wrbuf_data = rvdffe(io.dma_axi.w.bits.data,wrbuf_data_en & io.dma_bus_clk_en,clock,io.scan_mode)
val wrbuf_byteen = rvdffs_fpga(io.dma_axi.w.bits.strb,wrbuf_data_en,dma_bus_clk,io.dma_bus_clk_en,clock)
val wrbuf_en = io.dma_axi.aw.valid & io.dma_axi.aw.ready
val wrbuf_data_en = io.dma_axi.w.valid & io.dma_axi.w.ready
val wrbuf_cmd_sent = bus_cmd_sent & bus_cmd_write
val wrbuf_rst = wrbuf_cmd_sent.asBool & !wrbuf_en
val wrbuf_data_rst = wrbuf_cmd_sent.asBool & !wrbuf_data_en
wrbuf_vld := withClock(dma_bus_clk) {RegNext(Mux(wrbuf_en, 1.U, wrbuf_vld) & !wrbuf_rst, 0.U)}
wrbuf_data_vld := withClock(dma_bus_clk) {RegNext(Mux(wrbuf_data_en, 1.U, wrbuf_data_vld) & !wrbuf_data_rst, 0.U)}
val wrbuf_tag = withClock(dma_bus_clk) {
RegEnable(io.dma_axi.aw.bits.id, 0.U, wrbuf_en)
}
val wrbuf_sz = withClock(dma_bus_clk) {
RegEnable(io.dma_axi.aw.bits.size, 0.U, wrbuf_en)
}
val wrbuf_addr = rvdffe(io.dma_axi.aw.bits.addr, wrbuf_en & io.dma_bus_clk_en, clock, io.scan_mode)
val wrbuf_data = rvdffe(io.dma_axi.w.bits.data, wrbuf_data_en & io.dma_bus_clk_en, clock, io.scan_mode)
val wrbuf_byteen = withClock(dma_bus_clk) {
RegEnable(io.dma_axi.w.bits.strb, 0.U, wrbuf_data_en)
}
// Read channel buffer
val rdbuf_en = io.dma_axi.ar.valid & io.dma_axi.ar.ready
val rdbuf_cmd_sent = bus_cmd_sent & ~bus_cmd_write
val rdbuf_rst = rdbuf_cmd_sent & ~rdbuf_en
val rdbuf_vld = rvdffsc_fpga(1.B,rdbuf_en,rdbuf_rst,dma_bus_clk,io.dma_bus_clk_en,clock)
val rdbuf_tag = rvdffs_fpga(io.dma_axi.ar.bits.id,rdbuf_en,dma_bus_clk,io.dma_bus_clk_en,clock)
val rdbuf_sz = rvdffs_fpga(io.dma_axi.ar.bits.size,rdbuf_en,dma_bus_clk,io.dma_bus_clk_en,clock)
val rdbuf_addr = rvdffe(io.dma_axi.ar.bits.addr,rdbuf_en & io.dma_bus_clk_en,clock,io.scan_mode)
val rdbuf_en = io.dma_axi.ar.valid & io.dma_axi.ar.ready
val rdbuf_cmd_sent = bus_cmd_sent & !bus_cmd_write
val rdbuf_rst = rdbuf_cmd_sent.asBool & !rdbuf_en
io.dma_axi.aw.ready := ~(wrbuf_vld & ~wrbuf_cmd_sent)
io.dma_axi.w.ready := ~(wrbuf_data_vld & ~wrbuf_cmd_sent)
io.dma_axi.ar.ready := ~(rdbuf_vld & ~rdbuf_cmd_sent)
rdbuf_vld := withClock(dma_bus_clk) {RegNext(Mux(rdbuf_en, 1.U, rdbuf_vld) & !rdbuf_rst, 0.U)}
val rdbuf_tag = withClock(dma_bus_clk) {
RegEnable(io.dma_axi.ar.bits.id, 0.U, rdbuf_en)
}
val rdbuf_sz = withClock(dma_bus_clk) {
RegEnable(io.dma_axi.ar.bits.size, 0.U, rdbuf_en)
}
val rdbuf_addr = rvdffe(io.dma_axi.ar.bits.addr, rdbuf_en & io.dma_bus_clk_en, clock, io.scan_mode)
io.dma_axi.aw.ready := ~(wrbuf_vld & !wrbuf_cmd_sent)
io.dma_axi.w.ready := ~(wrbuf_data_vld & !wrbuf_cmd_sent)
io.dma_axi.ar.ready := ~(rdbuf_vld & !rdbuf_cmd_sent)
//Generate a single request from read/write channel
val axi_mstr_sel = WireInit(Bool(),0.B)
bus_cmd_valid := (wrbuf_vld & wrbuf_data_vld) | rdbuf_vld
bus_cmd_sent := bus_cmd_valid & dma_fifo_ready
bus_cmd_write := axi_mstr_sel
bus_cmd_posted_write := 0.U
bus_cmd_addr := Mux(axi_mstr_sel, wrbuf_addr, rdbuf_addr)
bus_cmd_sz := Mux(axi_mstr_sel, wrbuf_sz, rdbuf_sz)
bus_cmd_wdata := wrbuf_data
bus_cmd_byteen := wrbuf_byteen
bus_cmd_tag := Mux(axi_mstr_sel, wrbuf_tag, rdbuf_tag)
bus_cmd_mid := 0.U
bus_cmd_prty := 0.U
bus_cmd_valid := (wrbuf_vld & wrbuf_data_vld) | rdbuf_vld
bus_cmd_sent := bus_cmd_valid & dma_fifo_ready.asUInt
bus_cmd_write := axi_mstr_sel
bus_cmd_posted_write := 0.U;
bus_cmd_addr := Mux(axi_mstr_sel.asBool, wrbuf_addr, rdbuf_addr)
bus_cmd_sz := Mux(axi_mstr_sel.asBool, wrbuf_sz, rdbuf_sz)
bus_cmd_wdata := wrbuf_data
bus_cmd_byteen := wrbuf_byteen
bus_cmd_tag := Mux(axi_mstr_sel.asBool, wrbuf_tag, rdbuf_tag)
bus_cmd_mid := 0.U
bus_cmd_prty := 0.U
// Sel=1 -> write has higher priority
val axi_mstr_priority = WireInit(Bool(),0.B)
axi_mstr_sel := Mux(((wrbuf_vld & wrbuf_data_vld & rdbuf_vld)===1.U).asBool(), axi_mstr_priority, (wrbuf_vld & wrbuf_data_vld) )
val axi_mstr_prty_in = ~axi_mstr_priority
val axi_mstr_prty_en = bus_cmd_sent
axi_mstr_priority := rvdffs_fpga(axi_mstr_prty_in.asUInt(),axi_mstr_prty_en,dma_bus_clk,io.dma_bus_clk_en,clock)
val axi_rsp_valid = fifo_valid(RspPtr) & ~fifo_dbg(RspPtr) & fifo_done_bus(RspPtr)
val axi_rsp_rdata = fifo_data(RspPtr)
val axi_rsp_write = fifo_write(RspPtr)
val axi_rsp_error = Mux(fifo_error(RspPtr)(0), 2.U,Mux(fifo_error(RspPtr)(1), 3.U, 0.U))
val axi_rsp_tag = fifo_tag(RspPtr)
axi_mstr_sel := Mux((wrbuf_vld & wrbuf_data_vld & rdbuf_vld) === 1.U, axi_mstr_priority, wrbuf_vld & wrbuf_data_vld)
val axi_mstr_prty_in = ~axi_mstr_priority
val axi_mstr_prty_en = bus_cmd_sent
axi_mstr_priority := withClock(dma_bus_clk) {
RegEnable(axi_mstr_prty_in, 0.U, axi_mstr_prty_en.asBool)
}
val axi_rsp_valid = fifo_valid(RspPtr) & !fifo_dbg(RspPtr) & fifo_done_bus(RspPtr)
val axi_rsp_rdata = fifo_data(RspPtr)
val axi_rsp_write = fifo_write(RspPtr)
val axi_rsp_error = Mux(fifo_error(RspPtr)(0), 2.U, Mux(fifo_error(RspPtr)(1), 3.U, 0.U));
val axi_rsp_tag = fifo_tag(RspPtr)
// AXI response channel signals
io.dma_axi.b.valid := axi_rsp_valid & axi_rsp_write
io.dma_axi.b.bits.resp := axi_rsp_error
io.dma_axi.b.bits.id := axi_rsp_tag
io.dma_axi.r.valid := axi_rsp_valid & ~axi_rsp_write
io.dma_axi.r.bits.resp := axi_rsp_error
io.dma_axi.r.bits.data := axi_rsp_rdata
io.dma_axi.r.bits.last := 1.U
io.dma_axi.r.bits.id := axi_rsp_tag
io.dma_axi.b.valid := axi_rsp_valid & axi_rsp_write
io.dma_axi.b.bits.resp := axi_rsp_error(1,0)
io.dma_axi.b.bits.id := axi_rsp_tag
io.dma_axi.r.valid := axi_rsp_valid & !axi_rsp_write
io.dma_axi.r.bits.resp := axi_rsp_error
io.dma_axi.r.bits.data := axi_rsp_rdata(63,0)
io.dma_axi.r.bits.last := 1.U
io.dma_axi.r.bits.id := axi_rsp_tag
bus_posted_write_done := 0.U
bus_rsp_valid := (io.dma_axi.b.valid | io.dma_axi.r.valid)
bus_rsp_sent := (io.dma_axi.b.valid & io.dma_axi.b.ready) | (io.dma_axi.r.valid & io.dma_axi.r.ready)
io.dma_active := wrbuf_vld | rdbuf_vld | (fifo_valid.orR)
}
object DMA extends App {
println((new chisel3.stage.ChiselStage).emitVerilog(new dma_ctrl))
bus_rsp_valid := (io.dma_axi.b.valid | io.dma_axi.r.valid)
bus_rsp_sent := ((io.dma_axi.b.valid & io.dma_axi.b.ready) | (io.dma_axi.r.valid & io.dma_axi.r.ready))
io.lsu_dma.dma_dccm_ctl.dma_mem_addr := io.lsu_dma.dma_lsc_ctl.dma_mem_addr
io.lsu_dma.dma_dccm_ctl.dma_mem_wdata := io.lsu_dma.dma_lsc_ctl.dma_mem_wdata
io.ifu_dma.dma_mem_ctl.dma_mem_sz := io.lsu_dma.dma_lsc_ctl.dma_mem_sz
io.ifu_dma.dma_mem_ctl.dma_mem_addr := io.lsu_dma.dma_lsc_ctl.dma_mem_addr
io.ifu_dma.dma_mem_ctl.dma_mem_wdata := io.lsu_dma.dma_lsc_ctl.dma_mem_wdata
io.ifu_dma.dma_mem_ctl.dma_mem_write := io.lsu_dma.dma_lsc_ctl.dma_mem_write
io.ifu_dma.dma_mem_ctl.dma_mem_tag := io.lsu_dma.dma_mem_tag
}

View File

@ -21,12 +21,11 @@ class exu extends Module with lib with RequireAsyncReset{
val exu_div_wren = Output(UInt(1.W)) // Divide write enable to GPR
//debug
val dbg_cmd_wrdata = Input(UInt(32.W)) // Debug data to primary I0 RS1
val dec_csr_rddata_d = Input(UInt(32.W))
val lsu_nonblock_load_data = Input(UInt(32.W))
//lsu
val lsu_exu = Flipped(new lsu_exu())
//ifu_ifc
val exu_flush_path_final = Output(UInt(31.W)) // Target for the oldest flush source
})
val PREDPIPESIZE = BTB_ADDR_HI - BTB_ADDR_LO + BHT_GHR_SIZE + BTB_BTAG_SIZE +1
@ -36,7 +35,9 @@ class exu extends Module with lib with RequireAsyncReset{
val i0_taken_d = Wire(UInt(1.W))
val mul_valid_x = Wire(UInt(1.W))
val i0_valid_d = Wire(UInt(1.W))
val i0_branch_x = Wire(UInt(1.W))
val flush_lower_ff = Wire(UInt(1.W))
val data_gate_en = Wire(UInt(1.W))
val csr_rs1_in_d = Wire(UInt(32.W))
val i0_predict_newp_d = Wire(Valid(new predict_pkt_t()))
val i0_flush_path_d = Wire(UInt(31.W))
val i0_predict_p_d = Wire(Valid(new predict_pkt_t()))
@ -53,119 +54,130 @@ class exu extends Module with lib with RequireAsyncReset{
i0_pp_r.bits.toffset := 0.U
val x_data_en = io.dec_exu.decode_exu.dec_data_en(1)
val x_data_en_q1 = io.dec_exu.decode_exu.dec_data_en(1) & io.dec_exu.dec_alu.dec_csr_ren_d
val x_data_en_q2 = io.dec_exu.decode_exu.dec_data_en(1) & io.dec_exu.decode_exu.dec_i0_branch_d
val r_data_en = io.dec_exu.decode_exu.dec_data_en(0)
val r_data_en_q2 = io.dec_exu.decode_exu.dec_data_en(0) & i0_branch_x
val x_ctl_en = io.dec_exu.decode_exu.dec_ctl_en(1)
val r_ctl_en = io.dec_exu.decode_exu.dec_ctl_en(0)
val predpipe_d = Cat(io.dec_exu.decode_exu.i0_predict_fghr_d, io.dec_exu.decode_exu.i0_predict_index_d, io.dec_exu.decode_exu.i0_predict_btag_d)
val i0_flush_path_x =rvdffpcie(i0_flush_path_d,x_data_en.asBool,reset.asAsyncReset,clock,io.scan_mode)
i0_predict_p_x :=rvdffppe(i0_predict_p_d,clock,reset.asAsyncReset,x_data_en.asBool,io.scan_mode,elements= 13,io.exu_bp.exu_mp_pkt.bits.pret)
val predpipe_x =rvdffe(predpipe_d,x_data_en_q2.asBool,clock,io.scan_mode)
val predpipe_r =rvdffe(predpipe_x ,r_data_en_q2.asBool,clock,io.scan_mode)
val ghr_x =rvdffe(ghr_x_ns ,x_ctl_en.asBool,clock,io.scan_mode)
val i0_pred_correct_upper_x =rvdffe(i0_pred_correct_upper_d ,x_ctl_en.asBool,clock,io.scan_mode)
val i0_flush_upper_x =rvdffe(i0_flush_upper_d ,x_ctl_en.asBool,clock,io.scan_mode)
val i0_taken_x =rvdffe(i0_taken_d ,x_ctl_en.asBool,clock,io.scan_mode)
val i0_valid_x =rvdffe(i0_valid_d ,x_ctl_en.asBool,clock,io.scan_mode)
i0_pp_r :=rvdffppe(i0_predict_p_x,clock,reset.asAsyncReset(),r_ctl_en.asBool,io.scan_mode,elements = 13,io.exu_bp.exu_mp_pkt.bits.pret)
val pred_temp1 =rvdffpcie(io.dec_exu.decode_exu.pred_correct_npc_x(5,0) ,r_data_en.asBool,reset.asAsyncReset(),clock,io.scan_mode)
val i0_pred_correct_upper_r =rvdffppe_UInt(i0_pred_correct_upper_x ,clock,reset.asAsyncReset(),r_ctl_en.asBool,io.scan_mode,WIDTH=1)
val i0_flush_path_upper_r =rvdffpcie(i0_flush_path_x ,r_data_en.asBool,reset.asAsyncReset(),clock,io.scan_mode)
val pred_temp2 =rvdffpcie(io.dec_exu.decode_exu.pred_correct_npc_x(30,6) ,r_data_en.asBool,reset.asAsyncReset(),clock,io.scan_mode)
pred_correct_npc_r :=Cat(pred_temp2,pred_temp1)
ghr_d :=rvdffie(ghr_d_ns,clock,reset.asAsyncReset(),io.scan_mode)
mul_valid_x :=rvdffie(io.dec_exu.decode_exu.mul_p.valid,clock,reset.asAsyncReset(),io.scan_mode)
i0_branch_x :=rvdffie(io.dec_exu.decode_exu.dec_i0_branch_d,clock,reset.asAsyncReset(),io.scan_mode)
val i0_rs1_bypass_en_d = io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(0) | io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(1) | io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(2) | io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(3)
val i0_rs2_bypass_en_d = io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(0) | io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(1) | io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(2) | io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(3)
val i0_flush_path_x =rvdffe(i0_flush_path_d,x_data_en.asBool,clock,io.scan_mode)
io.dec_exu.decode_exu.exu_csr_rs1_x :=rvdffe(csr_rs1_in_d,x_data_en.asBool,clock,io.scan_mode)
i0_predict_p_x :=rvdffe(i0_predict_p_d,x_data_en.asBool,clock,io.scan_mode)
val predpipe_x =rvdffe(predpipe_d,x_data_en.asBool,clock,io.scan_mode)
val predpipe_r =rvdffe(predpipe_x ,r_data_en.asBool,clock,io.scan_mode)
val ghr_x =rvdffe(ghr_x_ns ,x_ctl_en.asBool,clock,io.scan_mode)
val i0_pred_correct_upper_x =rvdffe(i0_pred_correct_upper_d ,x_ctl_en.asBool,clock,io.scan_mode)
val i0_flush_upper_x =rvdffe(i0_flush_upper_d ,x_ctl_en.asBool,clock,io.scan_mode)
val i0_taken_x =rvdffe(i0_taken_d ,x_ctl_en.asBool,clock,io.scan_mode)
val i0_valid_x =rvdffe(i0_valid_d ,x_ctl_en.asBool,clock,io.scan_mode)
i0_pp_r :=rvdffe(i0_predict_p_x,r_ctl_en.asBool,clock,io.scan_mode)
val pred_temp1 =rvdffe(io.dec_exu.decode_exu.pred_correct_npc_x(5,0) ,r_ctl_en.asBool,clock,io.scan_mode)
val i0_pred_correct_upper_r =rvdffe(i0_pred_correct_upper_x ,r_ctl_en.asBool,clock,io.scan_mode)
val i0_flush_path_upper_r =rvdffe(i0_flush_path_x ,r_data_en.asBool,clock,io.scan_mode)
val pred_temp2 =rvdffe(io.dec_exu.decode_exu.pred_correct_npc_x(30,6) ,r_data_en.asBool,clock,io.scan_mode)
pred_correct_npc_r :=Cat(pred_temp2,pred_temp1)
when (BHT_SIZE.asUInt===32.U || BHT_SIZE.asUInt===64.U){
ghr_d :=RegEnable(ghr_d_ns,0.U,data_gate_en.asBool)
mul_valid_x :=RegEnable(io.dec_exu.decode_exu.mul_p.valid,0.U,data_gate_en.asBool)
flush_lower_ff :=RegEnable(io.dec_exu.tlu_exu.dec_tlu_flush_lower_r,0.U,data_gate_en.asBool)
}.otherwise{
ghr_d :=rvdffe(ghr_d_ns ,data_gate_en.asBool,clock,io.scan_mode)
mul_valid_x :=rvdffe(io.dec_exu.decode_exu.mul_p.valid ,data_gate_en.asBool,clock,io.scan_mode)
flush_lower_ff :=rvdffe(io.dec_exu.tlu_exu.dec_tlu_flush_lower_r ,data_gate_en.asBool,clock,io.scan_mode)
}
data_gate_en := (ghr_d_ns =/= ghr_d) | ( io.dec_exu.decode_exu.mul_p.valid =/= mul_valid_x) | ( io.dec_exu.tlu_exu.dec_tlu_flush_lower_r =/= flush_lower_ff)
val i0_rs1_bypass_en_d = io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(0) | io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(1)
val i0_rs2_bypass_en_d = io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(0) | io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(1)
val i0_rs1_bypass_data_d = Mux1H(Seq(
io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(0).asBool -> io.dec_exu.decode_exu.dec_i0_result_r,
io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(1).asBool -> io.lsu_exu.lsu_result_m,
io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(2).asBool -> io.dec_exu.decode_exu.exu_i0_result_x,
io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(3).asBool -> io.lsu_nonblock_load_data
io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(0).asBool -> io.dec_exu.decode_exu.dec_i0_rs1_bypass_data_d,
io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(1).asBool -> io.dec_exu.decode_exu.exu_i0_result_x
))
val i0_rs2_bypass_data_d = Mux1H(Seq(
io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(0).asBool -> io.dec_exu.decode_exu.dec_i0_result_r,
io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(1).asBool -> io.lsu_exu.lsu_result_m,
io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(2).asBool -> io.dec_exu.decode_exu.exu_i0_result_x,
io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(3).asBool -> io.lsu_nonblock_load_data
io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(0).asBool -> io.dec_exu.decode_exu.dec_i0_rs2_bypass_data_d,
io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(1).asBool -> io.dec_exu.decode_exu.exu_i0_result_x
))
val i0_rs1_d = Mux1H(Seq(
i0_rs1_bypass_en_d.asBool -> i0_rs1_bypass_data_d,
(!i0_rs1_bypass_en_d & io.dec_exu.decode_exu.dec_i0_select_pc_d).asBool -> Cat(io.dec_exu.ib_exu.dec_i0_pc_d,0.U(1.W)),
(!i0_rs1_bypass_en_d & io.dec_exu.ib_exu.dec_debug_wdata_rs1_d).asBool -> io.dbg_cmd_wrdata,
i0_rs1_bypass_en_d.asBool -> i0_rs1_bypass_data_d,
(!i0_rs1_bypass_en_d & io.dec_exu.decode_exu.dec_i0_select_pc_d).asBool -> Cat(io.dec_exu.ib_exu.dec_i0_pc_d,0.U(1.W)),
(!i0_rs1_bypass_en_d & io.dec_exu.ib_exu.dec_debug_wdata_rs1_d).asBool -> io.dbg_cmd_wrdata,
(!i0_rs1_bypass_en_d & !io.dec_exu.ib_exu.dec_debug_wdata_rs1_d & io.dec_exu.decode_exu.dec_i0_rs1_en_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs1_d
))
io.dec_exu.decode_exu.exu_csr_rs1_x :=rvdffe(i0_rs1_d,x_data_en_q1.asBool,clock,io.scan_mode)
val i0_rs2_d = Mux1H(Seq(
val i0_rs2_d = Mux1H(Seq(
(!i0_rs2_bypass_en_d & io.dec_exu.decode_exu.dec_i0_rs2_en_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs2_d,
(!i0_rs2_bypass_en_d).asBool -> io.dec_exu.decode_exu.dec_i0_immed_d,
(i0_rs2_bypass_en_d).asBool -> i0_rs2_bypass_data_d
(!i0_rs2_bypass_en_d).asBool -> io.dec_exu.decode_exu.dec_i0_immed_d,
(i0_rs2_bypass_en_d).asBool -> i0_rs2_bypass_data_d
))
dontTouch(i0_rs2_d)
io.lsu_exu.exu_lsu_rs1_d:=Mux1H(Seq(
(!i0_rs1_bypass_en_d & !io.dec_exu.decode_exu.dec_extint_stall & io.dec_exu.decode_exu.dec_i0_rs1_en_d & io.dec_exu.decode_exu.dec_qual_lsu_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs1_d,
(i0_rs1_bypass_en_d & !io.dec_exu.decode_exu.dec_extint_stall & io.dec_exu.decode_exu.dec_qual_lsu_d).asBool -> i0_rs1_bypass_data_d,
(io.dec_exu.decode_exu.dec_extint_stall & io.dec_exu.decode_exu.dec_qual_lsu_d).asBool -> Cat(io.dec_exu.tlu_exu.dec_tlu_meihap,0.U(2.W))
(!i0_rs1_bypass_en_d & !io.dec_exu.decode_exu.dec_extint_stall & io.dec_exu.decode_exu.dec_i0_rs1_en_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs1_d,
(i0_rs1_bypass_en_d & !io.dec_exu.decode_exu.dec_extint_stall).asBool -> i0_rs1_bypass_data_d,
(io.dec_exu.decode_exu.dec_extint_stall).asBool -> Cat(io.dec_exu.tlu_exu.dec_tlu_meihap,0.U(2.W))
))
io.lsu_exu.exu_lsu_rs2_d:=Mux1H(Seq(
(!i0_rs2_bypass_en_d & !io.dec_exu.decode_exu.dec_extint_stall & io.dec_exu.decode_exu.dec_i0_rs2_en_d & io.dec_exu.decode_exu.dec_qual_lsu_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs2_d,
(i0_rs2_bypass_en_d & !io.dec_exu.decode_exu.dec_extint_stall & io.dec_exu.decode_exu.dec_qual_lsu_d).asBool -> i0_rs2_bypass_data_d
(!i0_rs2_bypass_en_d & !io.dec_exu.decode_exu.dec_extint_stall & io.dec_exu.decode_exu.dec_i0_rs2_en_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs2_d,
(i0_rs2_bypass_en_d & !io.dec_exu.decode_exu.dec_extint_stall).asBool -> i0_rs2_bypass_data_d
))
val muldiv_rs1_d=Mux1H(Seq(
(!i0_rs1_bypass_en_d & io.dec_exu.decode_exu.dec_i0_rs1_en_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs1_d,
(i0_rs1_bypass_en_d).asBool -> i0_rs1_bypass_data_d
(i0_rs1_bypass_en_d).asBool -> i0_rs1_bypass_data_d
))
val muldiv_rs2_d=Mux1H(Seq(
(!i0_rs2_bypass_en_d & io.dec_exu.decode_exu.dec_i0_rs2_en_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs2_d,
(!i0_rs2_bypass_en_d).asBool -> io.dec_exu.decode_exu.dec_i0_immed_d,
(i0_rs2_bypass_en_d).asBool -> i0_rs2_bypass_data_d
))
csr_rs1_in_d := Mux(io.dec_exu.dec_alu.dec_csr_ren_d.asBool, i0_rs1_d, io.dec_exu.decode_exu.exu_csr_rs1_x)
val i_alu=Module(new exu_alu_ctl())
i_alu.io.dec_alu <> io.dec_exu.dec_alu
i_alu.io.scan_mode :=io.scan_mode
i_alu.io.enable :=x_data_en
i_alu.io.pp_in :=i0_predict_newp_d
i_alu.io.scan_mode :=io.scan_mode
i_alu.io.enable :=x_ctl_en
i_alu.io.pp_in :=i0_predict_newp_d
i_alu.io.flush_upper_x :=i0_flush_upper_x
i_alu.io.csr_rddata_in :=io.dec_csr_rddata_d
i_alu.io.dec_tlu_flush_lower_r :=io.dec_exu.tlu_exu.dec_tlu_flush_lower_r
i_alu.io.a_in :=i0_rs1_d.asSInt
i_alu.io.b_in :=i0_rs2_d
i_alu.io.dec_i0_pc_d :=io.dec_exu.ib_exu.dec_i0_pc_d
i_alu.io.i0_ap :=io.dec_exu.decode_exu.i0_ap
val alu_result_x =i_alu.io.result_ff
i0_flush_upper_d :=i_alu.io.flush_upper_out
i0_flush_path_d :=i_alu.io.flush_path_out
io.exu_flush_final := i_alu.io.flush_final_out
i0_predict_p_d :=i_alu.io.predict_p_out
i_alu.io.a_in :=i0_rs1_d.asSInt
i_alu.io.b_in :=i0_rs2_d
i_alu.io.dec_i0_pc_d :=io.dec_exu.ib_exu.dec_i0_pc_d
i_alu.io.i0_ap :=io.dec_exu.decode_exu.i0_ap
val alu_result_x =i_alu.io.result_ff
i0_flush_upper_d :=i_alu.io.flush_upper_out
i0_flush_path_d :=i_alu.io.flush_path_out
io.exu_flush_final := i_alu.io.flush_final_out
i0_predict_p_d :=i_alu.io.predict_p_out
i0_pred_correct_upper_d :=i_alu.io.pred_correct_out
val i_mul = Module(new exu_mul_ctl())
i_mul.io.scan_mode := io.scan_mode
i_mul.io.mul_p := io.dec_exu.decode_exu.mul_p
//i_mul.io.mul_p := VecInit.tabulate(io.dec_exu.decode_exu.mul_p.getElements.size-1)(i=>io.dec_exu.decode_exu.mul_p.getElements(i).asUInt & Fill(io.dec_exu.decode_exu.mul_p.getElements.size,io.dec_exu.decode_exu.mul_p.valid)).asTypeOf(io.dec_exu.decode_exu.mul_p) //& io.dec_exu.decode_exu.mul_p.valid
i_mul.io.rs1_in := muldiv_rs1_d & Fill(32,io.dec_exu.decode_exu.mul_p.valid)
i_mul.io.rs2_in := i0_rs2_d & Fill(32,io.dec_exu.decode_exu.mul_p.valid)
i_mul.io.mul_p := io.dec_exu.decode_exu.mul_p
i_mul.io.rs1_in := muldiv_rs1_d
i_mul.io.rs2_in := muldiv_rs2_d
val mul_result_x = i_mul.io.result_x
val i_div = Module(new exu_div_ctl())
i_div.io.dec_div <> io.dec_exu.dec_div
i_div.io.scan_mode := io.scan_mode
i_div.io.scan_mode := io.scan_mode
i_div.io.dividend := muldiv_rs1_d
i_div.io.divisor := i0_rs2_d
i_div.io.divisor := muldiv_rs2_d
io.exu_div_wren := i_div.io.exu_div_wren
io.exu_div_result := i_div.io.exu_div_result
io.dec_exu.decode_exu.exu_i0_result_x := Mux(mul_valid_x.asBool, mul_result_x, alu_result_x)
i0_predict_newp_d := io.dec_exu.decode_exu.dec_i0_predict_p_d
i0_predict_newp_d.bits.boffset := io.dec_exu.ib_exu.dec_i0_pc_d(0) // from the start of inst
io.dec_exu.decode_exu.exu_i0_result_x := Mux(mul_valid_x.asBool, mul_result_x, alu_result_x)
i0_predict_newp_d := io.dec_exu.decode_exu.dec_i0_predict_p_d
i0_predict_newp_d.bits.boffset := io.dec_exu.ib_exu.dec_i0_pc_d(0) // from the start of inst
io.dec_exu.tlu_exu.exu_pmu_i0_br_misp := i0_pp_r.bits.misp
io.dec_exu.tlu_exu.exu_pmu_i0_br_ataken := i0_pp_r.bits.ataken
@ -176,73 +188,48 @@ class exu extends Module with lib with RequireAsyncReset{
i0_taken_d := (i0_predict_p_d.bits.ataken & io.dec_exu.dec_alu.dec_i0_alu_decode_d)
if(BTB_ENABLE) {
// maintain GHR at D
ghr_d_ns := Mux1H(Seq(
(!io.dec_exu.tlu_exu.dec_tlu_flush_lower_r & i0_valid_d).asBool -> Cat(ghr_d(BHT_GHR_SIZE - 2, 0), i0_taken_d),
(!io.dec_exu.tlu_exu.dec_tlu_flush_lower_r & !i0_valid_d).asBool -> ghr_d,
(io.dec_exu.tlu_exu.dec_tlu_flush_lower_r).asBool -> ghr_x
))
// maintain GHR at X
ghr_x_ns := Mux(i0_valid_x === 1.U, Cat(ghr_x(BHT_GHR_SIZE - 2, 0), i0_taken_x), ghr_x)
// maintain GHR at D
ghr_d_ns:=Mux1H(Seq(
(!io.dec_exu.tlu_exu.dec_tlu_flush_lower_r & i0_valid_d).asBool -> Cat(ghr_d(BHT_GHR_SIZE-2,0),i0_taken_d),
(!io.dec_exu.tlu_exu.dec_tlu_flush_lower_r & !i0_valid_d).asBool -> ghr_d,
(io.dec_exu.tlu_exu.dec_tlu_flush_lower_r).asBool -> ghr_x
))
io.dec_exu.tlu_exu.exu_i0_br_valid_r := i0_pp_r.valid
io.dec_exu.tlu_exu.exu_i0_br_mp_r := i0_pp_r.bits.misp
io.exu_bp.exu_i0_br_way_r := i0_pp_r.bits.way
io.dec_exu.tlu_exu.exu_i0_br_hist_r := Fill(2, i0_pp_r.valid) & i0_pp_r.bits.hist
io.dec_exu.tlu_exu.exu_i0_br_error_r := i0_pp_r.bits.br_error
io.dec_exu.tlu_exu.exu_i0_br_middle_r := i0_pp_r.bits.pc4 ^ i0_pp_r.bits.boffset
io.dec_exu.tlu_exu.exu_i0_br_start_error_r := i0_pp_r.bits.br_start_error
io.exu_bp.exu_i0_br_fghr_r := predpipe_r(PREDPIPESIZE - 1, BTB_ADDR_HI + BTB_BTAG_SIZE - BTB_ADDR_LO + 1)
io.dec_exu.tlu_exu.exu_i0_br_index_r := predpipe_r(BTB_ADDR_HI + BTB_BTAG_SIZE - BTB_ADDR_LO, BTB_BTAG_SIZE)
io.exu_bp.exu_i0_br_index_r := io.dec_exu.tlu_exu.exu_i0_br_index_r
final_predict_mp := Mux(i0_flush_upper_x === 1.U, i0_predict_p_x, 0.U.asTypeOf(i0_predict_p_x))
val final_predpipe_mp = Mux(i0_flush_upper_x === 1.U, predpipe_x, 0.U)
// maintain GHR at X
ghr_x_ns:=Mux(i0_valid_x===1.U, Cat(ghr_x(BHT_GHR_SIZE-2,0),i0_taken_x), ghr_x )
val after_flush_eghr = Mux((i0_flush_upper_x === 1.U & !(io.dec_exu.tlu_exu.dec_tlu_flush_lower_r === 1.U)), ghr_d, ghr_x)
io.dec_exu.tlu_exu.exu_i0_br_valid_r := i0_pp_r.valid
io.dec_exu.tlu_exu.exu_i0_br_mp_r := i0_pp_r.bits.misp
io.exu_bp.exu_i0_br_way_r := i0_pp_r.bits.way
io.dec_exu.tlu_exu.exu_i0_br_hist_r := i0_pp_r.bits.hist
io.dec_exu.tlu_exu.exu_i0_br_error_r := i0_pp_r.bits.br_error
io.dec_exu.tlu_exu.exu_i0_br_middle_r := i0_pp_r.bits.pc4 ^ i0_pp_r.bits.boffset
io.dec_exu.tlu_exu.exu_i0_br_start_error_r := i0_pp_r.bits.br_start_error
io.exu_bp.exu_i0_br_fghr_r := predpipe_r(PREDPIPESIZE-1,BTB_ADDR_HI+BTB_BTAG_SIZE-BTB_ADDR_LO+1)
io.dec_exu.tlu_exu.exu_i0_br_index_r := predpipe_r(BTB_ADDR_HI+BTB_BTAG_SIZE-BTB_ADDR_LO,BTB_BTAG_SIZE)
io.exu_bp.exu_i0_br_index_r := io.dec_exu.tlu_exu.exu_i0_br_index_r
final_predict_mp := Mux(i0_flush_upper_x===1.U,i0_predict_p_x,0.U.asTypeOf(i0_predict_p_x))
val final_predpipe_mp = Mux(i0_flush_upper_x===1.U,predpipe_x,0.U)
io.exu_bp.exu_mp_pkt.valid := final_predict_mp.valid
io.exu_bp.exu_mp_pkt.bits.way := final_predict_mp.bits.way
io.exu_bp.exu_mp_pkt.bits.misp := final_predict_mp.bits.misp
io.exu_bp.exu_mp_pkt.bits.pcall := final_predict_mp.bits.pcall
io.exu_bp.exu_mp_pkt.bits.pja := final_predict_mp.bits.pja
io.exu_bp.exu_mp_pkt.bits.pret := final_predict_mp.bits.pret
io.exu_bp.exu_mp_pkt.bits.ataken := final_predict_mp.bits.ataken
io.exu_bp.exu_mp_pkt.bits.boffset := final_predict_mp.bits.boffset
io.exu_bp.exu_mp_pkt.bits.pc4 := final_predict_mp.bits.pc4
io.exu_bp.exu_mp_pkt.bits.hist := final_predict_mp.bits.hist(1, 0)
io.exu_bp.exu_mp_pkt.bits.toffset := final_predict_mp.bits.toffset(11, 0)
io.exu_bp.exu_mp_fghr := after_flush_eghr
io.exu_bp.exu_mp_index := final_predpipe_mp(PREDPIPESIZE - BHT_GHR_SIZE - 1, BTB_BTAG_SIZE)
io.exu_bp.exu_mp_btag := final_predpipe_mp(BTB_BTAG_SIZE - 1, 0)
io.exu_bp.exu_mp_eghr := final_predpipe_mp(PREDPIPESIZE - 1, BTB_ADDR_HI - BTB_ADDR_LO + BTB_BTAG_SIZE + 1) // mp ghr for bht write
}
else {
val after_flush_eghr = Mux((i0_flush_upper_x===1.U & !(io.dec_exu.tlu_exu.dec_tlu_flush_lower_r===1.U)), ghr_d, ghr_x)
ghr_d_ns := 0.U
ghr_x_ns := 0.U
io.exu_bp.exu_mp_pkt := 0.U
io.exu_bp.exu_mp_eghr := 0.U
io.exu_bp.exu_mp_fghr := 0.U
io.exu_bp.exu_mp_index := 0.U
io.exu_bp.exu_mp_btag := 0.U
io.dec_exu.tlu_exu.exu_i0_br_hist_r := 0.U
io.dec_exu.tlu_exu.exu_i0_br_error_r := 0.U
io.dec_exu.tlu_exu.exu_i0_br_start_error_r := 0.U
io.dec_exu.tlu_exu.exu_i0_br_index_r := 0.U
io.dec_exu.tlu_exu.exu_i0_br_valid_r := 0.U
io.dec_exu.tlu_exu.exu_i0_br_mp_r := 0.U
io.dec_exu.tlu_exu.exu_i0_br_middle_r := 0.U
io.exu_bp.exu_i0_br_fghr_r := 0.U
io.exu_bp.exu_i0_br_way_r := 0.U
}
io.exu_flush_path_final := Mux1H(Seq(
io.dec_exu.tlu_exu.dec_tlu_flush_lower_r.asBool -> io.dec_exu.tlu_exu.dec_tlu_flush_path_r,
(~io.dec_exu.tlu_exu.dec_tlu_flush_lower_r & i0_flush_upper_d).asBool -> i0_flush_path_d))
io.exu_bp.exu_mp_pkt.bits.way := final_predict_mp.bits.way
io.exu_bp.exu_mp_pkt.bits.misp := final_predict_mp.bits.misp
io.exu_bp.exu_mp_pkt.bits.pcall := final_predict_mp.bits.pcall
io.exu_bp.exu_mp_pkt.bits.pja := final_predict_mp.bits.pja
io.exu_bp.exu_mp_pkt.bits.pret := final_predict_mp.bits.pret
io.exu_bp.exu_mp_pkt.bits.ataken := final_predict_mp.bits.ataken
io.exu_bp.exu_mp_pkt.bits.boffset := final_predict_mp.bits.boffset
io.exu_bp.exu_mp_pkt.bits.pc4 := final_predict_mp.bits.pc4
io.exu_bp.exu_mp_pkt.bits.hist := final_predict_mp.bits.hist(1,0)
io.exu_bp.exu_mp_pkt.bits.toffset := final_predict_mp.bits.toffset(11,0)
io.exu_bp.exu_mp_fghr := after_flush_eghr
io.exu_bp.exu_mp_index := final_predpipe_mp(PREDPIPESIZE-BHT_GHR_SIZE-1,BTB_BTAG_SIZE)
io.exu_bp.exu_mp_btag := final_predpipe_mp(BTB_BTAG_SIZE-1,0)
io.exu_bp.exu_mp_eghr := final_predpipe_mp(PREDPIPESIZE-1,BTB_ADDR_HI-BTB_ADDR_LO+BTB_BTAG_SIZE+1) // mp ghr for bht write
io.exu_flush_path_final := Mux(io.dec_exu.tlu_exu.dec_tlu_flush_lower_r.asBool, io.dec_exu.tlu_exu.dec_tlu_flush_path_r, i0_flush_path_d)
io.dec_exu.tlu_exu.exu_npc_r := Mux(i0_pred_correct_upper_r===1.U, pred_correct_npc_r, i0_flush_path_upper_r)
}
object exu_main extends App {
println((new chisel3.stage.ChiselStage).emitVerilog(new exu()))
}

View File

@ -9,7 +9,6 @@ class exu_alu_ctl extends Module with lib with RequireAsyncReset{
val io = IO(new Bundle{
val dec_alu = new dec_alu()
val csr_rddata_in = Input(UInt(32.W)) // CSR data
val dec_i0_pc_d = Input(UInt(31.W)) // for pc=pc+2,4 calculations
val scan_mode = Input(UInt(1.W)) // Scan control
val flush_upper_x = Input(UInt(1.W)) // Branch flush from previous cycle
@ -27,123 +26,15 @@ class exu_alu_ctl extends Module with lib with RequireAsyncReset{
val pred_correct_out = Output(UInt(1.W)) // NPC control
val predict_p_out = Valid(new predict_pkt_t) // Predicted branch structure
})
//zbb
val ap_clz = WireInit(Bool(),0.B)
val ap_ctz = WireInit(Bool(),0.B)
val ap_pcnt = WireInit(Bool(),0.B)
val ap_sext_b = WireInit(Bool(),0.B)
val ap_sext_h = WireInit(Bool(),0.B)
val ap_min = WireInit(Bool(),0.B)
val ap_max = WireInit(Bool(),0.B)
val ap_pack = WireInit(Bool(),0.B)
val ap_packu = WireInit(Bool(),0.B)
val ap_packh = WireInit(Bool(),0.B)
val ap_rol = WireInit(Bool(),0.B)
val ap_ror = WireInit(Bool(),0.B)
val ap_rev = WireInit(Bool(),0.B)
val ap_rev8 = WireInit(Bool(),0.B)
val ap_orc_b = WireInit(Bool(),0.B)
val ap_orc16 = WireInit(Bool(),0.B)
val ap_zbb = WireInit(Bool(),0.B)
// Zbs
val ap_sbset = WireInit(Bool(),0.B)
val ap_sbclr = WireInit(Bool(),0.B)
val ap_sbinv = WireInit(Bool(),0.B)
val ap_sbext = WireInit(Bool(),0.B)
// Zbr
val ap_slo = WireInit(Bool(),0.B)
val ap_sro = WireInit(Bool(),0.B)
// Zba
val ap_sh1add = WireInit(Bool(),0.B)
val ap_sh2add = WireInit(Bool(),0.B)
val ap_sh3add = WireInit(Bool(),0.B)
val ap_zba = WireInit(Bool(),0.B)
if (BITMANIP_ZBB) {
ap_clz := io.i0_ap.clz
ap_ctz := io.i0_ap.ctz
ap_pcnt := io.i0_ap.pcnt
ap_sext_b := io.i0_ap.sext_b
ap_sext_h := io.i0_ap.sext_h
ap_min := io.i0_ap.min
ap_max := io.i0_ap.max
} else{
ap_clz := 0.U
ap_ctz := 0.U
ap_pcnt := 0.U
ap_sext_b := 0.U
ap_sext_h := 0.U
ap_min := 0.U
ap_max := 0.U
}
if ( (BITMANIP_ZBB) | (BITMANIP_ZBP) ) {
ap_pack := io.i0_ap.pack
ap_packu := io.i0_ap.packu
ap_packh := io.i0_ap.packh
ap_rol := io.i0_ap.rol
ap_ror := io.i0_ap.ror
ap_rev := io.i0_ap.grev & (io.b_in(4,0) === "b11111".U)
ap_rev8 := io.i0_ap.grev & (io.b_in(4,0) === "b11000".U)
ap_orc_b := io.i0_ap.gorc & (io.b_in(4,0) === "b00111".U)
ap_orc16 := io.i0_ap.gorc & (io.b_in(4,0) === "b10000".U)
ap_zbb := io.i0_ap.zbb
} else{
ap_pack := 0.U
ap_packu := 0.U
ap_packh := 0.U
ap_rol := 0.U
ap_ror := 0.U
ap_rev := 0.U
ap_rev8 := 0.U
ap_orc_b := 0.U
ap_orc16 := 0.U
ap_zbb := 0.U
}
if (BITMANIP_ZBS) {
ap_sbset := io.i0_ap.sbset
ap_sbclr := io.i0_ap.sbclr
ap_sbinv := io.i0_ap.sbinv
ap_sbext := io.i0_ap.sbext
}else {
ap_sbset := 0.U
ap_sbclr := 0.U
ap_sbinv := 0.U
ap_sbext := 0.U
}
if (BITMANIP_ZBP) {
ap_slo := io.i0_ap.slo
ap_sro := io.i0_ap.sro
} else {
ap_slo := 0.U
ap_sro := 0.U
}
if (BITMANIP_ZBA) {
ap_sh1add := io.i0_ap.sh1add
ap_sh2add := io.i0_ap.sh2add
ap_sh3add := io.i0_ap.sh3add
ap_zba := io.i0_ap.zba
} else {
ap_sh1add := 0.U
ap_sh2add := 0.U
ap_sh3add := 0.U
ap_zba := 0.U
}
io.dec_alu.exu_i0_pc_x := rvdffpcie(io.dec_i0_pc_d,io.enable,reset.asAsyncReset(),clock,io.scan_mode.asBool) // any PC is run through here - doesn't have to be alu
io.dec_alu.exu_i0_pc_x := rvdffe(io.dec_i0_pc_d,io.enable,clock,io.scan_mode.asBool) // any PC is run through here - doesn't have to be alu
val result = WireInit(UInt(32.W),0.U)
io.result_ff := rvdffe(result,io.enable & io.dec_alu.dec_i0_alu_decode_d,clock,io.scan_mode.asBool)
val zba_a_in = Mux1H(Seq(
ap_sh1add -> Cat(io.a_in(30,0),0.U(1.W)).asSInt ,
ap_sh2add -> Cat(io.a_in(29,0),0.U(2.W)).asSInt ,
ap_sh3add -> Cat(io.a_in(28,0),0.U(3.W)).asSInt ,
~ap_zba -> io.a_in ))
io.result_ff := rvdffe(result,io.enable,clock,io.scan_mode.asBool)
val bm = Mux( io.i0_ap.sub.asBool, ~io.b_in, io.b_in) //H:b modified
val aout = WireInit(UInt(33.W),0.U)
aout := Mux(io.i0_ap.sub.asBool,(Cat(0.U(1.W),zba_a_in) + Cat(0.U(1.W),~io.b_in) + Cat(0.U(32.W),io.i0_ap.sub)), (Cat(0.U(1.W),io.a_in) + Cat(0.U(1.W), io.b_in) + Cat(0.U(32.W),io.i0_ap.sub)))
aout := Mux(io.i0_ap.sub.asBool,(Cat(0.U(1.W),io.a_in) + Cat(0.U(1.W),~io.b_in) + Cat(0.U(32.W),io.i0_ap.sub)), (Cat(0.U(1.W),io.a_in) + Cat(0.U(1.W), io.b_in) + Cat(0.U(32.W),io.i0_ap.sub)))
val cout = aout(32)
val ov = (!io.a_in(31) & !bm(31) & aout(31)) | ( io.a_in(31) & bm(31) & !aout(31) ) //overflow check from last bits
@ -155,143 +46,31 @@ class exu_alu_ctl extends Module with lib with RequireAsyncReset{
val ge = !lt // if not less then
val lout = Mux1H(Seq(
io.dec_alu.dec_csr_ren_d -> io.csr_rddata_in.asSInt ,
(io.i0_ap.land & !ap_zbb).asBool -> (Cat(0.U(1.W),io.a_in).asSInt & io.b_in.asSInt) ,
(io.i0_ap.lor & !ap_zbb).asBool -> (Cat(0.U(1.W),io.a_in).asSInt | io.b_in.asSInt) ,
(io.i0_ap.lxor & !ap_zbb).asBool -> (Cat(0.U(1.W),io.a_in).asSInt ^ io.b_in.asSInt) ,
(io.i0_ap.land & ap_zbb).asBool -> (Cat(0.U(1.W),io.a_in).asSInt & ~io.b_in.asSInt) ,
(io.i0_ap.lor & ap_zbb).asBool -> (Cat(0.U(1.W),io.a_in).asSInt | ~io.b_in.asSInt) ,
(io.i0_ap.lxor & ap_zbb).asBool -> (Cat(0.U(1.W),io.a_in).asSInt ^ ~io.b_in.asSInt) ))
// val lout = Mux1H(Seq(
// io.dec_alu.dec_csr_ren_d.asBool -> io.b_in.asSInt, //read enable read rs2
// io.i0_ap.land.asBool -> (io.a_in & io.b_in.asSInt), //and rs1 and 2
// io.i0_ap.lor.asBool -> (io.a_in | io.b_in.asSInt),
// io.i0_ap.lxor.asBool -> (io.a_in ^ io.b_in.asSInt)))
// * * * * * * * * * * * * * * * * * * BitManip : SLO,SRO * * * * * * * * * * * * * * * * * *
// * * * * * * * * * * * * * * * * * * BitManip : ROL,ROR * * * * * * * * * * * * * * * * * *
// * * * * * * * * * * * * * * * * * * BitManip : ZBEXT * * * * * * * * * * * * * * * * * *
val lout = Mux1H(Seq(
io.dec_alu.dec_csr_ren_d.asBool -> io.b_in.asSInt, //read enable read rs2
io.i0_ap.land.asBool -> (io.a_in & io.b_in.asSInt), //and rs1 and 2
io.i0_ap.lor.asBool -> (io.a_in | io.b_in.asSInt),
io.i0_ap.lxor.asBool -> (io.a_in ^ io.b_in.asSInt)))
val shift_amount = Mux1H(Seq (
io.i0_ap.sll.asBool -> (32.U(6.W) - Cat(0.U(1.W),io.b_in(4,0))), // [5] unused
io.i0_ap.srl.asBool -> Cat(0.U(1.W),io.b_in(4,0)) ,
io.i0_ap.sra.asBool -> Cat(0.U(1.W),io.b_in(4,0)) ,
ap_rol -> (32.U(6.W) - Cat(0.U(1.W),io.b_in(4,0)) ) ,
ap_ror -> Cat(0.U(1.W),io.b_in(4,0)) ,
ap_slo -> (32.U(6.W) - Cat(0.U(1.W),io.b_in(4,0)) ) ,
ap_sro -> Cat(0.U(1.W),io.b_in(4,0)) ,
ap_sbext -> Cat(0.U(1.W),io.b_in(4,0)) ))
io.i0_ap.sra.asBool -> Cat(0.U(1.W),io.b_in(4,0)) ))
val shift_mask = WireInit(UInt(32.W),0.U)
shift_mask := ( "hffffffff".U(32.W) << (repl(5,io.i0_ap.sll | ap_slo) & io.b_in(4,0)) )
shift_mask := ( "hffffffff".U(32.W) << (repl(5,io.i0_ap.sll) & io.b_in(4,0)) )
val shift_extend = WireInit(UInt(63.W),0.U)
shift_extend := Cat((repl(31,io.i0_ap.sra) & repl(31,io.a_in(31))) | (repl(31,io.i0_ap.sll) & io.a_in(30,0)), io.a_in)
shift_extend := Cat( Mux1H(Seq(io.i0_ap.sra.asBool() -> Fill(31,io.a_in(31)) ,
io.i0_ap.sll.asBool() -> io.a_in(30,0) ,
ap_rol -> io.a_in(30,0) ,
ap_ror -> io.a_in(30,0) ,
ap_slo -> io.a_in(30,0) ,
ap_sro -> Fill(31,1.U) )),io.a_in)
shift_extend := Cat((repl(31,io.i0_ap.sra) & repl(31,io.a_in(31))) | (repl(31,io.i0_ap.sll) & io.a_in(30,0)),io.a_in)
val shift_long = WireInit(UInt(63.W),0.U)
shift_long := ( shift_extend >> shift_amount(4,0) ) // 62-32 unused
shift_long := ( shift_extend >> shift_amount(4,0) ); // 62-32 unused
val sout = ( shift_long(31,0) & shift_mask(31,0) ) | ( Fill(32,ap_slo) & ~shift_mask(31,0) ) //incase of sra shift_mask is 1
// * * * * * * * * * * * * * * * * * * BitManip : CLZ,CTZ * * * * * * * * * * * * * * * * * *
val bitmanip_a_reverse_ff = (0 until io.a_in.getWidth).map(i=> io.a_in(i).asUInt).reduce(Cat(_,_))
// {a_in[0], a_in[1], a_in[2], a_in[3], a_in[4], a_in[5], a_in[6], a_in[7],
// a_in[8], a_in[9], a_in[10], a_in[11], a_in[12], a_in[13], a_in[14], a_in[15],
// a_in[16], a_in[17], a_in[18], a_in[19], a_in[20], a_in[21], a_in[22], a_in[23],
// a_in[24], a_in[25], a_in[26], a_in[27], a_in[28], a_in[29], a_in[30], a_in[31]};
val bitmanip_lzd_in = Mux1H(Seq(ap_clz -> io.a_in, ap_ctz -> bitmanip_a_reverse_ff.asSInt))
/////////////////////
val bitmanip_lzd_os = bitmanip_lzd_in
val bitmanip_dw_lzd_enc = WireInit(UInt(6.W),0.U)
bitmanip_dw_lzd_enc := MuxCase(0.U,(0 until 32).map(i=> (bitmanip_lzd_os(31,i)===0.U)->(32-i).U))//return leading zeros
val bitmanip_clz_ctz_result = Cat(Fill(6, ap_clz | ap_ctz) & bitmanip_dw_lzd_enc(5), Fill(5,!bitmanip_dw_lzd_enc(5)) & bitmanip_dw_lzd_enc(4,0) )
// * * * * * * * * * * * * * * * * * * BitManip : PCNT * * * * * * * * * * * * * * * * * *
val bitmanip_pcnt_result = Fill(6,ap_pcnt) & PopCount(io.a_in)
// * * * * * * * * * * * * * * * * * * BitManip : SEXT_B,SEXT_H * * * * * * * * * * * * * * * * *
val sout = ( shift_long(31,0) & shift_mask(31,0) ); //incase of sra shift_mask is 1
val bitmanip_sext_result = Mux1H(Seq(ap_sext_b -> Cat( Fill(24,io.a_in(7)) ,io.a_in(7,0)),
ap_sext_h -> Cat( Fill(16,io.a_in(15)),io.a_in(15,0))) )
// * * * * * * * * * * * * * * * * * * BitManip : MIN,MAX,MINU,MAXU * * * * * * * * * * * * * * *
val bitmanip_minmax_sel = ap_min | ap_max;
val bitmanip_minmax_sel_a = ge ^ ap_min;
val bitmanip_minmax_result = Mux1H(Seq(
(bitmanip_minmax_sel & bitmanip_minmax_sel_a) -> io.a_in,
(bitmanip_minmax_sel & !bitmanip_minmax_sel_a) -> io.b_in.asSInt ))
// * * * * * * * * * * * * * * * * * * BitManip : PACK, PACKU, PACKH * * * * * * * * * * * * * * *
val bitmanip_pack_result = Fill(32,ap_pack) & Cat(io.b_in(15,0), io.a_in(15,0))
val bitmanip_packu_result = Fill(32,ap_packu) & Cat(io.b_in(31,16),io.a_in(31,16))
val bitmanip_packh_result = Fill(32,ap_packh) & Cat(0.U(16.W),io.b_in(7,0),io.a_in(7,0))
// * * * * * * * * * * * * * * * * * * BitManip : REV, REV8, ORC_B * * * * * * * * * * * * * * * *
val bitmanip_rev_result = Fill(32,ap_rev) & (0 until io.a_in.getWidth).map(i=> io.a_in(i).asUInt).reduce(Cat(_,_))
val bitmanip_rev8_result = Fill(32,ap_rev8) & (0 until io.a_in.getWidth/8).map(i=> io.a_in(7+i*8,0+i*8).asUInt).reduce(Cat(_,_)) //{a_in[7:0],a_in[15:8],a_in[23:16],a_in[31:24]};
// uint32_t gorc32(uint32_t rs1, uint32_t rs2)
// {
// uint32_t x = rs1;
// int shamt = rs2 & 31; ORC.B ORC16
// if (shamt & 1) x |= ((x & 0x55555555) << 1) | ((x & 0xAAAAAAAA) >> 1); 1 0
// if (shamt & 2) x |= ((x & 0x33333333) << 2) | ((x & 0xCCCCCCCC) >> 2); 1 0
// if (shamt & 4) x |= ((x & 0x0F0F0F0F) << 4) | ((x & 0xF0F0F0F0) >> 4); 1 0
// if (shamt & 8) x |= ((x & 0x00FF00FF) << 8) | ((x & 0xFF00FF00) >> 8); 0 0
// if (shamt & 16) x |= ((x & 0x0000FFFF) << 16) | ((x & 0xFFFF0000) >> 16); 0 1
// return x;
// }
// BEFORE 31 , 30 , 29 , 28 , 27 , 26, 25, 24
// shamt[0] b = a31|a30,a31|a30,a29|a28,a29|a28, a27|a26,a27|a26,a25|a24,a25|a24
// shamt[1] c = b31|b29,b30|b28,b31|b29,b30|b28, b27|b25,b26|b24,b27|b25,b26|b24
// shamt[2] d = c31|c27,c30|c26,c29|c25,c28|c24, c31|c27,c30|c26,c29|c25,c28|c24
//
// Expand d31 = c31 | c27;
// = b31 | b29 | b27 | b25;
// = a31|a30 | a29|a28 | a27|a26 | a25|a24
val bitmanip_orc_b_result = Fill(32,ap_orc_b) & (0 until io.a_in.getWidth/8).map(i=> Fill(8,io.a_in(7+i*8,0+i*8).orR).asUInt).reverse.reduce(Cat(_,_)) //{ {8{| a_in[31:24]}}, {8{| a_in[23:16]}}, {8{| a_in[15:8]}}, {8{| a_in[7:0]}} };
val bitmanip_orc16_result = Fill(32,ap_orc16) & Cat(io.a_in(31,16) | io.a_in(15,0), io.a_in(31,16) | io.a_in(15,0))
// * * * * * * * * * * * * * * * * * * BitManip : ZBSET, ZBCLR, ZBINV * * * * * * * * * * * * * *
val bitmanip_sb_1hot = "h00000001".U(32.W) << io.b_in(4,0)
val bitmanip_sb_data = Mux1H(Seq(
ap_sbset -> ( io.a_in | bitmanip_sb_1hot(31,0).asSInt),
ap_sbclr -> ( io.a_in & ~bitmanip_sb_1hot(31,0).asSInt),
ap_sbinv -> ( io.a_in ^ bitmanip_sb_1hot(31,0).asSInt) ))
val sel_shift = io.i0_ap.sll | io.i0_ap.srl | io.i0_ap.sra | ap_slo | ap_sro | ap_rol | ap_ror
val sel_adder = (io.i0_ap.add | io.i0_ap.sub | ap_zba) & !io.i0_ap.slt & !ap_min & !ap_max
val sel_shift = io.i0_ap.sll | io.i0_ap.srl | io.i0_ap.sra
val sel_adder = (io.i0_ap.add | io.i0_ap.sub) & !io.i0_ap.slt
val sel_pc = io.i0_ap.jal | io.pp_in.bits.pcall | io.pp_in.bits.pja | io.pp_in.bits.pret
val csr_write_data = Mux(io.i0_ap.csr_imm.asBool, io.b_in.asSInt, io.a_in)
@ -301,29 +80,11 @@ class exu_alu_ctl extends Module with lib with RequireAsyncReset{
// for jal or pcall, it will be the link address pc+2 or pc+4
val pcout = rvbradder(Cat(io.dec_i0_pc_d,0.U),Cat(io.dec_alu.dec_i0_br_immed_d,0.U))
result := lout(31,0) | (Fill(32,sel_shift) & sout(31,0)) |
(Fill(32,sel_adder) & aout(31,0)) |
(Fill(32,sel_pc) & pcout ) |
(Fill(32,io.i0_ap.csr_write) & csr_write_data(31,0)) |
Cat(0.U(31.W), slt_one) |
(Fill(32,ap_sbext) & Cat(0.U(31.W), sout(0))) |
(Cat(0.U(26.W), bitmanip_clz_ctz_result(5,0))) |
(Cat(0.U(26.W), bitmanip_pcnt_result(5,0)) ) |
bitmanip_sext_result(31,0) |
bitmanip_minmax_result(31,0) |
bitmanip_pack_result(31,0) |
bitmanip_packu_result(31,0) |
bitmanip_packh_result(31,0) |
bitmanip_rev_result(31,0) |
bitmanip_rev8_result(31,0) |
bitmanip_orc_b_result(31,0) |
bitmanip_orc16_result(31,0) |
bitmanip_sb_data(31,0)
// lout(31,0) | Cat(0.U(31.W),slt_one) | (Mux1H(Seq(
// sel_shift.asBool -> sout(31,0),
// sel_adder.asBool -> aout(31,0),
// sel_pc.asBool -> pcout,
// io.i0_ap.csr_write.asBool -> csr_write_data(31,0))))
result := lout(31,0) | Cat(0.U(31.W),slt_one) | (Mux1H(Seq(
sel_shift.asBool -> sout(31,0),
sel_adder.asBool -> aout(31,0),
sel_pc.asBool -> pcout,
io.i0_ap.csr_write.asBool -> csr_write_data(31,0))))
// *** branch handling ***
@ -360,3 +121,5 @@ class exu_alu_ctl extends Module with lib with RequireAsyncReset{
io.predict_p_out.bits.ataken := actual_taken; // send a control signal telling it branch taken or not
io.predict_p_out.bits.hist := newhist
}

View File

@ -1,6 +1,6 @@
package exu
import chisel3.{util, _}
import chisel3._
import chisel3.experimental.chiselName
import chisel3.util._
import include._
@ -8,93 +8,13 @@ import lib._
@chiselName
class exu_div_ctl extends Module with RequireAsyncReset with lib {
val io = IO(new Bundle {
val scan_mode = Input(Bool())
val dividend = Input(UInt(32.W))
val divisor = Input(UInt(32.W))
val exu_div_result = Output(UInt(32.W))
val exu_div_wren = Output(UInt(1.W))
val dec_div = new dec_div()
})
val out_raw =WireInit(0.U(32.W))
io.exu_div_result := Fill(32,io.exu_div_wren) & out_raw
if(!DIV_NEW) {
val divider_old = Module(new exu_div_existing_1bit_cheapshortq())
divider_old.io.scan_mode := io.scan_mode
divider_old.io.cancel := io.dec_div.dec_div_cancel
divider_old.io.valid_in := io.dec_div.div_p.valid
divider_old.io.signed_in := ~io.dec_div.div_p.bits.unsign
divider_old.io.rem_in := io.dec_div.div_p.bits.rem
divider_old.io.dividend_in := io.dividend
divider_old.io.divisor_in := io.divisor
out_raw := divider_old.io.data_out
io.exu_div_wren := divider_old.io.valid_out
}
if(DIV_NEW & DIV_BIT==1) {
val divider_new1 = Module(new exu_div_new_1bit_fullshortq())
divider_new1.io.scan_mode := io.scan_mode
divider_new1.io.cancel := io.dec_div.dec_div_cancel
divider_new1.io.valid_in := io.dec_div.div_p.valid
divider_new1.io.signed_in := ~io.dec_div.div_p.bits.unsign
divider_new1.io.rem_in := io.dec_div.div_p.bits.rem
divider_new1.io.dividend_in := io.dividend
divider_new1.io.divisor_in := io.divisor
out_raw := divider_new1.io.data_out
io.exu_div_wren := divider_new1.io.valid_out
}
if(DIV_NEW & DIV_BIT==2) {
val divider_new2 = Module(new exu_div_new_2bit_fullshortq())
divider_new2.io.scan_mode := io.scan_mode
divider_new2.io.cancel := io.dec_div.dec_div_cancel
divider_new2.io.valid_in := io.dec_div.div_p.valid
divider_new2.io.signed_in := ~io.dec_div.div_p.bits.unsign
divider_new2.io.rem_in := io.dec_div.div_p.bits.rem
divider_new2.io.dividend_in := io.dividend
divider_new2.io.divisor_in := io.divisor
out_raw := divider_new2.io.data_out
io.exu_div_wren := divider_new2.io.valid_out
}
if(DIV_NEW & DIV_BIT==3) {
val divider_new3 = Module(new exu_div_new_3bit_fullshortq())
divider_new3.io.scan_mode := io.scan_mode
divider_new3.io.cancel := io.dec_div.dec_div_cancel
divider_new3.io.valid_in := io.dec_div.div_p.valid
divider_new3.io.signed_in := ~io.dec_div.div_p.bits.unsign
divider_new3.io.rem_in := io.dec_div.div_p.bits.rem
divider_new3.io.dividend_in := io.dividend
divider_new3.io.divisor_in := io.divisor
out_raw := divider_new3.io.data_out
io.exu_div_wren := divider_new3.io.valid_out
}
if(DIV_NEW & DIV_BIT==4) {
val divider_new4 = Module(new exu_div_new_4bit_fullshortq())
divider_new4.io.scan_mode := io.scan_mode
divider_new4.io.cancel := io.dec_div.dec_div_cancel
divider_new4.io.valid_in := io.dec_div.div_p.valid
divider_new4.io.signed_in := ~io.dec_div.div_p.bits.unsign
divider_new4.io.rem_in := io.dec_div.div_p.bits.rem
divider_new4.io.dividend_in := io.dividend
divider_new4.io.divisor_in := io.divisor
out_raw := divider_new4.io.data_out
io.exu_div_wren := divider_new4.io.valid_out
}
}
object div_main extends App {
println((new chisel3.stage.ChiselStage).emitVerilog(new exu_div_ctl()))
}
////////////////////////////////////////// OLD DIVIDER /////////////////////////////////////
class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset with lib {
val io = IO(new Bundle{
val scan_mode = Input(Bool())
val cancel = Input(Bool())
val valid_in = Input(Bool())
val signed_in = Input(Bool())
val rem_in = Input(Bool())
val dividend_in = Input(UInt(32.W))
val divisor_in = Input(UInt(32.W))
val data_out = Output(UInt(32.W))
val valid_out = Output(UInt(1.W))
val scan_mode = Input(Bool())
val dividend = Input(UInt(32.W))
val divisor = Input(UInt(32.W))
val exu_div_result = Output(UInt(32.W))
val exu_div_wren = Output(UInt(1.W))
val dec_div = new dec_div()
})
val run_state = WireInit(0.U(1.W))
val count = WireInit(0.U(6.W))
@ -113,7 +33,7 @@ class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset wi
val rem_ff = WireInit(0.U(1.W))
val add = WireInit(0.U(1.W))
val a_eff = WireInit(0.U(33.W))
val a_eff_shift = WireInit(0.U(65.W))
val a_eff_shift = WireInit(0.U(56.W))
val rem_correct = WireInit(0.U(1.W))
val valid_ff_x = WireInit(0.U(1.W))
val finish_ff = WireInit(0.U(1.W))
@ -123,8 +43,7 @@ class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset wi
val count_in = WireInit(0.U(6.W))
val dividend_eff = WireInit(0.U(32.W))
val a_shift = WireInit(0.U(33.W))
val shortq = WireInit(0.U(6.W))
val valid_x = valid_ff_x & !io.cancel
val valid_x = valid_ff_x & !io.dec_div.dec_div_cancel
// START - short circuit logic for small numbers {{
// small number divides - any 4b / 4b is done in 1 cycle (divisor != 0)
@ -134,9 +53,9 @@ class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset wi
((q_ff(31,0) === 0.U) & (m_ff(31,0) =/= 0.U) & !rem_ff & valid_x)
def pat(x : List[Int], y : List[Int]) = {
val pat_a = (0 until x.size).map(i=> if(x(i)>=0) q_ff(x(i)) else !q_ff(x(i).abs)).reduce(_&_)
val pat_b = (0 until y.size).map(i=> if(y(i)>=0) m_ff(y(i)) else !m_ff(y(i).abs)).reduce(_&_)
pat_a & pat_b
val pat1 = (0 until x.size).map(i=> if(x(i)>=0) q_ff(x(i)) else !q_ff(x(i).abs)).reduce(_&_)
val pat2 = (0 until y.size).map(i=> if(y(i)>=0) m_ff(y(i)) else !m_ff(y(i).abs)).reduce(_&_)
pat1 & pat2
}
val smallnum = Cat(
@ -168,32 +87,32 @@ class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset wi
short_dividend := Cat (sign_ff & q_ff(31),q_ff(31,0))
val a_cls = Cat(0.U(2.W),
val a_cls = Cat(
Mux1H(Seq (
!short_dividend(32).asBool -> (short_dividend(31,24) =/= Fill(8,0.U)),
short_dividend(32).asBool -> (short_dividend(31,23) =/= Fill(9,1.U))
short_dividend(32).asBool -> (short_dividend(31,23) =/= Fill(9,1.U))
)),
Mux1H(Seq (
!short_dividend(32).asBool -> (short_dividend(23,16) =/= Fill(8,0.U)),
short_dividend(32).asBool -> (short_dividend(22,15) =/= Fill(8,1.U))
short_dividend(32).asBool -> (short_dividend(22,15) =/= Fill(8,1.U))
)),
Mux1H(Seq (
!short_dividend(32).asBool -> (short_dividend(15,8) =/= Fill(8,0.U)),
short_dividend(32).asBool -> (short_dividend(14,7) =/= Fill(8,1.U))
short_dividend(32).asBool -> (short_dividend(14,7) =/= Fill(8,1.U))
))
)
val b_cls = Cat(0.U(2.W),
val b_cls = Cat(
Mux1H(Seq (
!m_ff(32).asBool -> (m_ff(31,24) =/= Fill(8,0.U)),
m_ff(32).asBool -> (m_ff(31,24) =/= Fill(8,1.U))
m_ff(32).asBool -> (m_ff(31,24) =/= Fill(8,1.U))
)),
Mux1H(Seq (
!m_ff(32).asBool -> (m_ff(23,16) =/= Fill(8,0.U)),
m_ff(32).asBool -> (m_ff(23,16) =/= Fill(8,1.U))
m_ff(32).asBool -> (m_ff(23,16) =/= Fill(8,1.U))
)),
Mux1H(Seq (
!m_ff(32).asBool -> (m_ff(15,8) =/= Fill(8,0.U)),
m_ff(32).asBool -> (m_ff(15,8) =/= Fill(8,1.U))
m_ff(32).asBool -> (m_ff(15,8) =/= Fill(8,1.U))
))
)
val shortq_raw = Cat(
@ -209,7 +128,7 @@ class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset wi
( (a_cls(2,0) === "b001".U ) & (b_cls(2,0) === "b001".U ) ) |
( (a_cls(2,0) === "b000".U ) & (b_cls(2,0) === "b000".U ) ) ,
( (a_cls(2) === "b1".U ) & (b_cls(2,1) === "b01".U ) ) | // Shift by 16
( (a_cls(2) === "b1".U ) & (b_cls(2,1) === "b01".U ) ) | // Shift by 16
( (a_cls(2,1) === "b01".U ) & (b_cls(2,0) === "b001".U ) ) |
( (a_cls(2,0) === "b001".U ) & (b_cls(2,0) === "b000".U ) ) ,
@ -218,37 +137,43 @@ class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset wi
)
val shortq_enable = valid_ff_x & (m_ff(31,0) =/= 0.U(32.W)) & (shortq_raw =/= 0.U(4.W))
val shortq_shift = Cat(0.U(2.W),Fill(4,shortq_enable) & shortq_raw)
val shortq_shift_ff = Cat(0.U(1.W),Mux1H(Seq (
val shortq_shift = Fill(4,shortq_enable) & shortq_raw
val shortq_shift_ff = Mux1H(Seq (
shortq_shift_xx(3).asBool -> "b11111".U,
shortq_shift_xx(2).asBool -> "b11000".U,
shortq_shift_xx(1).asBool -> "b10000".U,
shortq_shift_xx(0).asBool -> "b01000".U
)))
))
// *** End Short *** }}
val finish = smallnum_case | Mux(!rem_ff ,count === 32.U(6.W) ,count === 33.U(6.W))
val div_clken = io.valid_in | run_state | finish | finish_ff
val run_in = (io.valid_in | run_state) & !finish & !io.cancel
count_in := Fill(6,(run_state & !finish & !io.cancel & !shortq_enable)) & (count + Cat(0.U,shortq_shift_ff(4,0)) + (1.U)(6.W))
io.valid_out := finish_ff & !io.cancel
val sign_eff = io.signed_in & (io.divisor_in =/= 0.U(32.W))
val div_clken = io.dec_div.div_p.valid | run_state | finish | finish_ff
val run_in = (io.dec_div.div_p.valid | run_state) & !finish & !io.dec_div.dec_div_cancel
count_in := Fill(6,(run_state & !finish & !io.dec_div.dec_div_cancel & !shortq_enable)) & (count + Cat(0.U,shortq_shift_ff) + (1.U)(6.W))
//io.test := count_in
io.exu_div_wren := finish_ff & !io.dec_div.dec_div_cancel
val sign_eff = !io.dec_div.div_p.bits.unsign & (io.divisor =/= 0.U(32.W))
q_in := Mux1H(Seq(
(!run_state).asBool -> Cat(0.U(1.W),io.dividend_in) ,
(run_state & (valid_ff_x | shortq_enable_ff)).asBool -> (Cat(dividend_eff(31,0),!a_in(32)) << shortq_shift_ff(4,0)) ,
(!run_state).asBool -> Cat(0.U(1.W),io.dividend) ,
(run_state & (valid_ff_x | shortq_enable_ff)).asBool -> (Cat(dividend_eff(31,0),!a_in(32)) << shortq_shift_ff) ,
(run_state & !(valid_ff_x | shortq_enable_ff)).asBool -> Cat(q_ff(31,0),!a_in(32))
))
val qff_enable = io.valid_in | (run_state & !shortq_enable)
val qff_enable = io.dec_div.div_p.valid | (run_state & !shortq_enable)
dividend_eff := Mux((sign_ff & dividend_neg_ff).asBool, rvtwoscomp(q_ff(31,0)),q_ff(31,0))
m_eff := Mux(add.asBool , m_ff, ~m_ff )
a_eff_shift := Cat(0.U(33.W), dividend_eff) << shortq_shift_ff(4,0)
a_eff_shift := Cat(0.U(24.W), dividend_eff) << shortq_shift_ff
a_eff := Mux1H(Seq(
rem_correct.asBool -> a_ff ,
(!rem_correct & !shortq_enable_ff).asBool -> Cat(a_ff(31,0), q_ff(32)) ,
(!rem_correct & shortq_enable_ff).asBool -> a_eff_shift(64,32)
(!rem_correct & shortq_enable_ff).asBool -> Cat(0.U(9.W),a_eff_shift(55,32))
))
val aff_enable = io.valid_in | (run_state & !shortq_enable & (count =/= 33.U(6.W))) | rem_correct
val aff_enable = io.dec_div.div_p.valid | (run_state & !shortq_enable & (count =/= 33.U(6.W))) | rem_correct
a_shift := Fill(33,run_state) & a_eff
a_in := Fill(33,run_state) & (a_shift + m_eff + Cat(0.U(32.W),!add))
val m_already_comp = divisor_neg_ff & sign_ff
@ -258,698 +183,29 @@ class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset wi
val q_ff_eff = Mux((sign_ff & (dividend_neg_ff ^ divisor_neg_ff)).asBool,rvtwoscomp(q_ff(31,0)), q_ff(31,0))
val a_ff_eff = Mux((sign_ff & dividend_neg_ff ).asBool, rvtwoscomp(a_ff(31,0)), a_ff(31,0))
io.data_out := Mux1H(Seq(
io.exu_div_result := Mux1H(Seq(
smallnum_case_ff.asBool -> Cat(0.U(28.W), smallnum_ff),
rem_ff.asBool -> a_ff_eff ,
(!smallnum_case_ff & !rem_ff).asBool -> q_ff_eff
))
valid_ff_x := rvdffe(io.valid_in & !io.cancel, div_clken,clock,io.scan_mode)
finish_ff := rvdffe(finish & !io.cancel, div_clken,clock,io.scan_mode)
run_state := rvdffe(run_in,div_clken,clock,io.scan_mode)
count := rvdffe(count_in, div_clken,clock,io.scan_mode)
dividend_neg_ff := rvdffe((io.valid_in & io.dividend_in(31)) | (!io.valid_in & dividend_neg_ff), div_clken,clock,io.scan_mode)
divisor_neg_ff := rvdffe((io.valid_in & io.divisor_in(31)) | (!io.valid_in & divisor_neg_ff), div_clken,clock,io.scan_mode)
sign_ff := rvdffe((io.valid_in & sign_eff) | (!io.valid_in & sign_ff), div_clken,clock,io.scan_mode)
rem_ff := rvdffe((io.valid_in & io.rem_in) | (!io.valid_in & rem_ff), div_clken,clock,io.scan_mode)
smallnum_case_ff := rvdffe(smallnum_case, div_clken,clock,io.scan_mode)
smallnum_ff := rvdffe(smallnum, div_clken,clock,io.scan_mode)
shortq_enable_ff := rvdffe(shortq_enable, div_clken,clock,io.scan_mode)
shortq_shift_xx := rvdffe(shortq_shift, div_clken,clock,io.scan_mode)
q_ff := rvdffe(q_in, qff_enable,clock,io.scan_mode)
a_ff := rvdffe(a_in, aff_enable,clock,io.scan_mode)
m_ff := rvdffe(Cat(io.signed_in & io.divisor_in(31), io.divisor_in(31,0)), io.valid_in,clock,io.scan_mode)
}
/////////////////////////////////////////////// 1 BIT FULL DIVIDER//////////////////////////////////
class exu_div_new_1bit_fullshortq extends Module with RequireAsyncReset with lib {
val io = IO(new Bundle{
val scan_mode = Input(Bool())
val cancel = Input(Bool())
val valid_in = Input(Bool())
val signed_in = Input(Bool())
val rem_in = Input(Bool())
val dividend_in = Input(UInt(32.W))
val divisor_in = Input(UInt(32.W))
val data_out = Output(UInt(32.W))
val valid_out = Output(UInt(1.W))
})
val valid_ff = WireInit(Bool(),init=false.B)
val finish_ff = WireInit(Bool(),init=false.B)
val control_ff = WireInit(0.U(3.W))
val count_ff = WireInit(0.U(7.W))
val smallnum = WireInit(0.U(4.W))
val a_ff = WireInit(0.U(32.W))
val b_ff = WireInit(0.U(33.W))
val q_ff = WireInit(0.U(32.W))
val r_ff = WireInit(0.U(32.W))
val quotient_set = WireInit(Bool(),init=false.B)
val shortq_enable = WireInit(Bool(),init=false.B)
val shortq_enable_ff = WireInit(Bool(),init=false.B)
val by_zero_case_ff = WireInit(Bool(),init=false.B)
val adder_out = WireInit(0.U(33.W))
val ar_shifted = WireInit(0.U(64.W))
val shortq_shift_ff = WireInit(0.U(5.W))
val dividend_sign_ff = control_ff(2)
val divisor_sign_ff = control_ff(1)
val rem_ff = control_ff(0)
val by_zero_case = valid_ff & (b_ff(31,0) === 0.U)
val smallnum_case = ((a_ff(31,4) === 0.U) & (b_ff(31,4) === 0.U) & !by_zero_case & !rem_ff & valid_ff & !io.cancel) |
((a_ff(31,0) === 0.U) & !by_zero_case & !rem_ff & valid_ff & !io.cancel)
val valid_ff_in = io.valid_in & !io.cancel
val control_in = Cat((!io.valid_in & control_ff(2)) | (io.valid_in & io.signed_in & io.dividend_in(31)), (!io.valid_in & control_ff(1)) | (io.valid_in & io.signed_in & io.divisor_in(31)), (!io.valid_in & control_ff(0)) | (io.valid_in & io.rem_in))
val running_state = count_ff.orR() | shortq_enable_ff
val misc_enable = io.valid_in | valid_ff | io.cancel | running_state | finish_ff
val finish_raw = smallnum_case | by_zero_case | (count_ff === 32.U)
val finish = finish_raw & !io.cancel
val count_enable = (valid_ff | running_state) & !finish & !finish_ff & !io.cancel & !shortq_enable
val count_in = Fill(7,count_enable) & (count_ff + Cat(0.U(6.W),1.U) + Cat(0.U(2.W),shortq_shift_ff))
val a_enable = io.valid_in | running_state
val a_shift = running_state & !shortq_enable_ff
ar_shifted := Cat (Fill(32,dividend_sign_ff),a_ff) << shortq_shift_ff
val b_twos_comp = valid_ff & !(dividend_sign_ff ^ divisor_sign_ff)
val twos_comp_b_sel = valid_ff & !(dividend_sign_ff ^ divisor_sign_ff)
val twos_comp_q_sel = !valid_ff & !rem_ff & (dividend_sign_ff ^ divisor_sign_ff) & !by_zero_case_ff
val b_enable = io.valid_in | b_twos_comp
val rq_enable = io.valid_in | valid_ff | running_state
val r_sign_sel = valid_ff & dividend_sign_ff & !by_zero_case
val r_restore_sel = running_state & !quotient_set & !shortq_enable_ff
val r_adder_sel = running_state & quotient_set & !shortq_enable_ff
val twos_comp_in = Mux1H(Seq (
twos_comp_q_sel -> q_ff,
twos_comp_b_sel -> b_ff(31,0)
))
val twos_comp_out = rvtwoscomp(twos_comp_in)
val exu_div_cgc = rvclkhdr(clock,div_clken.asBool,io.scan_mode)
val a_in = Mux1H(Seq (
(!a_shift & !shortq_enable_ff).asBool -> io.dividend_in,
a_shift -> Cat(a_ff(30,0),0.U),
shortq_enable_ff -> ar_shifted(31,0)
))
val b_in = Mux1H(Seq (
!b_twos_comp -> Cat(io.signed_in & io.divisor_in(31),io.divisor_in(31,0)),
b_twos_comp -> Cat(!divisor_sign_ff,twos_comp_out(31,0))
))
val r_in = Mux1H (Seq(
r_sign_sel -> "hffffffff".U(32.W),
r_restore_sel -> Cat(r_ff(30,0),a_ff(31)),
r_adder_sel -> adder_out(31,0),
shortq_enable_ff -> ar_shifted(63,32),
by_zero_case -> a_ff
))
val q_in = Mux1H (Seq(
!valid_ff -> Cat(q_ff(30,0),quotient_set),
smallnum_case -> Cat(0.U(28.W),smallnum),
by_zero_case -> Fill(32,1.U)
))
adder_out := Cat(r_ff,a_ff(31)) + b_ff
quotient_set := (!adder_out(32) ^ dividend_sign_ff) | ((a_ff(30,0) === 0.U) & (adder_out === 0.U))
io.valid_out := finish_ff & !io.cancel
io.data_out := Mux1H(Seq(
(!rem_ff & !twos_comp_q_sel).asBool() -> q_ff,
rem_ff -> r_ff,
twos_comp_q_sel -> twos_comp_out
))
def pat1(x : List[Int], y : List[Int]) = {
val pat_a = (0 until x.size).map(i=> if(x(i)>=0) a_ff(x(i)) else !a_ff(x(i).abs)).reduce(_&_)
val pat_b = (0 until y.size).map(i=> if(y(i)>=0) b_ff(y(i)) else !b_ff(y(i).abs)).reduce(_&_)
pat_a & pat_b
withClock(exu_div_cgc) {
valid_ff_x := RegNext(io.dec_div.div_p.valid & !io.dec_div.dec_div_cancel, 0.U)
finish_ff := RegNext(finish & !io.dec_div.dec_div_cancel, 0.U)
run_state := RegNext(run_in, 0.U)
count := RegNext(count_in, 0.U)
dividend_neg_ff := RegEnable(io.dividend(31), 0.U, io.dec_div.div_p.valid.asBool)
divisor_neg_ff := RegEnable(io.divisor(31), 0.U, io.dec_div.div_p.valid.asBool)
sign_ff := RegEnable(sign_eff, 0.U, io.dec_div.div_p.valid.asBool)
rem_ff := RegEnable(io.dec_div.div_p.bits.rem, 0.U, io.dec_div.div_p.valid.asBool)
smallnum_case_ff := RegNext(smallnum_case, 0.U)
smallnum_ff := RegNext(smallnum, 0.U)
shortq_enable_ff := RegNext(shortq_enable, 0.U)
shortq_shift_xx := RegNext(shortq_shift, 0.U)
}
smallnum := Cat(
pat1(List(3),List(-3, -2, -1)),
pat1(List(3),List(-3, -2))& !b_ff(0) | pat1(List(2),List(-3, -2, -1)) | pat1(List(3, 2),List(-3, -2)),
pat1(List(2),List(-3, -2))& !b_ff(0) | pat1(List(1),List(-3, -2, -1)) | pat1(List(3),List(-3, -1))& !b_ff(0) |
pat1(List(3, -2),List(-3, -2, 1, 0)) | pat1(List(-3, 2, 1),List(-3, -2)) | pat1(List(3, 2),List(-3))& !b_ff(0) |
pat1(List(3, 2),List(-3, 2, -1)) | pat1(List(3, 1),List(-3,-1)) | pat1(List(3, 2, 1),List(-3, 2)),
pat1(List(2, 1, 0),List(-3, -1)) | pat1(List(3, -2, 0),List(-3, 1, 0)) | pat1(List(2),List(-3, -1))& !b_ff(0) |
pat1(List(1),List(-3, -2))& !b_ff(0) | pat1(List(0),List(-3, -2, -1)) | pat1(List(-3, 2, -1),List(-3, -2, 1, 0)) |
pat1(List(-3, 2, 1),List(-3))& !b_ff(0) | pat1(List(3),List(-2, -1)) & !b_ff(0) | pat1(List(3, -2),List(-3, 2, 1)) |
pat1(List(-3, 2, 1),List(-3, 2, -1)) | pat1(List(-3, 2, 0),List(-3, -1)) | pat1(List(3, -2, -1),List(-3, 2, 0)) |
pat1(List(-2, 1, 0),List(-3, -2)) | pat1(List(3, 2),List(-1)) & !b_ff(0) | pat1(List(-3, 2, 1, 0),List(-3, 2)) |
pat1(List(3, 2),List(3, -2)) | pat1(List(3, 1),List(3,-2,-1)) | pat1(List(3, 0),List(-2, -1)) |
pat1(List(3, -1),List(-3, 2, 1, 0)) | pat1(List(3, 2, 1),List(3)) & !b_ff(0) | pat1(List(3, 2, 1),List(3, -1)) |
pat1(List(3, 2, 0),List(3, -1)) | pat1(List(3, -2, 1),List(-3, 1)) | pat1(List(3, 1, 0),List(-2)) |
pat1(List(3, 2, 1, 0),List(3)) |pat1(List(3, 1),List(-2)) & !b_ff(0))
val shortq_dividend = Cat(dividend_sign_ff,a_ff)
val a_enc = Module(new exu_div_cls)
a_enc.io.operand := shortq_dividend
val dw_a_enc1 = a_enc.io.cls
val b_enc = Module(new exu_div_cls)
b_enc.io.operand := b_ff
val dw_b_enc1 = b_enc.io.cls
val dw_a_enc = Cat (0.U, dw_a_enc1)
val dw_b_enc = Cat (0.U, dw_b_enc1)
val dw_shortq_raw = Cat(0.U,dw_b_enc) - Cat(0.U,dw_a_enc) + 1.U(7.W)
val shortq = Mux(dw_shortq_raw(6).asBool(),0.U,dw_shortq_raw(5,0))
shortq_enable := valid_ff & !shortq(5) & !(shortq(4,1) === "b1111".U) & !io.cancel
val shortq_shift = Mux(!shortq_enable,0.U,("b11111".U - shortq(4,0)))
valid_ff := rvdffe(valid_ff_in, misc_enable,clock,io.scan_mode)
control_ff := rvdffe(control_in, misc_enable,clock,io.scan_mode)
by_zero_case_ff := rvdffe(by_zero_case,misc_enable,clock,io.scan_mode)
shortq_enable_ff := rvdffe(shortq_enable, misc_enable,clock,io.scan_mode)
shortq_shift_ff := rvdffe(shortq_shift, misc_enable,clock,io.scan_mode)
finish_ff := rvdffe(finish, misc_enable,clock,io.scan_mode)
count_ff := rvdffe(count_in, misc_enable,clock,io.scan_mode)
a_ff := rvdffe(a_in, a_enable,clock,io.scan_mode)
b_ff := rvdffe(b_in, b_enable,clock,io.scan_mode)
r_ff := rvdffe(r_in, rq_enable,clock,io.scan_mode)
q_ff := rvdffe(q_in, rq_enable,clock,io.scan_mode)
}
/////////////////////////////////////////////// 2 BIT FULL DIVIDER//////////////////////////////////
class exu_div_new_2bit_fullshortq extends Module with RequireAsyncReset with lib {
val io = IO(new Bundle{
val scan_mode = Input(Bool())
val cancel = Input(Bool())
val valid_in = Input(Bool())
val signed_in = Input(Bool())
val rem_in = Input(Bool())
val dividend_in = Input(UInt(32.W))
val divisor_in = Input(UInt(32.W))
val data_out = Output(UInt(32.W))
val valid_out = Output(UInt(1.W))
})
val valid_ff = WireInit(Bool(),init=false.B)
val finish_ff = WireInit(Bool(),init=false.B)
val control_ff = WireInit(0.U(3.W))
val count_ff = WireInit(0.U(7.W))
val smallnum = WireInit(0.U(4.W))
val a_ff = WireInit(0.U(32.W))
val b_ff1 = WireInit(0.U(33.W))
val b_ff = WireInit(0.U(35.W))
val q_ff = WireInit(0.U(32.W))
val r_ff = WireInit(0.U(32.W))
val quotient_raw = WireInit(0.U(4.W))
val quotient_new = WireInit(0.U(2.W))
val shortq_enable = WireInit(Bool(),init=false.B)
val shortq_enable_ff = WireInit(Bool(),init=false.B)
val by_zero_case_ff = WireInit(Bool(),init=false.B)
val ar_shifted = WireInit(0.U(64.W))
val shortq_shift_ff = WireInit(0.U(5.W))
val valid_ff_in = io.valid_in & !io.cancel
val control_in = Cat((!io.valid_in & control_ff(2)) | (io.valid_in & io.signed_in & io.dividend_in(31)), (!io.valid_in & control_ff(1)) | (io.valid_in & io.signed_in & io.divisor_in(31)), (!io.valid_in & control_ff(0)) | (io.valid_in & io.rem_in))
val dividend_sign_ff = control_ff(2)
val divisor_sign_ff = control_ff(1)
val rem_ff = control_ff(0)
val by_zero_case = valid_ff & (b_ff(31,0) === 0.U)
val smallnum_case = ((a_ff(31,4) === 0.U) & (b_ff(31,4) === 0.U) & !by_zero_case & !rem_ff & valid_ff & !io.cancel) |
((a_ff(31,0) === 0.U) & !by_zero_case & !rem_ff & valid_ff & !io.cancel)
val running_state = count_ff.orR() | shortq_enable_ff
val misc_enable = io.valid_in | valid_ff | io.cancel | running_state | finish_ff
val finish_raw = smallnum_case | by_zero_case | (count_ff === 32.U)
val finish = finish_raw & !io.cancel
val count_enable = (valid_ff | running_state) & !finish & !finish_ff & !io.cancel & !shortq_enable
val count_in = Fill(7,count_enable) & (count_ff + Cat(0.U(5.W),2.U) + Cat(0.U(2.W),shortq_shift_ff(4,1),0.U))
val a_enable = io.valid_in | running_state
val a_shift = running_state & !shortq_enable_ff
ar_shifted := Cat (Fill(32,dividend_sign_ff),a_ff) << Cat(shortq_shift_ff(4,1),0.U)
val b_twos_comp = valid_ff & !(dividend_sign_ff ^ divisor_sign_ff)
val twos_comp_b_sel = valid_ff & !(dividend_sign_ff ^ divisor_sign_ff)
val twos_comp_q_sel = !valid_ff & !rem_ff & (dividend_sign_ff ^ divisor_sign_ff) & !by_zero_case_ff
val b_enable = io.valid_in | b_twos_comp
val rq_enable = io.valid_in | valid_ff | running_state
val r_sign_sel = valid_ff & dividend_sign_ff & !by_zero_case
val r_restore_sel = running_state & (quotient_new === 0.U) & !shortq_enable_ff
val r_adder1_sel = running_state & (quotient_new === 1.U) & !shortq_enable_ff
val r_adder2_sel = running_state & (quotient_new === 2.U) & !shortq_enable_ff
val r_adder3_sel = running_state & (quotient_new === 3.U) & !shortq_enable_ff
val adder1_out = Cat(r_ff(30,0),a_ff(31,30)) + b_ff(32,0)
val adder2_out = Cat(r_ff(31,0),a_ff(31,30)) + Cat(b_ff(32,0),0.U)
val adder3_out = Cat(r_ff(31),r_ff(31,0),a_ff(31,30)) + Cat(b_ff(33,0),0.U) + b_ff
quotient_raw := Cat((!adder3_out(34) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder3_out === 0.U)),
(!adder2_out(33) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder2_out === 0.U)),
(!adder1_out(32) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder1_out === 0.U)),0.U)
quotient_new := Cat ((quotient_raw(3) | quotient_raw(2)) , (quotient_raw(3) |(!quotient_raw(2) & quotient_raw(1))))
val twos_comp_in = Mux1H(Seq (
twos_comp_q_sel -> q_ff,
twos_comp_b_sel -> b_ff(31,0)
))
val twos_comp_out = rvtwoscomp(twos_comp_in)
val a_in = Mux1H(Seq (
(!a_shift & !shortq_enable_ff).asBool -> io.dividend_in,
a_shift -> Cat(a_ff(29,0),0.U(2.W)),
shortq_enable_ff -> ar_shifted(31,0)
))
val b_in = Mux1H(Seq (
!b_twos_comp -> Cat(io.signed_in & io.divisor_in(31),io.divisor_in(31,0)),
b_twos_comp -> Cat(!divisor_sign_ff,twos_comp_out(31,0))
))
val r_in = Mux1H (Seq(
r_sign_sel -> "hffffffff".U(32.W),
r_restore_sel -> Cat(r_ff(29,0),a_ff(31,30)),
r_adder1_sel -> adder1_out(31,0),
r_adder2_sel -> adder2_out(31,0),
r_adder3_sel -> adder3_out(31,0),
shortq_enable_ff -> ar_shifted(63,32),
by_zero_case -> a_ff
))
val q_in = Mux1H (Seq(
!valid_ff -> Cat(q_ff(29,0),quotient_new),
smallnum_case -> Cat(0.U(28.W),smallnum),
by_zero_case -> Fill(32,1.U)
))
io.valid_out := finish_ff & !io.cancel
io.data_out := Mux1H(Seq(
(!rem_ff & !twos_comp_q_sel).asBool() -> q_ff,
rem_ff -> r_ff,
twos_comp_q_sel -> twos_comp_out
))
def pat1(x : List[Int], y : List[Int]) = {
val pat_a = (0 until x.size).map(i=> if(x(i)>=0) a_ff(x(i)) else !a_ff(x(i).abs)).reduce(_&_)
val pat_b = (0 until y.size).map(i=> if(y(i)>=0) b_ff(y(i)) else !b_ff(y(i).abs)).reduce(_&_)
pat_a & pat_b
}
smallnum := Cat(
pat1(List(3),List(-3, -2, -1)),
pat1(List(3),List(-3, -2))& !b_ff(0) | pat1(List(2),List(-3, -2, -1)) | pat1(List(3, 2),List(-3, -2)),
pat1(List(2),List(-3, -2))& !b_ff(0) | pat1(List(1),List(-3, -2, -1)) | pat1(List(3),List(-3, -1))& !b_ff(0) |
pat1(List(3, -2),List(-3, -2, 1, 0)) | pat1(List(-3, 2, 1),List(-3, -2)) | pat1(List(3, 2),List(-3))& !b_ff(0) |
pat1(List(3, 2),List(-3, 2, -1)) | pat1(List(3, 1),List(-3,-1)) | pat1(List(3, 2, 1),List(-3, 2)),
pat1(List(2, 1, 0),List(-3, -1)) | pat1(List(3, -2, 0),List(-3, 1, 0)) | pat1(List(2),List(-3, -1))& !b_ff(0) |
pat1(List(1),List(-3, -2))& !b_ff(0) | pat1(List(0),List(-3, -2, -1)) | pat1(List(-3, 2, -1),List(-3, -2, 1, 0)) |
pat1(List(-3, 2, 1),List(-3))& !b_ff(0) | pat1(List(3),List(-2, -1)) & !b_ff(0) | pat1(List(3, -2),List(-3, 2, 1)) |
pat1(List(-3, 2, 1),List(-3, 2, -1)) | pat1(List(-3, 2, 0),List(-3, -1)) | pat1(List(3, -2, -1),List(-3, 2, 0)) |
pat1(List(-2, 1, 0),List(-3, -2)) | pat1(List(3, 2),List(-1)) & !b_ff(0) | pat1(List(-3, 2, 1, 0),List(-3, 2)) |
pat1(List(3, 2),List(3, -2)) | pat1(List(3, 1),List(3,-2,-1)) | pat1(List(3, 0),List(-2, -1)) |
pat1(List(3, -1),List(-3, 2, 1, 0)) | pat1(List(3, 2, 1),List(3)) & !b_ff(0) | pat1(List(3, 2, 1),List(3, -1)) |
pat1(List(3, 2, 0),List(3, -1)) | pat1(List(3, -2, 1),List(-3, 1)) | pat1(List(3, 1, 0),List(-2)) |
pat1(List(3, 2, 1, 0),List(3)) |pat1(List(3, 1),List(-2)) & !b_ff(0))
val shortq_dividend = Cat(dividend_sign_ff,a_ff)
val a_enc = Module(new exu_div_cls)
a_enc.io.operand := shortq_dividend
val dw_a_enc1 = a_enc.io.cls
val b_enc = Module(new exu_div_cls)
b_enc.io.operand := b_ff(32,0)
val dw_b_enc1 = b_enc.io.cls
val dw_a_enc = Cat (0.U, dw_a_enc1)
val dw_b_enc = Cat (0.U, dw_b_enc1)
val dw_shortq_raw = Cat(0.U,dw_b_enc) - Cat(0.U,dw_a_enc) + 1.U(7.W)
val shortq = Mux(dw_shortq_raw(6).asBool(),0.U,dw_shortq_raw(5,0))
shortq_enable := valid_ff & !shortq(5) & !(shortq(4,1) === "b1111".U) & !io.cancel
val shortq_shift = Mux(!shortq_enable,0.U,("b11111".U - shortq(4,0)))
b_ff := Cat(b_ff1(32),b_ff1(32),b_ff1)
valid_ff := rvdffe(valid_ff_in, misc_enable,clock,io.scan_mode)
control_ff := rvdffe(control_in, misc_enable,clock,io.scan_mode)
by_zero_case_ff := rvdffe(by_zero_case,misc_enable,clock,io.scan_mode)
shortq_enable_ff := rvdffe(shortq_enable, misc_enable,clock,io.scan_mode)
shortq_shift_ff := Cat(rvdffe(shortq_shift(4,1), misc_enable,clock,io.scan_mode),0.U)
finish_ff := rvdffe(finish, misc_enable,clock,io.scan_mode)
count_ff := rvdffe(count_in, misc_enable,clock,io.scan_mode)
a_ff := rvdffe(a_in, a_enable,clock,io.scan_mode)
b_ff1 := rvdffe(b_in(32,0), b_enable,clock,io.scan_mode)
r_ff := rvdffe(r_in, rq_enable,clock,io.scan_mode)
q_ff := rvdffe(q_in, rq_enable,clock,io.scan_mode)
}
/////////////////////////////////////////////// 3 BIT FULL DIVIDER//////////////////////////////////
class exu_div_new_3bit_fullshortq extends Module with RequireAsyncReset with lib {
val io = IO(new Bundle{
val scan_mode = Input(Bool())
val cancel = Input(Bool())
val valid_in = Input(Bool())
val signed_in = Input(Bool())
val rem_in = Input(Bool())
val dividend_in = Input(UInt(32.W))
val divisor_in = Input(UInt(32.W))
val data_out = Output(UInt(32.W))
val valid_out = Output(UInt(1.W))
})
val valid_ff = WireInit(Bool(),init=false.B)
val finish_ff = WireInit(Bool(),init=false.B)
val control_ff = WireInit(0.U(3.W))
val count_ff = WireInit(0.U(7.W))
val smallnum = WireInit(0.U(4.W))
val a_ff = WireInit(0.U(33.W))
val b_ff1 = WireInit(0.U(33.W))
val b_ff = WireInit(0.U(37.W))
val q_ff = WireInit(0.U(32.W))
val r_ff = WireInit(0.U(33.W))
val quotient_raw = WireInit(0.U(8.W))
val quotient_new = WireInit(0.U(3.W))
val shortq_enable = WireInit(Bool(),init=false.B)
val shortq_enable_ff = WireInit(Bool(),init=false.B)
val by_zero_case_ff = WireInit(Bool(),init=false.B)
val ar_shifted = WireInit(0.U(66.W))
val shortq_shift = WireInit(0.U(5.W))
val shortq_decode = WireInit(0.U(5.W))
val shortq_shift_ff = WireInit(0.U(5.W))
val valid_ff_in = io.valid_in & !io.cancel
val control_in = Cat((!io.valid_in & control_ff(2)) | (io.valid_in & io.signed_in & io.dividend_in(31)), (!io.valid_in & control_ff(1)) | (io.valid_in & io.signed_in & io.divisor_in(31)), (!io.valid_in & control_ff(0)) | (io.valid_in & io.rem_in))
val dividend_sign_ff = control_ff(2)
val divisor_sign_ff = control_ff(1)
val rem_ff = control_ff(0)
val by_zero_case = valid_ff & (b_ff(31,0) === 0.U)
val smallnum_case = ((a_ff(31,4) === 0.U) & (b_ff(31,4) === 0.U) & !by_zero_case & !rem_ff & valid_ff & !io.cancel) |
((a_ff(31,0) === 0.U) & !by_zero_case & !rem_ff & valid_ff & !io.cancel)
val running_state = count_ff.orR() | shortq_enable_ff
val misc_enable = io.valid_in | valid_ff | io.cancel | running_state | finish_ff
val finish_raw = smallnum_case | by_zero_case | (count_ff === 33.U)
val finish = finish_raw & !io.cancel
val count_enable = (valid_ff | running_state) & !finish & !finish_ff & !io.cancel & !shortq_enable
val count_in = Fill(7,count_enable) & (count_ff + Cat(0.U(5.W),3.U(2.W)) + Cat(0.U(2.W),shortq_shift_ff))
val a_enable = io.valid_in | running_state
val a_shift = running_state & !shortq_enable_ff
ar_shifted := Cat (Fill(33,dividend_sign_ff),a_ff) << shortq_shift_ff(4,0)
val b_twos_comp = valid_ff & !(dividend_sign_ff ^ divisor_sign_ff)
val twos_comp_b_sel = valid_ff & !(dividend_sign_ff ^ divisor_sign_ff)
val twos_comp_q_sel = !valid_ff & !rem_ff & (dividend_sign_ff ^ divisor_sign_ff) & !by_zero_case_ff
val b_enable = io.valid_in | b_twos_comp
val rq_enable = io.valid_in | valid_ff | running_state
val r_sign_sel = valid_ff & dividend_sign_ff & !by_zero_case
val r_adder_sel = (0 to 7 ).map(i=> (running_state & (quotient_new === i.asUInt) & !shortq_enable_ff))
val adder1_out = Cat(r_ff(30,0),a_ff(32,30)) + b_ff(33,0)
val adder2_out = Cat(r_ff(31,0),a_ff(32,30)) + Cat(b_ff(33,0),0.U)
val adder3_out = Cat(r_ff(32,0),a_ff(32,30)) + Cat(b_ff(34,0),0.U) + b_ff(35,0)
val adder4_out = Cat(r_ff(32),r_ff(32,0),a_ff(32,30)) + Cat(b_ff(34,0),0.U(2.W))
val adder5_out = Cat(r_ff(32),r_ff(32,0),a_ff(32,30)) + Cat(b_ff(34,0),0.U(2.W)) + b_ff
val adder6_out = Cat(r_ff(32),r_ff(32,0),a_ff(32,30)) + Cat(b_ff(34,0),0.U(2.W)) + Cat(b_ff(35,0),0.U)
val adder7_out = Cat(r_ff(32),r_ff(32,0),a_ff(32,30)) + Cat(b_ff(34,0),0.U(2.W)) + Cat(b_ff(35,0),0.U) + b_ff
quotient_raw := Cat((!adder7_out(36) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder7_out === 0.U)),
(!adder6_out(36) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder6_out === 0.U)),
(!adder5_out(36) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder5_out === 0.U)),
(!adder4_out(36) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder4_out === 0.U)),
(!adder3_out(35) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder3_out === 0.U)),
(!adder2_out(34) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder2_out === 0.U)),
(!adder1_out(33) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder1_out === 0.U)), 0.U)
quotient_new := Cat ((quotient_raw(7) | quotient_raw(6) | quotient_raw(5) | quotient_raw(4)),
(quotient_raw(7) | quotient_raw(6) |(!quotient_raw(4) & quotient_raw(3)) |(!quotient_raw(3) & quotient_raw(2))),
(quotient_raw(7) | (!quotient_raw(6) & quotient_raw(5)) | (!quotient_raw(4) & quotient_raw(3)) |(!quotient_raw(2) & quotient_raw(1))))
val twos_comp_in = Mux1H(Seq (
twos_comp_q_sel -> q_ff,
twos_comp_b_sel -> b_ff(31,0)
))
val twos_comp_out = rvtwoscomp(twos_comp_in)
val a_in = Mux1H(Seq (
(!a_shift & !shortq_enable_ff).asBool -> Cat(io.signed_in & io.dividend_in(31),io.dividend_in(31,0)),
a_shift -> Cat(a_ff(29,0),0.U(3.W)),
shortq_enable_ff -> ar_shifted(32,0)
))
val b_in = Mux1H(Seq (
!b_twos_comp -> Cat(io.signed_in & io.divisor_in(31),io.divisor_in(31,0)),
b_twos_comp -> Cat(!divisor_sign_ff,twos_comp_out(31,0))
))
val r_in = Mux1H (Seq(
r_sign_sel -> Fill(33,1.U),
r_adder_sel(0) -> Cat(r_ff(29,0),a_ff(32,30)),
r_adder_sel(1) -> adder1_out(32,0),
r_adder_sel(2) -> adder2_out(32,0),
r_adder_sel(3) -> adder3_out(32,0),
r_adder_sel(4) -> adder4_out(32,0),
r_adder_sel(5) -> adder5_out(32,0),
r_adder_sel(6) -> adder6_out(32,0),
r_adder_sel(7) -> adder7_out(32,0),
shortq_enable_ff -> ar_shifted(65,33),
by_zero_case -> Cat(0.U,a_ff(31,0))
))
val q_in = Mux1H (Seq(
!valid_ff -> Cat(q_ff(28,0),quotient_new),
smallnum_case -> Cat(0.U(28.W),smallnum),
by_zero_case -> Fill(32,1.U)
))
io.valid_out := finish_ff & !io.cancel
io.data_out := Mux1H(Seq(
(!rem_ff & !twos_comp_q_sel).asBool() -> q_ff,
rem_ff -> r_ff(31,0),
twos_comp_q_sel -> twos_comp_out
))
def pat1(x : List[Int], y : List[Int]) = {
val pat_a = (0 until x.size).map(i=> if(x(i)>=0) a_ff(x(i)) else !a_ff(x(i).abs)).reduce(_&_)
val pat_b = (0 until y.size).map(i=> if(y(i)>=0) b_ff(y(i)) else !b_ff(y(i).abs)).reduce(_&_)
pat_a & pat_b
}
smallnum := Cat(
pat1(List(3),List(-3, -2, -1)),
pat1(List(3),List(-3, -2))& !b_ff(0) | pat1(List(2),List(-3, -2, -1)) | pat1(List(3, 2),List(-3, -2)),
pat1(List(2),List(-3, -2))& !b_ff(0) | pat1(List(1),List(-3, -2, -1)) | pat1(List(3),List(-3, -1))& !b_ff(0) |
pat1(List(3, -2),List(-3, -2, 1, 0)) | pat1(List(-3, 2, 1),List(-3, -2)) | pat1(List(3, 2),List(-3))& !b_ff(0) |
pat1(List(3, 2),List(-3, 2, -1)) | pat1(List(3, 1),List(-3,-1)) | pat1(List(3, 2, 1),List(-3, 2)),
pat1(List(2, 1, 0),List(-3, -1)) | pat1(List(3, -2, 0),List(-3, 1, 0)) | pat1(List(2),List(-3, -1))& !b_ff(0) |
pat1(List(1),List(-3, -2))& !b_ff(0) | pat1(List(0),List(-3, -2, -1)) | pat1(List(-3, 2, -1),List(-3, -2, 1, 0)) |
pat1(List(-3, 2, 1),List(-3))& !b_ff(0) | pat1(List(3),List(-2, -1)) & !b_ff(0) | pat1(List(3, -2),List(-3, 2, 1)) |
pat1(List(-3, 2, 1),List(-3, 2, -1)) | pat1(List(-3, 2, 0),List(-3, -1)) | pat1(List(3, -2, -1),List(-3, 2, 0)) |
pat1(List(-2, 1, 0),List(-3, -2)) | pat1(List(3, 2),List(-1)) & !b_ff(0) | pat1(List(-3, 2, 1, 0),List(-3, 2)) |
pat1(List(3, 2),List(3, -2)) | pat1(List(3, 1),List(3,-2,-1)) | pat1(List(3, 0),List(-2, -1)) |
pat1(List(3, -1),List(-3, 2, 1, 0)) | pat1(List(3, 2, 1),List(3)) & !b_ff(0) | pat1(List(3, 2, 1),List(3, -1)) |
pat1(List(3, 2, 0),List(3, -1)) | pat1(List(3, -2, 1),List(-3, 1)) | pat1(List(3, 1, 0),List(-2)) |
pat1(List(3, 2, 1, 0),List(3)) |pat1(List(3, 1),List(-2)) & !b_ff(0))
val shortq_dividend = Cat(dividend_sign_ff,a_ff(31,0))
val a_enc = Module(new exu_div_cls)
a_enc.io.operand := shortq_dividend
val dw_a_enc1 = a_enc.io.cls
val b_enc = Module(new exu_div_cls)
b_enc.io.operand := b_ff(32,0)
val dw_b_enc1 = b_enc.io.cls
val dw_a_enc = Cat (0.U, dw_a_enc1)
val dw_b_enc = Cat (0.U, dw_b_enc1)
val dw_shortq_raw = Cat(0.U,dw_b_enc) - Cat(0.U,dw_a_enc) + 1.U(7.W)
val shortq = Mux(dw_shortq_raw(6).asBool(),0.U,dw_shortq_raw(5,0))
shortq_enable := valid_ff & !shortq(5) & !(shortq(4,2) === "b111".U) & !io.cancel
val list = Array(27,27,27,27,27,27,24,24,24,21,21,21,18,18,18,15,15,15,12,12,12,9,9,9,6,6,6,3,0,0,0,0)
shortq_decode := Mux1H((31 to 0 by -1).map(i=> (shortq === i.U) -> list(i).U))
shortq_shift := Mux(!shortq_enable,0.U,shortq_decode)
b_ff := Cat(b_ff1(32),b_ff1(32),b_ff1(32),b_ff1(32),b_ff1)
valid_ff := rvdffe(valid_ff_in, misc_enable,clock,io.scan_mode)
control_ff := rvdffe(control_in, misc_enable,clock,io.scan_mode)
by_zero_case_ff := rvdffe(by_zero_case,misc_enable,clock,io.scan_mode)
shortq_enable_ff := rvdffe(shortq_enable, misc_enable,clock,io.scan_mode)
shortq_shift_ff := rvdffe(shortq_shift, misc_enable,clock,io.scan_mode)
finish_ff := rvdffe(finish, misc_enable,clock,io.scan_mode)
count_ff := rvdffe(count_in, misc_enable,clock,io.scan_mode)
a_ff := rvdffe(a_in, a_enable,clock,io.scan_mode)
b_ff1 := rvdffe(b_in(32,0), b_enable,clock,io.scan_mode)
r_ff := rvdffe(r_in, rq_enable,clock,io.scan_mode)
q_ff := rvdffe(q_in, rq_enable,clock,io.scan_mode)
}
/////////////////////////////////////////////// 4 BIT FULL DIVIDER//////////////////////////////////
class exu_div_new_4bit_fullshortq extends Module with RequireAsyncReset with lib {
val io = IO(new Bundle {
val scan_mode = Input(Bool())
val cancel = Input(Bool())
val valid_in = Input(Bool())
val signed_in = Input(Bool())
val rem_in = Input(Bool())
val dividend_in = Input(UInt(32.W))
val divisor_in = Input(UInt(32.W))
val data_out = Output(UInt(32.W))
val valid_out = Output(UInt(1.W))
})
val valid_ff = WireInit(Bool(),init=false.B)
val finish_ff = WireInit(Bool(),init=false.B)
val control_ff = WireInit(0.U(3.W))
val count_ff = WireInit(0.U(7.W))
val smallnum = WireInit(0.U(4.W))
val a_ff = WireInit(0.U(32.W))
val b_ff1 = WireInit(0.U(33.W))
val b_ff = WireInit(0.U(38.W))
val q_ff = WireInit(0.U(32.W))
val r_ff = WireInit(0.U(33.W))
val quotient_raw = WireInit(0.U(16.W))
val quotient_new = WireInit(0.U(4.W))
val shortq_enable = WireInit(Bool(),init=false.B)
val shortq_enable_ff = WireInit(Bool(),init=false.B)
val by_zero_case_ff = WireInit(Bool(),init=false.B)
val ar_shifted = WireInit(0.U(65.W))
val shortq_shift = WireInit(0.U(5.W))
val shortq_decode = WireInit(0.U(5.W))
val shortq_shift_ff = WireInit(0.U(5.W))
val valid_ff_in = io.valid_in & !io.cancel
val control_in = Cat((!io.valid_in & control_ff(2)) | (io.valid_in & io.signed_in & io.dividend_in(31)), (!io.valid_in & control_ff(1)) | (io.valid_in & io.signed_in & io.divisor_in(31)), (!io.valid_in & control_ff(0)) | (io.valid_in & io.rem_in))
val dividend_sign_ff = control_ff(2)
val divisor_sign_ff = control_ff(1)
val rem_ff = control_ff(0)
val by_zero_case = valid_ff & (b_ff(31,0) === 0.U)
val smallnum_case = ((a_ff(31,4) === 0.U) & (b_ff(31,4) === 0.U) & !by_zero_case & !rem_ff & valid_ff & !io.cancel) |
((a_ff(31,0) === 0.U) & !by_zero_case & !rem_ff & valid_ff & !io.cancel)
val running_state = count_ff.orR() | shortq_enable_ff
val misc_enable = io.valid_in | valid_ff | io.cancel | running_state | finish_ff
val finish_raw = smallnum_case | by_zero_case | (count_ff === 32.U)
val finish = finish_raw & !io.cancel
val count_enable = (valid_ff | running_state) & !finish & !finish_ff & !io.cancel & !shortq_enable
val count_in = Fill(7,count_enable) & (count_ff + 4.U(7.W) + Cat(0.U(2.W),shortq_shift_ff))
val a_enable = io.valid_in | running_state
val a_shift = running_state & !shortq_enable_ff
ar_shifted := Cat (Fill(33,dividend_sign_ff),a_ff(31,0)) << shortq_shift_ff
val b_twos_comp = valid_ff & !(dividend_sign_ff ^ divisor_sign_ff)
val twos_comp_b_sel = valid_ff & !(dividend_sign_ff ^ divisor_sign_ff)
val twos_comp_q_sel = !valid_ff & !rem_ff & (dividend_sign_ff ^ divisor_sign_ff) & !by_zero_case_ff
val b_enable = io.valid_in | b_twos_comp
val rq_enable = io.valid_in | valid_ff | running_state
val r_sign_sel = valid_ff & dividend_sign_ff & !by_zero_case
val r_adder_sel = (0 to 15 ).map(i=> (running_state & (quotient_new === i.asUInt) & !shortq_enable_ff))
val adder1_out = Cat(r_ff(30,0),a_ff(31,28)) + b_ff(34,0)
val adder2_out = Cat(r_ff(31,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U)
val adder3_out = Cat(r_ff(32,0),a_ff(31,28)) + Cat(b_ff(35,0),0.U) + b_ff(36,0)
val adder4_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(35,0),0.U(2.W))
val adder5_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(35,0),0.U(2.W)) + b_ff
val adder6_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(35,0),0.U(2.W)) + Cat(b_ff(36,0),0.U)
val adder7_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(35,0),0.U(2.W)) + Cat(b_ff(36,0),0.U) + b_ff
val adder8_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U(3.W))
val adder9_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U(3.W)) + b_ff
val adder10_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U(3.W)) + Cat(b_ff(36,0),0.U)
val adder11_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U(3.W)) + Cat(b_ff(36,0),0.U) + b_ff
val adder12_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U(3.W)) + Cat(b_ff(35,0),0.U(2.W))
val adder13_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U(3.W)) + Cat(b_ff(35,0),0.U(2.W)) + b_ff
val adder14_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U(3.W)) + Cat(b_ff(35,0),0.U(2.W)) + Cat(b_ff(36,0),0.U)
val adder15_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U(3.W)) + Cat(b_ff(35,0),0.U(2.W)) + Cat(b_ff(36,0),0.U) + b_ff
quotient_raw := Cat(
(!adder15_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder15_out === 0.U)),
(!adder14_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder14_out === 0.U)),
(!adder13_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder13_out === 0.U)),
(!adder12_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder12_out === 0.U)),
(!adder11_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder11_out === 0.U)),
(!adder10_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder10_out === 0.U)),
(!adder9_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder9_out === 0.U)),
(!adder8_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder8_out === 0.U)),
(!adder7_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder7_out === 0.U)),
(!adder6_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder6_out === 0.U)),
(!adder5_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder5_out === 0.U)),
(!adder4_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder4_out === 0.U)),
(!adder3_out(36) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder3_out === 0.U)),
(!adder2_out(35) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder2_out === 0.U)),
(!adder1_out(34) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder1_out === 0.U)), 0.U)
quotient_new := Cat(
(Mux1H((8 to 14).map(i=> (quotient_raw(15,i)=== Cat(Fill(15-i,0.U),1.U)).asBool -> 1.U)) | (quotient_raw(15)===1.U)),
Mux1H (Seq(( quotient_raw(15,4) === "b000000000001".U(12.W)) -> 1.U, ( quotient_raw(15,5) === "b00000000001".U(11.W)) -> 1.U, ( quotient_raw(15,6) === "b0000000001".U(10.W)) -> 1.U, ( quotient_raw(15,7) === "b000000001".U(9.W)) -> 1.U,
( quotient_raw(15,12)=== "b0001".U(4.W)) -> 1.U, ( quotient_raw(15,13)=== "b001".U(3.W)) -> 1.U, ( quotient_raw(15,14)=== "b01".U(2.W)) -> 1.U, ( quotient_raw(15) === "b1".U) -> 1.U)),
Mux1H(Seq(( quotient_raw(15,2) === "b00000000000001".U(14.W)) -> 1.U, ( quotient_raw(15,3) === "b0000000000001".U(13.W)) -> 1.U, ( quotient_raw(15,6) === "b0000000001".U(10.W)) -> 1.U, ( quotient_raw(15,7) === "b000000001".U(9.W)) -> 1.U,
( quotient_raw(15,10)=== "b000001".U(6.W)) -> 1.U, ( quotient_raw(15,11)=== "b00001".U(5.W)) -> 1.U, ( quotient_raw(15,14)=== "b01".U(2.W)) -> 1.U, ( quotient_raw(15) === "b1".U) -> 1.U)),
(Mux1H((1 to 13 by 2).map(i=> (quotient_raw(15,i)=== Cat(Fill(15-i,0.U),1.U)).asBool -> 1.U)) | (quotient_raw(15)===1.U) ))
val twos_comp_in = Mux1H(Seq (
twos_comp_q_sel -> q_ff,
twos_comp_b_sel -> b_ff(31,0)
))
val twos_comp_out = rvtwoscomp(twos_comp_in)
val a_in = Mux1H(Seq (
(!a_shift & !shortq_enable_ff).asBool -> io.dividend_in(31,0),
a_shift -> Cat(a_ff(27,0),0.U(4.W)),
shortq_enable_ff -> ar_shifted(31,0)
))
val b_in = Mux1H(Seq (
!b_twos_comp -> Cat(io.signed_in & io.divisor_in(31),io.divisor_in(31,0)),
b_twos_comp -> Cat(!divisor_sign_ff,twos_comp_out(31,0))
))
val r_in = Mux1H (Seq(
r_sign_sel -> Fill(33,1.U),
r_adder_sel(0) -> Cat(r_ff(28,0),a_ff(31,28)),
r_adder_sel(1) -> adder1_out(32,0),
r_adder_sel(2) -> adder2_out(32,0),
r_adder_sel(3) -> adder3_out(32,0),
r_adder_sel(4) -> adder4_out(32,0),
r_adder_sel(5) -> adder5_out(32,0),
r_adder_sel(6) -> adder6_out(32,0),
r_adder_sel(7) -> adder7_out(32,0),
r_adder_sel(8) -> adder8_out(32,0),
r_adder_sel(9) -> adder9_out(32,0),
r_adder_sel(10) -> adder10_out(32,0),
r_adder_sel(11) -> adder11_out(32,0),
r_adder_sel(12) -> adder12_out(32,0),
r_adder_sel(13) -> adder13_out(32,0),
r_adder_sel(14) -> adder14_out(32,0),
r_adder_sel(15) -> adder15_out(32,0),
shortq_enable_ff -> ar_shifted(64,32),
by_zero_case -> Cat(0.U,a_ff(31,0))
))
val q_in = Mux1H (Seq(
!valid_ff -> Cat(q_ff(27,0),quotient_new),
smallnum_case -> Cat(0.U(28.W),smallnum),
by_zero_case -> Fill(32,1.U)
))
io.valid_out := finish_ff & !io.cancel
io.data_out := Mux1H(Seq(
(!rem_ff & !twos_comp_q_sel).asBool() -> q_ff,
rem_ff -> r_ff(31,0),
twos_comp_q_sel -> twos_comp_out
))
def pat1(x : List[Int], y : List[Int]) = {
val pat_a = (0 until x.size).map(i=> if(x(i)>=0) a_ff(x(i)) else !a_ff(x(i).abs)).reduce(_&_)
val pat_b = (0 until y.size).map(i=> if(y(i)>=0) b_ff(y(i)) else !b_ff(y(i).abs)).reduce(_&_)
pat_a & pat_b
}
smallnum := Cat(
pat1(List(3),List(-3, -2, -1)),
pat1(List(3),List(-3, -2))& !b_ff(0) | pat1(List(2),List(-3, -2, -1)) | pat1(List(3, 2),List(-3, -2)),
pat1(List(2),List(-3, -2))& !b_ff(0) | pat1(List(1),List(-3, -2, -1)) | pat1(List(3),List(-3, -1))& !b_ff(0) |
pat1(List(3, -2),List(-3, -2, 1, 0)) | pat1(List(-3, 2, 1),List(-3, -2)) | pat1(List(3, 2),List(-3))& !b_ff(0) |
pat1(List(3, 2),List(-3, 2, -1)) | pat1(List(3, 1),List(-3,-1)) | pat1(List(3, 2, 1),List(-3, 2)),
pat1(List(2, 1, 0),List(-3, -1)) | pat1(List(3, -2, 0),List(-3, 1, 0)) | pat1(List(2),List(-3, -1))& !b_ff(0) |
pat1(List(1),List(-3, -2))& !b_ff(0) | pat1(List(0),List(-3, -2, -1)) | pat1(List(-3, 2, -1),List(-3, -2, 1, 0)) |
pat1(List(-3, 2, 1),List(-3))& !b_ff(0) | pat1(List(3),List(-2, -1)) & !b_ff(0) | pat1(List(3, -2),List(-3, 2, 1)) |
pat1(List(-3, 2, 1),List(-3, 2, -1)) | pat1(List(-3, 2, 0),List(-3, -1)) | pat1(List(3, -2, -1),List(-3, 2, 0)) |
pat1(List(-2, 1, 0),List(-3, -2)) | pat1(List(3, 2),List(-1)) & !b_ff(0) | pat1(List(-3, 2, 1, 0),List(-3, 2)) |
pat1(List(3, 2),List(3, -2)) | pat1(List(3, 1),List(3,-2,-1)) | pat1(List(3, 0),List(-2, -1)) |
pat1(List(3, -1),List(-3, 2, 1, 0)) | pat1(List(3, 2, 1),List(3)) & !b_ff(0) | pat1(List(3, 2, 1),List(3, -1)) |
pat1(List(3, 2, 0),List(3, -1)) | pat1(List(3, -2, 1),List(-3, 1)) | pat1(List(3, 1, 0),List(-2)) |
pat1(List(3, 2, 1, 0),List(3)) |pat1(List(3, 1),List(-2)) & !b_ff(0))
val shortq_dividend = Cat(dividend_sign_ff,a_ff(31,0))
val a_enc = Module(new exu_div_cls)
a_enc.io.operand := shortq_dividend
val dw_a_enc1 = a_enc.io.cls
val b_enc = Module(new exu_div_cls)
b_enc.io.operand := b_ff(32,0)
val dw_b_enc1 = b_enc.io.cls
val dw_a_enc = Cat (0.U, dw_a_enc1)
val dw_b_enc = Cat (0.U, dw_b_enc1)
val dw_shortq_raw = Cat(0.U,dw_b_enc) - Cat(0.U,dw_a_enc) + 1.U(7.W)
val shortq = Mux(dw_shortq_raw(6).asBool(),0.U,dw_shortq_raw(5,0))
shortq_enable := valid_ff & !shortq(5) & !(shortq(4,2) === "b111".U) & !io.cancel
val list = Array(28,28,28,28,24,24,24,24,20,20,20,20,16,16,16,16,12,12,12,12,8,8,8,8,4,4,4,4,0,0,0,0)
shortq_decode := Mux1H((31 to 0 by -1).map(i=> (shortq === i.U) -> list(i).U))
shortq_shift := Mux(!shortq_enable,0.U,shortq_decode)
b_ff := Cat(b_ff1(32),b_ff1(32),b_ff1(32),b_ff1(32),b_ff1(32),b_ff1)
valid_ff := rvdffe(valid_ff_in, misc_enable,clock,io.scan_mode)
control_ff := rvdffe(control_in, misc_enable,clock,io.scan_mode)
by_zero_case_ff := rvdffe(by_zero_case,misc_enable,clock,io.scan_mode)
shortq_enable_ff := rvdffe(shortq_enable, misc_enable,clock,io.scan_mode)
shortq_shift_ff := rvdffe(shortq_shift, misc_enable,clock,io.scan_mode)
finish_ff := rvdffe(finish, misc_enable,clock,io.scan_mode)
count_ff := rvdffe(count_in, misc_enable,clock,io.scan_mode)
a_ff := rvdffe(a_in, a_enable,clock,io.scan_mode)
b_ff1 := rvdffe(b_in(32,0), b_enable,clock,io.scan_mode)
r_ff := rvdffe(r_in, rq_enable,clock,io.scan_mode)
q_ff := rvdffe(q_in, rq_enable,clock,io.scan_mode)
}
class exu_div_cls extends Module{
val io= IO(new Bundle{
val operand = Input(UInt(33.W))
val cls = Output(UInt(5.W))
})
val cls_zeros = WireInit(0.U(5.W))
val cls_ones = WireInit(0.U(5.W))
cls_zeros := Mux1H((0 until 32).map(i=> (io.operand(31,31-i)===1.U)->i.U))
when(io.operand(31,0) === "hffffffff".U) { cls_ones := 31.U}
.otherwise{cls_ones := Mux1H((1 until 32).map(i=> (io.operand(31,31-i) === Cat(Fill(i,1.U),0.U)).asBool -> (i-1).U ))}
io.cls := Mux(io.operand(32),cls_ones,cls_zeros)
}
q_ff := rvdffe(q_in, qff_enable.asBool,clock,io.scan_mode)
a_ff := rvdffe(a_in, aff_enable.asBool,clock,io.scan_mode)
m_ff := rvdffe(Cat(!io.dec_div.div_p.bits.unsign & io.divisor(31), io.divisor), io.dec_div.div_p.valid.asBool,clock,io.scan_mode)
}

View File

@ -4,7 +4,7 @@ import chisel3._
import chisel3.util._
import include._
import lib._
import chisel3.stage.ChiselStage
class exu_mul_ctl extends Module with RequireAsyncReset with lib {
val io = IO(new Bundle{
@ -22,104 +22,7 @@ class exu_mul_ctl extends Module with RequireAsyncReset with lib {
val prod_x = WireInit(SInt(66.W), 0.S)
val low_x = WireInit(0.U(1.W))
// *** Start - BitManip ***
// val bitmanip_sel_d = WireInit(Bool(),0.B)
// val bitmanip_sel_x = WireInit(Bool(),0.B)
// val bitmanip_d = WireInit(UInt(32.W),0.U)
// val bitmanip_x = WireInit(UInt(32.W),0.U)
// ZBE
val ap_bext = WireInit(Bool(),0.B)
val ap_bdep = WireInit(Bool(),0.B)
// ZBC
val ap_clmul = WireInit(Bool(),0.B)
val ap_clmulh = WireInit(Bool(),0.B)
val ap_clmulr = WireInit(Bool(),0.B)
// ZBP
val ap_grev = WireInit(Bool(),0.B)
val ap_gorc = WireInit(Bool(),0.B)
val ap_shfl = WireInit(Bool(),0.B)
val ap_unshfl = WireInit(Bool(),0.B)
// ZBR
val ap_crc32_b = WireInit(Bool(),0.B)
val ap_crc32_h = WireInit(Bool(),0.B)
val ap_crc32_w = WireInit(Bool(),0.B)
val ap_crc32c_b = WireInit(Bool(),0.B)
val ap_crc32c_h = WireInit(Bool(),0.B)
val ap_crc32c_w = WireInit(Bool(),0.B)
// ZBF
val ap_bfp = WireInit(Bool(),0.B)
if (BITMANIP_ZBE == 1) {
ap_bext := io.mul_p.bits.bext
ap_bdep := io.mul_p.bits.bdep
}
else{
ap_bext := 0.U
ap_bdep := 0.U
}
if (BITMANIP_ZBC == 1) {
ap_clmul := io.mul_p.bits.clmul
ap_clmulh := io.mul_p.bits.clmulh
ap_clmulr := io.mul_p.bits.clmulr
}
else{
ap_clmul := 0.U
ap_clmulh := 0.U
ap_clmulr := 0.U
}
if (BITMANIP_ZBP == 1) {
ap_grev := io.mul_p.bits.grev
ap_gorc := io.mul_p.bits.gorc
ap_shfl := io.mul_p.bits.shfl
ap_unshfl := io.mul_p.bits.unshfl
}
else{
ap_grev := 0.U
ap_gorc := 0.U
ap_shfl := 0.U
ap_unshfl := 0.U
}
if (BITMANIP_ZBR == 1) {
ap_crc32_b := io.mul_p.bits.crc32_b
ap_crc32_h := io.mul_p.bits.crc32_h
ap_crc32_w := io.mul_p.bits.crc32_w
ap_crc32c_b := io.mul_p.bits.crc32c_b
ap_crc32c_h := io.mul_p.bits.crc32c_h
ap_crc32c_w := io.mul_p.bits.crc32c_w
}
else{
ap_crc32_b := 0.U
ap_crc32_h := 0.U
ap_crc32_w := 0.U
ap_crc32c_b := 0.U
ap_crc32c_h := 0.U
ap_crc32c_w := 0.U
}
if (BITMANIP_ZBF == 1) {
ap_bfp := io.mul_p.bits.bfp
}
else{
ap_bfp := 0.U
}
// *** End - BitManip ***
val mul_x_enable = io.mul_p.valid
val bit_x_enable = io.mul_p.valid
rs1_ext_in := Cat(io.mul_p.bits.rs1_sign & io.rs1_in(31),io.rs1_in).asSInt
rs2_ext_in := Cat(io.mul_p.bits.rs2_sign & io.rs2_in(31),io.rs2_in).asSInt
@ -128,269 +31,5 @@ class exu_mul_ctl extends Module with RequireAsyncReset with lib {
rs2_x := rvdffe (rs2_ext_in, mul_x_enable.asBool,clock,io.scan_mode)
prod_x := rs1_x * rs2_x
// * * * * * * * * * * * * * * * * * * BitManip : BEXT, BDEP * * * * * * * * * * * * * * * * * *
// *** BEXT == "gather" ***
def one_cal (ind:Int) : UInt = if (ind == 0) io.rs2_in(ind) else (0 to ind).map(io.rs2_in(_).asUInt).reduce(_+&_)
val bext_d = (0 until 32).map(i=> MuxCase(false.B, (0 until 32).map(j=> (one_cal(j) === (i+1).U).asBool -> io.rs1_in(j).asUInt))).reverse.reduce(Cat(_,_))
// *** BDEP == "scatter" ***
val bdep_d =(0 until 32).map(j => Mux((io.rs2_in(j) === 1.U), io.rs1_in(one_cal(j)-1.U),0.U)).reverse.reduce(Cat(_,_))
// * * * * * * * * * * * * * * * * * * BitManip : CLMUL, CLMULH, CLMULR * * * * * * * * * * * * *
val clmul_raw_d = WireInit(UInt(63.W),0.U)
clmul_raw_d := (1 until 31).map(i => Fill(63,io.rs2_in(i)) & Cat(Fill(31-i,0.U),io.rs1_in(31,0),Fill(i,0.U))).reduce(_^_) ^ ( Fill(63,io.rs2_in(0)) & Cat(Fill(31,0.U),io.rs1_in) ) ^ ( Fill(63,io.rs2_in(31)) & Cat(io.rs1_in,Fill(31,0.U)) )
// * * * * * * * * * * * * * * * * * * BitManip : GREV * * * * * * * * * * * * * * * * * *
// uint32_t grev32(uint32_t rs1, uint32_t rs2)
// {
// uint32_t x = rs1;
// int shamt = rs2 & 31;
//
// if (shamt & 1) x = ( (x & 0x55555555) << 1) | ( (x & 0xAAAAAAAA) >> 1);
// if (shamt & 2) x = ( (x & 0x33333333) << 2) | ( (x & 0xCCCCCCCC) >> 2);
// if (shamt & 4) x = ( (x & 0x0F0F0F0F) << 4) | ( (x & 0xF0F0F0F0) >> 4);
// if (shamt & 8) x = ( (x & 0x00FF00FF) << 8) | ( (x & 0xFF00FF00) >> 8);
// if (shamt & 16) x = ( (x & 0x0000FFFF) << 16) | ( (x & 0xFFFF0000) >> 16);
//
// return x;
// }
val grev1_d = Mux(io.rs2_in(0), Range(0, 31, 2).map(i=> Cat(io.rs1_in(i),io.rs1_in(i+1))).reverse.reduce(Cat(_,_)), io.rs1_in)
val grev2_d = Mux(io.rs2_in(1), Range(0, 31, 4).map(i=> Cat(grev1_d(i+1,i),grev1_d(i+1+2,i+2))).reverse.reduce(Cat(_,_)) , grev1_d(31,0))
val grev4_d = Mux(io.rs2_in(2), Range(0, 31, 8).map(i=> Cat(grev2_d(i+3,i),grev2_d(i+3+4,i+4))).reverse.reduce(Cat(_,_)) , grev2_d(31,0))
val grev8_d = Mux(io.rs2_in(3), Range(0, 31, 16).map(i=> Cat(grev4_d(i+7,i),grev4_d(i+7+8,i+8))).reverse.reduce(Cat(_,_)), grev4_d(31,0))
val grev_d = Mux(io.rs2_in(4), Cat(grev8_d(15,0),grev8_d(31,16)), grev8_d(31,0) )
// * * * * * * * * * * * * * * * * * * BitManip : GORC * * * * * * * * * * * * * * * * * *
// uint32_t gorc32(uint32_t rs1, uint32_t rs2)
// {
// uint32_t x = rs1;
// int shamt = rs2 & 31;
//
// if (shamt & 1) x |= ( (x & 0x55555555) << 1) | ( (x & 0xAAAAAAAA) >> 1);
// if (shamt & 2) x |= ( (x & 0x33333333) << 2) | ( (x & 0xCCCCCCCC) >> 2);
// if (shamt & 4) x |= ( (x & 0x0F0F0F0F) << 4) | ( (x & 0xF0F0F0F0) >> 4);
// if (shamt & 8) x |= ( (x & 0x00FF00FF) << 8) | ( (x & 0xFF00FF00) >> 8);
// if (shamt & 16) x |= ( (x & 0x0000FFFF) << 16) | ( (x & 0xFFFF0000) >> 16);
//
// return x;
// }
// logic [31:0] gorc1_d;
// logic [31:0] gorc2_d;
// logic [31:0] gorc4_d;
// logic [31:0] gorc8_d;
// logic [31:0] gorc_d;
//
val gorc1_d = ( Fill(32,io.rs2_in(0)) & Range(0, 31, 2).map(i=> Cat(io.rs1_in(i),io.rs1_in(i+1))).reverse.reduce(Cat(_,_)) ) | io.rs1_in
val gorc2_d = ( Fill(32,io.rs2_in(1)) & Range(0, 31, 4).map(i=> Cat(gorc1_d(i+1,i),gorc1_d(i+1+2,i+2))).reverse.reduce(Cat(_,_)) ) | gorc1_d
val gorc4_d = ( Fill(32,io.rs2_in(2)) & Range(0, 31, 8).map(i=> Cat(gorc2_d(i+3,i),gorc2_d(i+3+4,i+4))).reverse.reduce(Cat(_,_)) ) | gorc2_d
val gorc8_d = ( Fill(32,io.rs2_in(3)) & Range(0, 31, 16).map(i=> Cat(gorc4_d(i+7,i),gorc4_d(i+7+8,i+8))).reverse.reduce(Cat(_,_)) ) | gorc4_d
val gorc_d = ( Fill(32,io.rs2_in(4)) & Cat(gorc8_d(15,0),gorc8_d(31,16)) ) | gorc8_d
// * * * * * * * * * * * * * * * * * * BitManip : SHFL, UNSHLF * * * * * * * * * * * * * * * * * *
// uint32_t shuffle32_stage (uint32_t src, uint32_t maskL, uint32_t maskR, int N)
// {
// uint32_t x = src & ~(maskL | maskR);
// x |= ((src << N) & maskL) | ((src >> N) & maskR);
// return x;
// }
//
//
//
// uint32_t shfl32(uint32_t rs1, uint32_t rs2)
// {
// uint32_t x = rs1;
// int shamt = rs2 & 15
//
// if (shamt & 8) x = shuffle32_stage(x, 0x00ff0000, 0x0000ff00, 8);
// if (shamt & 4) x = shuffle32_stage(x, 0x0f000f00, 0x00f000f0, 4);
// if (shamt & 2) x = shuffle32_stage(x, 0x30303030, 0xc0c0c0c0, 2);
// if (shamt & 1) x = shuffle32_stage(x, 0x44444444, 0x22222222, 1);
//
// return x;
// }
val shfl8_d = Mux(io.rs2_in(3),Range(0, 9,8).map(i=> Cat(io.rs1_in(i+7+16,i+16),io.rs1_in(i+7,i))).reverse.reduce(Cat(_,_)) ,io.rs1_in)
val shfl4_d = Mux(io.rs2_in(2),Range(0, 13,4).map(i=> if(i<8) Cat(shfl8_d(i+3+8,i+8),shfl8_d(i+3,i))else Cat(shfl8_d(i+3+8+8,i+8+8),shfl8_d(i+3+8,i+8))).reverse.reduce(Cat(_,_)), shfl8_d)
val shfl2_d = Mux(io.rs2_in(1), Range(0, 15,2).map(i=> if(i<4)Cat(shfl4_d(i+1+4,i+4),shfl4_d(i+1,i))else if(i<8)Cat(shfl4_d(i+9,i+8),shfl4_d(i+5,i+4))else if(i<12)Cat(shfl4_d(i+13,i+12),shfl4_d(i+9,i+8))else Cat(shfl4_d(i+17,i+16),shfl4_d(i+13,i+12))).reverse.reduce(Cat(_,_)), shfl4_d)
val shfl_d = Mux(io.rs2_in(0), Range(0, 16,1).map(i=> if(i<2) Cat(shfl2_d(i+2),shfl2_d(i))else if(i<4) Cat(shfl2_d(i+4),shfl2_d(i+2))else if(i<6) Cat(shfl2_d(i+6),shfl2_d(i+4))else if(i<8) Cat(shfl2_d(i+8),shfl2_d(i+6))else if(i<10) Cat(shfl2_d(i+10),shfl2_d(i+8))else if(i<12) Cat(shfl2_d(i+12),shfl2_d(i+10))else if(i<14) Cat(shfl2_d(i+14),shfl2_d(i+12))else Cat(shfl2_d(i+16),shfl2_d(i+14))).reverse.reduce(Cat(_,_)), shfl2_d)
// // uint32_t unshfl32(uint32_t rs1, uint32_t rs2)
// // {
// // uint32_t x = rs1;
// // int shamt = rs2 & 15
// //
// // if (shamt & 1) x = shuffle32_stage(x, 0x44444444, 0x22222222, 1);
// // if (shamt & 2) x = shuffle32_stage(x, 0x30303030, 0xc0c0c0c0, 2);
// // if (shamt & 4) x = shuffle32_stage(x, 0x0f000f00, 0x00f000f0, 4);
// // if (shamt & 8) x = shuffle32_stage(x, 0x00ff0000, 0x0000ff00, 8);
// //
// // return x;
// // }
//
//
val unshfl1_d = Mux(io.rs2_in(0) , Range(0, 16,1).map(i=> if(i<2) Cat(io.rs1_in(i+2),io.rs1_in(i))else if(i<4) Cat(io.rs1_in(i+4),io.rs1_in(i+2))else if(i<6) Cat(io.rs1_in(i+6),io.rs1_in(i+4))else if(i<8) Cat(io.rs1_in(i+8),io.rs1_in(i+6))else if(i<10) Cat(io.rs1_in(i+10),io.rs1_in(i+8))else if(i<12) Cat(io.rs1_in(i+12),io.rs1_in(i+10))else if(i<14) Cat(io.rs1_in(i+14),io.rs1_in(i+12))else Cat(io.rs1_in(i+16),io.rs1_in(i+14))).reverse.reduce(Cat(_,_)) , io.rs1_in)
val unshfl2_d =Mux(io.rs2_in(1) , Range(0, 15,2).map(i=> if(i<4)Cat(unshfl1_d(i+1+4,i+4),unshfl1_d(i+1,i))else if(i<8)Cat(unshfl1_d(i+9,i+8),unshfl1_d(i+5,i+4))else if(i<12)Cat(unshfl1_d(i+13,i+12),unshfl1_d(i+9,i+8))else Cat(unshfl1_d(i+17,i+16),unshfl1_d(i+13,i+12))).reverse.reduce(Cat(_,_)) , unshfl1_d)
val unshfl4_d = Mux(io.rs2_in(2) , Range(0, 13,4).map(i=> if(i<8) Cat(unshfl2_d(i+3+8,i+8),unshfl2_d(i+3,i))else Cat(unshfl2_d(i+3+8+8,i+8+8),unshfl2_d(i+3+8,i+8))).reverse.reduce(Cat(_,_)) , unshfl2_d)
val unshfl_d = Mux(io.rs2_in(3) , Range(0, 9,8).map(i=> Cat(unshfl4_d(i+7+16,i+16),unshfl4_d(i+7,i))).reverse.reduce(Cat(_,_)) , unshfl4_d)
// * * * * * * * * * * * * * * * * * * BitManip : BFP * * * * * * * * * * * * * * * * * *
val bfp_len = Cat(io.rs2_in(27,24) === 0.U,io.rs2_in(27,24)) // If LEN field is zero, then LEN=16
val bfp_off = io.rs2_in(20,16)
val bfp_len_mask_ = "hffff_ffff".U(32.W) << bfp_len
val bfp_preshift_data = io.rs2_in(15,0) & ~bfp_len_mask_(15,0)
val bfp_shift_data = Cat(Fill(16,0.U),bfp_preshift_data(15,0), Fill(16,0.U),bfp_preshift_data(15,0)) << bfp_off
val bfp_shift_mask = Cat(bfp_len_mask_(31,0), bfp_len_mask_(31,0)) << bfp_off
val bfp_result_d = bfp_shift_data(63,32) | (io.rs1_in & bfp_shift_mask(63,32))
// * * * * * * * * * * * * * * * * * * BitManip : CRC32, CRC32c * * * * * * * * * * * * * * * * *
// *** computed from https: //crccalc.com ***
//
// "a" is 8'h61 = 8'b0110_0001 (8'h61 ^ 8'hff = 8'h9e)
//
// Input must first be XORed with 32'hffff_ffff
//
//
// CRC32
//
// Input Output Input Output
// ----- -------- -------- --------
// "a" e8b7be43 ffffff9e 174841bc
// "aa" 078a19d7 ffff9e9e f875e628
// "aaaa" ad98e545 9e9e9e9e 5267a1ba
//
//
//
// CRC32c
//
// Input Output Input Output
// ----- -------- -------- --------
// "a" c1d04330 ffffff9e 3e2fbccf
// "aa" f1f2dac2 ffff9e9e 0e0d253d
// "aaaa" 6a52eeb0 9e9e9e9e 95ad114f
val crc32_all = ap_crc32_b | ap_crc32_h | ap_crc32_w | ap_crc32c_b | ap_crc32c_h | ap_crc32c_w
val crc32_poly_rev = "hEDB88320".U(32.W) // bit reverse of 32'h04C11DB7
val crc32c_poly_rev = "h82F63B78".U(32.W) // bit reverse of 32'h1EDC6F41
val crc32_bd = Wire(Vec(9,UInt(32.W)))
crc32_bd(0) := io.rs1_in
for(i <- 1 to 8) {
crc32_bd(i) := (crc32_bd(i-1) >> 1) ^ (crc32_poly_rev & Fill(32,crc32_bd(i-1)(0)))//io.rs1_in
}
val crc32_hd = Wire(Vec(17,UInt(32.W)))
crc32_hd(0) := io.rs1_in
for(i <- 1 to 16) {
crc32_hd(i) := (crc32_hd(i-1) >> 1) ^ (crc32_poly_rev & Fill(32,crc32_hd(i-1)(0)))//io.rs1_in
}
val crc32_wd = Wire(Vec(33,UInt(32.W)))
crc32_wd(0) := io.rs1_in
for(i <- 1 to 32) {
crc32_wd(i) := (crc32_wd(i-1) >> 1) ^ (crc32_poly_rev & Fill(32,crc32_wd(i-1)(0)))//io.rs1_in
}
/////////////////////////////////////////////////////////////////////////////////////////
val crc32c_bd = Wire(Vec(9,UInt(32.W)))
crc32c_bd(0) := io.rs1_in
for(i <- 1 to 8) {
crc32c_bd(i) := (crc32c_bd(i-1) >> 1) ^ (crc32c_poly_rev & Fill(32,crc32c_bd(i-1)(0)))//io.rs1_in
}
val crc32c_hd = Wire(Vec(17,UInt(32.W)))
crc32c_hd(0) := io.rs1_in
for(i <- 1 to 16) {
crc32c_hd(i) := (crc32c_hd(i-1) >> 1) ^ (crc32c_poly_rev & Fill(32,crc32c_hd(i-1)(0)))//io.rs1_in
}
val crc32c_wd = Wire(Vec(33,UInt(32.W)))
crc32c_wd(0) := io.rs1_in
for(i <- 1 to 32) {
crc32c_wd(i) := (crc32c_wd(i-1) >> 1) ^ (crc32c_poly_rev & Fill(32,crc32c_wd(i-1)(0)))//io.rs1_in
}
// * * * * * * * * * * * * * * * * * * BitManip : Common logic * * * * * * * * * * * * * * * * * *
val bitmanip_sel_d = ap_bext | ap_bdep | ap_clmul | ap_clmulh | ap_clmulr | ap_grev | ap_gorc | ap_shfl | ap_unshfl | crc32_all | ap_bfp
val bitmanip_d = Mux1H(Seq(
ap_bext -> bext_d(31,0) ,
ap_bdep -> bdep_d(31,0) ,
ap_clmul -> clmul_raw_d(31,0) ,
ap_clmulh -> Cat(0.U(1.W),clmul_raw_d(62,32)) ,
ap_clmulr -> clmul_raw_d(62,31) ,
ap_grev -> grev_d(31,0) ,
ap_gorc -> gorc_d(31,0) ,
ap_shfl -> shfl_d(31,0) ,
ap_unshfl -> unshfl_d(31,0) ,
ap_crc32_b -> crc32_bd(8)(31,0) ,
ap_crc32_h -> crc32_hd(16)(31,0) ,
ap_crc32_w -> crc32_wd(32)(31,0) ,
ap_crc32c_b -> crc32c_bd(8)(31,0) ,
ap_crc32c_h -> crc32c_hd(16)(31,0) ,
ap_crc32c_w -> crc32c_wd(32)(31,0) ,
ap_bfp -> bfp_result_d(31,0) ))
//rvdffe #(33) i_bitmanip_ff (.*, .clk(clk), .din({bitmanip_sel_d,bitmanip_d[31:0]}), .dout({bitmanip_sel_x,bitmanip_x[31:0]}), .en(bit_x_enable));
val bitmanip_sel_x = rvdffe(bitmanip_sel_d,bit_x_enable,clock,io.scan_mode)
val bitmanip_x = rvdffe(bitmanip_d,bit_x_enable,clock,io.scan_mode)
io.result_x := (Fill(32,~bitmanip_sel_x & ~low_x) & prod_x(63,32) ) |
(Fill(32,~bitmanip_sel_x & low_x) & prod_x(31,0) ) |
bitmanip_x
io.result_x := Mux1H (Seq(!low_x.asBool -> prod_x(63,32), low_x.asBool -> prod_x(31,0)))
}
object mul extends App {
println((new ChiselStage).emitVerilog(new exu_mul_ctl))}

View File

@ -9,14 +9,9 @@ import include._
@chiselName
class ifu extends Module with lib with RequireAsyncReset {
val io = IO(new Bundle{
val ifu_i0_fa_index = Output(UInt(log2Ceil(BTB_SIZE).W))
val dec_i0_decode_d = Input(Bool()) // Dec
val dec_fa_error_index = Input(UInt(log2Ceil(BTB_SIZE).W))// Fully associative btb error index
val exu_flush_final = Input(Bool())
val exu_flush_path_final = Input(UInt(31.W))
val free_l2clk = Input(Clock())
val exu_flush_final = Input(Bool())
val exu_flush_path_final = Input(UInt(31.W))
val free_clk = Input(Clock())
val active_clk = Input(Clock())
val ifu_dec = new ifu_dec() // IFU and DEC interconnects
val exu_ifu = new exu_ifu() // IFU and EXU interconnects
@ -42,7 +37,8 @@ class ifu extends Module with lib with RequireAsyncReset {
val ifc_ctl = Module(new ifu_ifc_ctl)
// IFC wiring Inputs
ifc_ctl.io.free_l2clk := io.free_l2clk
ifc_ctl.io.active_clk := io.active_clk
ifc_ctl.io.free_clk := io.free_clk
ifc_ctl.io.scan_mode := io.scan_mode
ifc_ctl.io.ic_hit_f := mem_ctl.io.ic_hit_f
ifc_ctl.io.ifu_fb_consume1 := aln_ctl.io.ifu_fb_consume1
@ -75,16 +71,13 @@ class ifu extends Module with lib with RequireAsyncReset {
aln_ctl.io.ifu_bp_ret_f := bp_ctl.io.ifu_bp_ret_f
aln_ctl.io.exu_flush_final := io.exu_flush_final
aln_ctl.io.dec_aln <> io.ifu_dec.dec_aln
io.ifu_i0_fa_index := aln_ctl.io.ifu_i0_fa_index
aln_ctl.io.dec_i0_decode_d := io.dec_i0_decode_d
aln_ctl.io.ifu_bp_fa_index_f := bp_ctl.io.ifu_bp_fa_index_f
aln_ctl.io.ifu_fetch_data_f := mem_ctl.io.ic_data_f
aln_ctl.io.ifu_fetch_val := mem_ctl.io.ifu_fetch_val
aln_ctl.io.ifu_fetch_pc := ifc_ctl.io.ifc_fetch_addr_f
// BP wiring Inputs
bp_ctl.io.scan_mode := io.scan_mode
bp_ctl.io.active_clk := io.active_clk
bp_ctl.io.ic_hit_f := mem_ctl.io.ic_hit_f
bp_ctl.io.ifc_fetch_addr_f := ifc_ctl.io.ifc_fetch_addr_f
bp_ctl.io.ifc_fetch_req_f := ifc_ctl.io.ifc_fetch_req_f
@ -92,10 +85,9 @@ class ifu extends Module with lib with RequireAsyncReset {
bp_ctl.io.exu_bp <> io.exu_ifu.exu_bp
bp_ctl.io.exu_flush_final := io.exu_flush_final
bp_ctl.io.dec_tlu_flush_lower_wb := io.dec_tlu_flush_lower_wb
bp_ctl.io.dec_fa_error_index := io.dec_fa_error_index
// mem-ctl Inputs
mem_ctl.io.free_l2clk := io.free_l2clk
mem_ctl.io.free_clk := io.free_clk
mem_ctl.io.active_clk := io.active_clk
mem_ctl.io.exu_flush_final := io.exu_flush_final
mem_ctl.io.dec_mem_ctrl <> io.ifu_dec.dec_mem_ctrl
@ -127,6 +119,3 @@ class ifu extends Module with lib with RequireAsyncReset {
}
object ifu_top extends App {
println((new chisel3.stage.ChiselStage).emitVerilog(new ifu()))
}

View File

@ -6,30 +6,12 @@ import include._
class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
val io = IO(new Bundle{
val scan_mode = Input(Bool())
val scan_mode = Input(Bool())
val active_clk = Input(Clock())
val ifu_async_error_start = Input(Bool()) // Error coming from mem-ctl
val iccm_rd_ecc_double_err = Input(UInt(2.W)) // ICCM double error coming from mem-ctl
val ic_access_fault_f = Input(UInt(2.W)) // Access fault in I$
val iccm_rd_ecc_double_err = Input(Bool()) // ICCM double error coming from mem-ctl
val ic_access_fault_f = Input(Bool()) // Access fault in I$
val ic_access_fault_type_f = Input(UInt(2.W)) // Type of access fault occured
val dec_i0_decode_d = Input(Bool())
val dec_aln = new dec_aln()
// val ifu_i0_valid = Output(Bool())
// val ifu_i0_icaf = Output(Bool())
// val ifu_i0_icaf_type = Output(UInt(2.W))
// val ifu_i0_icaf_second = Output(Bool())
// val ifu_i0_dbecc = Output(Bool())
// val ifu_i0_instr = Output(UInt(32.W))
// val ifu_i0_pc = Output(UInt(31.W))
// val ifu_i0_pc4 = Output(Bool())
val ifu_bp_fa_index_f = Vec(2, Input(UInt(log2Ceil(BTB_SIZE).W)))
// val i0_brp = Output(Valid(new br_pkt_t()))
// val ifu_i0_bp_index = Output(UInt((BTB_ADDR_HI-BTB_ADDR_LO+1).W))
// val ifu_i0_bp_fghr = Output(UInt(BHT_GHR_SIZE.W))
// val ifu_i0_bp_btag = Output(UInt(BTB_BTAG_SIZE.W))
val ifu_i0_fa_index = Output(UInt(log2Ceil(BTB_SIZE).W))
// val ifu_pmu_instr_aligned = Output(Bool())
// val ifu_i0_cinst = Output(UInt(16.W))
val ifu_bp_fghr_f = Input(UInt(BHT_GHR_SIZE.W)) // Data coming from the branch predictor to put in the FP
val ifu_bp_btb_target_f = Input(UInt(31.W)) // Target for the instruction enqueue in the FP
val ifu_bp_poffset_f = Input(UInt(12.W)) // Offset to the current PC for branch
@ -40,19 +22,19 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
val ifu_bp_valid_f = Input(UInt(2.W)) // Valid Branch prediction
val ifu_bp_ret_f = Input(UInt(2.W)) // BP ret
val exu_flush_final = Input(Bool()) // Miss prediction
val dec_aln = new dec_aln() // Data going to the dec from the ALN
val ifu_fetch_data_f = Input(UInt(32.W)) // PC of the current instruction in the FP
val ifu_fetch_val = Input(UInt(2.W)) // PC boundary i.e 'x' of 2 or 4
val ifu_fetch_pc = Input(UInt(31.W)) // Current PC
/////////////////////////////////////////////////
/////////////////////////////////////////////////
val ifu_fb_consume1 = Output(Bool()) // FP used 1
val ifu_fb_consume2 = Output(Bool()) // FP used 2
})
val MHI = 1 + (BTB_ENABLE * (43+BHT_GHR_SIZE))
val MSIZE = 2 + (BTB_ENABLE * (43+BHT_GHR_SIZE))
val BRDATA_SIZE = if(BTB_ENABLE) 16+log2Ceil(BTB_SIZE) * 2 * BTB_FULLYA else 2
val BRDATA_WIDTH = if(BTB_ENABLE) 8+log2Ceil(BTB_SIZE)*BTB_FULLYA else 1
val MHI = 46+BHT_GHR_SIZE // 54
val MSIZE = 47+BHT_GHR_SIZE // 55
val BRDATA_SIZE = 12
val error_stall_in = WireInit(Bool(),0.U)
val alignval = WireInit(UInt(2.W), 0.U)
val q0final = WireInit(UInt(32.W), 0.U)
val q1final = WireInit(UInt(16.W), 0.U)
@ -76,8 +58,8 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
val shift_f2_f0 = WireInit(Bool(), init = 0.U)
val shift_f1_f0 = WireInit(Bool(), init = 0.U)
val f0icaf = WireInit(UInt(2.W), init = 0.U)
val f1icaf = WireInit(UInt(2.W), init = 0.U)
val f0icaf = WireInit(Bool(), init = 0.U)
val f1icaf = WireInit(Bool(), init = 0.U)
val sf0val = WireInit(UInt(2.W), 0.U)
val sf1val = WireInit(UInt(2.W), 0.U)
@ -86,9 +68,9 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
val misc1 = WireInit(UInt((MHI+1).W), 0.U)
val misc2 = WireInit(UInt((MHI+1).W), 0.U)
val brdata1 = WireInit(UInt(BRDATA_SIZE.W), init = 0.U)
val brdata0 = WireInit(UInt(BRDATA_SIZE.W), init = 0.U)
val brdata2 = WireInit(UInt(BRDATA_SIZE.W), init = 0.U)
val brdata1 = WireInit(UInt(12.W), init = 0.U)
val brdata0 = WireInit(UInt(12.W), init = 0.U)
val brdata2 = WireInit(UInt(12.W), init = 0.U)
val q0 = WireInit(UInt(32.W), init = 0.U)
val q1 = WireInit(UInt(32.W), init = 0.U)
@ -112,55 +94,52 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
val first4B = WireInit(Bool(), 0.U)
val shift_2B = WireInit(Bool(), 0.U)
val f0_shift_2B = WireInit(Bool(), 0.U)
implicit val clk = clock
implicit val rst = reset.asAsyncReset()
implicit val scan_mode = io.scan_mode
// Stall if there is an error in the instrucion
val error_stall_in = (error_stall | io.ifu_async_error_start) & !io.exu_flush_final
error_stall_in := (error_stall | io.ifu_async_error_start) & !io.exu_flush_final
// Flop the stall until flush
error_stall := withClock(io.active_clk) {RegNext(error_stall_in, init = 0.U)}
// Write Ptr of the FP
val wrptr = withClock(io.active_clk) {RegNext(wrptr_in, init = 0.U)}
// Read Ptr of the FP
val rdptr = withClock(io.active_clk) {RegNext(rdptr_in, init = 0.U)}
// Fetch Instruction boundary
val f2val = withClock(io.active_clk) {RegNext(f2val_in, init = 0.U)}
val f1val = withClock(io.active_clk) {RegNext(f1val_in, init = 0.U)}
val f0val = withClock(io.active_clk) {RegNext(f0val_in, init = 0.U)}
val q2off = withClock(io.active_clk) {RegNext(q2off_in, init = 0.U)}
val q1off = withClock(io.active_clk) {RegNext(q1off_in, init = 0.U)}
val q0off = withClock(io.active_clk) {RegNext(q0off_in, init = 0.U)}
// Flop the stall until flush
error_stall := rvdffie(error_stall_in,clock,reset.asAsyncReset(),io.scan_mode)
val f2val = rvdffie(f2val_in,clock,reset.asAsyncReset(),io.scan_mode)
val f1val = rvdffie(f1val_in,clock,reset.asAsyncReset(),io.scan_mode)
val f0val = rvdffie(f0val_in,clock,reset.asAsyncReset(),io.scan_mode)
// Instrution PC to the FP
val f2pc = rvdffe(io.ifu_fetch_pc, f2_wr_en.asBool, clock, io.scan_mode)
val f1pc = rvdffe(f1pc_in, f1_shift_wr_en.asBool, clock, io.scan_mode)
val f0pc = rvdffe(f0pc_in, f0_shift_wr_en.asBool, clock, io.scan_mode)
// Branch data to the FP
if(BTB_ENABLE){
brdata2 := rvdffe(brdata_in, qwen(2),clock,io.scan_mode)
brdata1 := rvdffe(brdata_in, qwen(1),clock,io.scan_mode)
brdata0 := rvdffe(brdata_in, qwen(0),clock,io.scan_mode)
// Miscalanious data to the FP including error's
misc2 := rvdffe(misc_data_in, qwen(2),clock,io.scan_mode)
misc1 := rvdffe(misc_data_in, qwen(1),clock,io.scan_mode)
misc0 := rvdffe(misc_data_in, qwen(0),clock,io.scan_mode)
}
else{
brdata2 := rvdffie(Mux(qwen(2),brdata_in, brdata2),clock,reset.asAsyncReset(),io.scan_mode)
brdata1 := rvdffie(Mux(qwen(1),brdata_in, brdata1),clock,reset.asAsyncReset(),io.scan_mode)
brdata0 := rvdffie(Mux(qwen(0),brdata_in, brdata0),clock,reset.asAsyncReset(),io.scan_mode)
// Miscalanious data to the FP including error's
misc2 := rvdffie(Mux(qwen(2),misc_data_in, misc2),clock,reset.asAsyncReset(),io.scan_mode)
misc1 := rvdffie(Mux(qwen(1),misc_data_in, misc1),clock,reset.asAsyncReset(),io.scan_mode)
misc0 := rvdffie(Mux(qwen(0),misc_data_in, misc0),clock,reset.asAsyncReset(),io.scan_mode)
}
brdata2 := rvdffe(brdata_in, qwen(2), clock, io.scan_mode)
brdata1 := rvdffe(brdata_in, qwen(1), clock, io.scan_mode)
brdata0 := rvdffe(brdata_in, qwen(0), clock, io.scan_mode)
// Miscalanious data to the FP including error's
misc2 := rvdffe(misc_data_in, qwen(2), clock, io.scan_mode)
misc1 := rvdffe(misc_data_in, qwen(1), clock, io.scan_mode)
misc0 := rvdffe(misc_data_in, qwen(0), clock, io.scan_mode)
// Instruction in the FP
q2 := rvdffe(io.ifu_fetch_data_f, qwen(2),clock,io.scan_mode)
q1 := rvdffe(io.ifu_fetch_data_f, qwen(1),clock,io.scan_mode)
q0 := rvdffe(io.ifu_fetch_data_f, qwen(0),clock,io.scan_mode)
val q2pc = rvdffe(io.ifu_fetch_pc, qwen(2),clock,io.scan_mode)
val q1pc = rvdffe(io.ifu_fetch_pc, qwen(1),clock,io.scan_mode)
val q0pc = rvdffe(io.ifu_fetch_pc, qwen(0),clock,io.scan_mode)
q2 := rvdffe(io.ifu_fetch_data_f, qwen(2), clock, io.scan_mode)
q1 := rvdffe(io.ifu_fetch_data_f, qwen(1), clock, io.scan_mode)
q0 := rvdffe(io.ifu_fetch_data_f, qwen(0), clock, io.scan_mode)
// Shift FP logic
f2_wr_en := fetch_to_f2
f1_shift_wr_en := fetch_to_f1 | shift_f2_f1 | f1_shift_2B
f0_shift_wr_en := fetch_to_f0 | shift_f2_f0 | shift_f1_f0 | shift_2B | shift_4B
// FP read enable .. 3-bit for Implemenation of 1HMux
val qren = Cat(rdptr === 2.U, rdptr === 1.U, rdptr === 0.U)
// FP write enable .. 3-bit for Implemenation of 1HMux
qwen := Cat(wrptr === 2.U & ifvalid, wrptr === 1.U & ifvalid, wrptr === 0.U & ifvalid)
qwen := Cat((wrptr === 2.U) & ifvalid, (wrptr === 1.U) & ifvalid, (wrptr === 0.U) & ifvalid)
// Read Pointer calculation
// Next rdptr = # of consume + current ptr location (Rounding it from 2)
rdptr_in := Mux1H(Seq((qren(0) & io.ifu_fb_consume1 & !io.exu_flush_final).asBool -> 1.U,
(qren(1) & io.ifu_fb_consume1 & !io.exu_flush_final).asBool -> 2.U,
(qren(2) & io.ifu_fb_consume1 & !io.exu_flush_final).asBool -> 0.U,
@ -169,156 +148,86 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
(qren(2) & io.ifu_fb_consume2 & !io.exu_flush_final).asBool -> 1.U,
(!io.ifu_fb_consume1 & !io.ifu_fb_consume2 & !io.exu_flush_final).asBool -> rdptr))
// As there is only 1 enqueue so each time move by 1
wrptr_in := Mux1H(Seq((qwen(0) & !io.exu_flush_final).asBool -> 1.U,
(qwen(1) & !io.exu_flush_final).asBool -> 2.U,
(qwen(2) & !io.exu_flush_final).asBool -> 0.U,
(!ifvalid & !io.exu_flush_final).asBool-> wrptr))
(!ifvalid & !io.exu_flush_final).asBool->wrptr))
q2off_in := Mux1H(Seq((!qwen(2) & (rdptr===2.U)).asBool -> (q2off.asUInt | f0_shift_2B),
(!qwen(2) & (rdptr===1.U)).asBool -> (q2off.asUInt | f1_shift_2B),
(!qwen(2) & (rdptr===0.U)).asBool -> q2off))
q2off_in := Mux1H(Seq((!qwen(2) & (rdptr===2.U)).asBool->(q2off.asUInt | f0_shift_2B),
(!qwen(2) & (rdptr===1.U)).asBool->(q2off.asUInt | f1_shift_2B),
(!qwen(2) & (rdptr===0.U)).asBool->q2off))
q1off_in := Mux1H(Seq((!qwen(1) & (rdptr===1.U)).asBool -> (q1off.asUInt | f0_shift_2B),
(!qwen(1) & (rdptr===0.U)).asBool -> (q1off.asUInt | f1_shift_2B),
(!qwen(1) & (rdptr===2.U)).asBool -> q1off))
q1off_in := Mux1H(Seq((!qwen(1) & (rdptr===1.U)).asBool->(q1off.asUInt | f0_shift_2B),
(!qwen(1) & (rdptr===0.U)).asBool->(q1off.asUInt | f1_shift_2B),
(!qwen(1) & (rdptr===2.U)).asBool->q1off))
q0off_in := Mux1H(Seq((!qwen(0) & (rdptr===0.U)).asBool -> (q0off.asUInt | f0_shift_2B),
(!qwen(0) & (rdptr===2.U)).asBool -> (q0off.asUInt | f1_shift_2B),
(!qwen(0) & (rdptr===1.U)).asBool -> q0off))
(!qwen(0) & (rdptr===2.U)).asBool -> (q0off.asUInt | f1_shift_2B),
(!qwen(0) & (rdptr===1.U)).asBool -> q0off))
// Shift FP logic
val q0ptr = Mux1H(Seq((rdptr===0.U)->q0off,
(rdptr===1.U)->q1off,
(rdptr===2.U)->q2off))
val q0ptr = Mux1H(Seq((rdptr===0.U) -> q0off,
(rdptr===1.U) -> q1off,
(rdptr===2.U) -> q2off))
val q1ptr = Mux1H(Seq((rdptr===0.U) -> q1off, (rdptr === 1.U) -> q2off, (rdptr === 2.U) -> q0off))
val q1ptr = Mux1H(Seq((rdptr===0.U) -> q1off, (rdptr === 1.U) -> q2off, (rdptr === 2.U) -> q0off))
val q0sel = Cat(q0ptr, !q0ptr)
val q1sel = Cat(q1ptr, !q1ptr)
// Misc data error, access-fault, type of fault, target, offset and ghr value
if(BTB_ENABLE){
misc_data_in := Cat(io.ic_access_fault_type_f, io.ifu_bp_btb_target_f, io.ifu_bp_poffset_f, io.ifu_bp_fghr_f)
}else{
misc_data_in := io.ic_access_fault_type_f
}
misc_data_in := Cat(io.iccm_rd_ecc_double_err, io.ic_access_fault_f, io.ic_access_fault_type_f,
io.ifu_bp_btb_target_f, io.ifu_bp_poffset_f, io.ifu_bp_fghr_f)
val misceff = Mux1H(Seq(qren(0).asBool() -> Cat(misc1, misc0),
qren(1).asBool() -> Cat(misc2, misc1),
qren(2).asBool() -> Cat(misc0, misc2)))
qren(1).asBool()->Cat(misc2, misc1),
qren(2).asBool()->Cat(misc0, misc2)))
val misc1eff = misceff(misceff.getWidth-1,MHI+1)
val misc0eff = misceff(MHI, 0)
///////////////////////////////////////////////////////////////////////
val f1ictype = if(BTB_ENABLE) misc1eff(misc1eff.getWidth-1, misc1eff.getWidth-2) else misc1eff
val f1prett = if(BTB_ENABLE) misc1eff(misc1eff.getWidth-3, misc1eff.getWidth-33) else 0.U
val f1poffset = if(BTB_ENABLE) misc1eff(misc1eff.getWidth-34, misc1eff.getWidth-45) else 0.U
val f1fghr = if(BTB_ENABLE) misc1eff(BHT_GHR_SIZE-1, 0) else 0.U
val f0ictype = if(BTB_ENABLE) misc0eff(misc0eff.getWidth-1, misc0eff.getWidth-2) else misc0eff
val f0prett = if(BTB_ENABLE) misc0eff(misc0eff.getWidth-3, misc0eff.getWidth-33) else 0.U
val f0poffset = if(BTB_ENABLE) misc0eff(misc0eff.getWidth-34, misc0eff.getWidth-45) else 0.U
val f0fghr = if(BTB_ENABLE) misc0eff(BHT_GHR_SIZE-1, 0) else 0.U
val f1dbecc = misc1eff(misc1eff.getWidth-1)
f1icaf := misc1eff(misc1eff.getWidth-2)
val f1ictype = misc1eff(misc1eff.getWidth-3,misc1eff.getWidth-4)
val f1prett = misc1eff(misc1eff.getWidth-5,misc1eff.getWidth-35)
val f1poffset = misc1eff(BHT_GHR_SIZE+11, BHT_GHR_SIZE)
val f1fghr = misc1eff(BHT_GHR_SIZE-1, 0)
val f0ret = WireInit(UInt(2.W), 0.U)
val f0brend = WireInit(UInt(2.W), 0.U)
val f0way = WireInit(UInt(2.W), 0.U)
val f0pc4 = WireInit(UInt(2.W), 0.U)
val f0hist0 = WireInit(UInt(2.W), 0.U)
val f0hist1 = WireInit(UInt(2.W), 0.U)
val f1ret = WireInit(UInt(2.W), 0.U)
val f1brend = WireInit(UInt(2.W), 0.U)
val f1way = WireInit(UInt(2.W), 0.U)
val f1pc4 = WireInit(UInt(2.W), 0.U)
val f1hist0 = WireInit(UInt(2.W), 0.U)
val f1hist1 = WireInit(UInt(2.W), 0.U)
val f0dbecc = misc0eff(misc1eff.getWidth-1)
f0icaf := misc0eff(misc1eff.getWidth-2)
val f0ictype = misc0eff(misc1eff.getWidth-3,misc1eff.getWidth-4)
val f0prett = misc0eff(misc1eff.getWidth-5,misc1eff.getWidth-35)
val f0poffset = misc0eff(BHT_GHR_SIZE+11, BHT_GHR_SIZE)
val f0fghr = misc0eff(BHT_GHR_SIZE-1, 0)
// Branch information
brdata_in := Cat(io.ifu_bp_hist1_f(1),io.ifu_bp_hist0_f(1),io.ifu_bp_pc4_f(1),io.ifu_bp_way_f(1),io.ifu_bp_valid_f(1),
io.ifu_bp_ret_f(1), io.ifu_bp_hist1_f(0),io.ifu_bp_hist0_f(0),io.ifu_bp_pc4_f(0),io.ifu_bp_way_f(0),
io.ifu_bp_valid_f(0),io.ifu_bp_ret_f(0))
// Effective branch information
val brdataeff = Mux1H(Seq(qren(0).asBool->Cat(brdata1,brdata0),
qren(1).asBool->Cat(brdata2,brdata1),
qren(2).asBool->Cat(brdata0,brdata2)))
val f0dbecc = WireInit(UInt(2.W), 0.U)
val f1dbecc = WireInit(UInt(2.W), 0.U)
val f0index = Wire(Vec(2,UInt(log2Ceil(BTB_SIZE).W)))
val f1index = Wire(Vec(2,UInt(log2Ceil(BTB_SIZE).W)))
f0index := (0 until 2).map(i => 0.U)
f1index := (0 until 2).map(i => 0.U)
val brdataeff = WireInit(UInt(((2*BRDATA_SIZE)).W),0.U)
brdataeff := Mux1H(Seq(qren(0).asBool -> Cat(brdata1,brdata0),
qren(1).asBool -> Cat(brdata2,brdata1),
qren(2).asBool -> Cat(brdata0,brdata2)))
val brdata1eff = WireInit(UInt(BRDATA_SIZE.W),0.U)
val brdata0eff = WireInit(UInt(BRDATA_SIZE.W),0.U)
brdata1eff := brdataeff(brdataeff.getWidth - 1,brdataeff.getWidth/2)
brdata0eff := brdataeff(brdataeff.getWidth/2 - 1,0)
val brdata0final = Mux1H(Seq(q0sel(0).asBool -> brdata0eff(2*BRDATA_WIDTH-1,0),
q0sel(1).asBool -> brdata0eff(BRDATA_SIZE-1,BRDATA_WIDTH)))
val brdata1final = Mux1H(Seq(q1sel(0).asBool -> brdata1eff(2*BRDATA_WIDTH-1,0),
q1sel(1).asBool -> brdata1eff(BRDATA_SIZE-1,BRDATA_WIDTH)))
if(BTB_ENABLE){
if(BTB_FULLYA){
brdata_in := Cat(io.ifu_bp_fa_index_f(1), io.iccm_rd_ecc_double_err(1), io.ic_access_fault_f(1), io.ifu_bp_hist1_f(1), io.ifu_bp_hist0_f(1), io.ifu_bp_pc4_f(1), io.ifu_bp_way_f(1), io.ifu_bp_valid_f(1), io.ifu_bp_ret_f(1),
io.ifu_bp_fa_index_f(0), io.iccm_rd_ecc_double_err(0), io.ic_access_fault_f(0), io.ifu_bp_hist1_f(0), io.ifu_bp_hist0_f(0), io.ifu_bp_pc4_f(0), io.ifu_bp_way_f(0), io.ifu_bp_valid_f(0), io.ifu_bp_ret_f(0))
val (brdata0eff,brdata1eff) = (brdataeff(11,0) , brdataeff(23,12))
f0ret := Cat(brdata0final(17) , brdata0final(0))
f0brend := Cat(brdata0final(18), brdata0final(1))
f0way := Cat(brdata0final(19), brdata0final(2))
f0pc4 := Cat(brdata0final(20), brdata0final(3))
f0hist0 := Cat(brdata0final(21), brdata0final(4))
f0hist1 := Cat(brdata0final(22), brdata0final(5))
f0icaf := Cat(brdata0final(23), brdata0final(6))
f0dbecc := Cat(brdata0final(24), brdata0final(7))
f0index(1) := Cat(brdata0final(33), brdata0final(32), brdata0final(31), brdata0final(30), brdata0final(29), brdata0final(28), brdata0final(27), brdata0final(26), brdata0final(25))
f0index(0) := Cat(brdata0final(16), brdata0final(15), brdata0final(14), brdata0final(13), brdata0final(12), brdata0final(11), brdata0final(10), brdata0final(9), brdata0final(8))
val brdata0final = Mux1H(Seq(q0sel(0).asBool -> brdata0eff, q0sel(1).asBool -> brdata0eff(11,6)))
val brdata1final = Mux1H(Seq(q1sel(0).asBool -> brdata1eff, q1sel(1).asBool -> brdata1eff(11,6)))
f1ret := Cat(brdata1final(17) , brdata1final(0))
f1brend := Cat(brdata1final(18), brdata1final(1))
f1way := Cat(brdata1final(19), brdata1final(2))
f1pc4 := Cat(brdata1final(20), brdata1final(3))
f1hist0 := Cat(brdata1final(21), brdata1final(4))
f1hist1 := Cat(brdata1final(22), brdata1final(5))
f1icaf := Cat(brdata1final(23), brdata1final(6))
f1dbecc := Cat(brdata1final(24), brdata1final(7))
f1index(1) := Cat(brdata1final(33), brdata1final(32), brdata1final(31), brdata1final(30), brdata1final(29), brdata1final(28), brdata1final(27), brdata1final(26), brdata1final(25))
f1index(0) := Cat(brdata1final(16), brdata1final(15), brdata1final(14), brdata1final(13), brdata1final(12), brdata1final(11), brdata1final(10), brdata1final(9), brdata1final(8))
val f0ret = Cat(brdata0final(6),brdata0final(0))
val f0brend = Cat(brdata0final(7),brdata0final(1))
val f0way = Cat(brdata0final(8),brdata0final(2))
val f0pc4 = Cat(brdata0final(9),brdata0final(3))
val f0hist0 = Cat(brdata0final(10),brdata0final(4))
val f0hist1 = Cat(brdata0final(11),brdata0final(5))
}else{
brdata_in := Cat(io.iccm_rd_ecc_double_err(1), io.ic_access_fault_f(1), io.ifu_bp_hist1_f(1), io.ifu_bp_hist0_f(1), io.ifu_bp_pc4_f(1), io.ifu_bp_way_f(1), io.ifu_bp_valid_f(1), io.ifu_bp_ret_f(1),
io.iccm_rd_ecc_double_err(0), io.ic_access_fault_f(0), io.ifu_bp_hist1_f(0), io.ifu_bp_hist0_f(0), io.ifu_bp_pc4_f(0), io.ifu_bp_way_f(0), io.ifu_bp_valid_f(0), io.ifu_bp_ret_f(0))
f0ret := Cat(brdata0final(8) , brdata0final(0))
f0brend := Cat(brdata0final(9) , brdata0final(1))
f0way := Cat(brdata0final(10), brdata0final(2))
f0pc4 := Cat(brdata0final(11), brdata0final(3))
f0hist0 := Cat(brdata0final(12), brdata0final(4))
f0hist1 := Cat(brdata0final(13), brdata0final(5))
f0icaf := Cat(brdata0final(14), brdata0final(6))
f0dbecc := Cat(brdata0final(15), brdata0final(7))
f1ret := Cat(brdata1final(8) , brdata1final(0))
f1brend := Cat(brdata1final(9) , brdata1final(1))
f1way := Cat(brdata1final(10), brdata1final(2))
f1pc4 := Cat(brdata1final(11), brdata1final(3))
f1hist0 := Cat(brdata1final(12), brdata1final(4))
f1hist1 := Cat(brdata1final(13), brdata1final(5))
f1icaf := Cat(brdata1final(14), brdata1final(6))
f1dbecc := Cat(brdata1final(15), brdata1final(7))
}
}else{
brdata_in := Cat(io.iccm_rd_ecc_double_err(1),io.ic_access_fault_f(1),
io.iccm_rd_ecc_double_err(0),io.ic_access_fault_f(0))
f0dbecc := Cat(brdata0final(3),brdata0final(1))
f0icaf := Cat(brdata0final(2),brdata0final(0))
f1dbecc := Cat(brdata1final(3),brdata1final(1))
f1icaf := Cat(brdata1final(2),brdata1final(0))
}
val f1ret = Cat(brdata1final(6),brdata1final(0))
val f1brend = Cat(brdata1final(7),brdata1final(1))
val f1way = Cat(brdata1final(8),brdata1final(2))
val f1pc4 = Cat(brdata1final(9),brdata1final(3))
val f1hist0 = Cat(brdata1final(10),brdata1final(4))
val f1hist1 = Cat(brdata1final(11),brdata1final(5))
f2_valid := f2val(0)
@ -341,82 +250,81 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
fetch_to_f0 := !sf0_valid & !sf1_valid & !f2_valid & ifvalid
fetch_to_f1 := (!sf0_valid & !sf1_valid & f2_valid & ifvalid) |
(!sf0_valid & sf1_valid & !f2_valid & ifvalid) |
( sf0_valid & !sf1_valid & !f2_valid & ifvalid)
(!sf0_valid & sf1_valid & !f2_valid & ifvalid) |
( sf0_valid & !sf1_valid & !f2_valid & ifvalid)
fetch_to_f2 := (!sf0_valid & sf1_valid & f2_valid & ifvalid) |
( sf0_valid & sf1_valid & !f2_valid & ifvalid)
( sf0_valid & sf1_valid & !f2_valid & ifvalid)
val f0pc_plus1 = f0pc + 1.U
val f1pc_plus1 = f1pc + 1.U
val sf1pc = (Fill(31, f1_shift_2B) & f1pc_plus1) | (Fill(31, !f1_shift_2B) & f1pc)
f1pc_in := Mux1H(Seq(fetch_to_f1.asBool->io.ifu_fetch_pc,
shift_f2_f1.asBool->f2pc,
(!fetch_to_f1 & !shift_f2_f1).asBool -> sf1pc))
f0pc_in := Mux1H(Seq(fetch_to_f0.asBool->io.ifu_fetch_pc,
shift_f2_f0.asBool->f2pc,
shift_f1_f0.asBool->sf1pc,
(!fetch_to_f0 & !shift_f2_f0 & !shift_f1_f0).asBool->f0pc_plus1))
f2val_in := Mux1H(Seq((fetch_to_f2 & !io.exu_flush_final).asBool->io.ifu_fetch_val,
(!fetch_to_f2 & !shift_f2_f1 & !shift_f2_f0 & !io.exu_flush_final).asBool->f2val))
(!fetch_to_f2 & !shift_f2_f1 & !shift_f2_f0 & !io.exu_flush_final).asBool->f2val))
sf1val := Mux1H(Seq(f1_shift_2B.asBool->f1val(1), !f1_shift_2B.asBool->f1val))
f1val_in := Mux1H(Seq(( fetch_to_f1 & !io.exu_flush_final).asBool -> io.ifu_fetch_val,
( shift_f2_f1 & !io.exu_flush_final).asBool->f2val,
(!fetch_to_f1 & !shift_f2_f1 & !shift_f1_f0 & !io.exu_flush_final).asBool->sf1val))
( shift_f2_f1 & !io.exu_flush_final).asBool->f2val,
(!fetch_to_f1 & !shift_f2_f1 & !shift_f1_f0 & !io.exu_flush_final).asBool->sf1val))
sf0val := Mux1H(Seq(shift_2B.asBool->Cat(0.U, f0val(1)),
(!shift_2B & !shift_4B).asBool->f0val))
(!shift_2B & !shift_4B).asBool->f0val))
f0val_in := Mux1H(Seq((fetch_to_f0 & !io.exu_flush_final).asBool->io.ifu_fetch_val,
( shift_f2_f0 & !io.exu_flush_final).asBool->f2val,
( shift_f1_f0 & !io.exu_flush_final).asBool->sf1val,
(!fetch_to_f0 & !shift_f2_f0 & !shift_f1_f0 & !io.exu_flush_final).asBool->sf0val))
( shift_f2_f0 & !io.exu_flush_final).asBool->f2val,
( shift_f1_f0 & !io.exu_flush_final).asBool->sf1val,
(!fetch_to_f0 & !shift_f2_f0 & !shift_f1_f0 & !io.exu_flush_final).asBool->sf0val))
val qeff = Mux1H(Seq(qren(0).asBool -> Cat(q1,q0),
qren(1).asBool -> Cat(q2,q1),
qren(2).asBool -> Cat(q0,q2)))
val qeff = Mux1H(Seq(qren(0).asBool->Cat(q1,q0),
qren(1).asBool->Cat(q2,q1),
qren(2).asBool->Cat(q0,q2)))
val (q1eff, q0eff) = (qeff(63,32), qeff(31,0))
q0final := Mux1H(Seq(q0sel(0).asBool->q0eff,
q0sel(1).asBool->q0eff(31,16)))
q0final := Mux1H(Seq(q0sel(0).asBool->q0eff, q0sel(1).asBool->q0eff(31,16)))
q1final := Mux1H(Seq(q1sel(0).asBool->q1eff(15,0), q1sel(1).asBool->q1eff(31,16)))
val qpceff = Mux1H(Seq(qren(0).asBool -> Cat(q1pc, q0pc),
qren(1).asBool -> Cat(q2pc, q1pc),
qren(2).asBool -> Cat(q0pc, q2pc)))
val q1pceff = qpceff(61, 31)
val q0pceff = qpceff(30, 0)
val q0pcfinal = Mux1H(Seq(q0sel(0) -> q0pceff, q0sel(1) -> (q0pceff+1.U)))
// Alinging the data according to the boundary of PC
val aligndata = Mux1H(Seq(f0val(1).asBool -> q0final, (!f0val(1) & f0val(0)).asBool -> Cat(q1final(15,0),q0final(15,0))))
val aligndata = Mux1H(Seq(f0val(1).asBool -> q0final, (~f0val(1) & f0val(0)).asBool -> Cat(q1final(15,0),q0final(15,0))))
alignval := Mux1H(Seq(f0val(1).asBool->3.U, (!f0val(1) & f0val(0)) -> Cat(f1val(0),1.U)))
val alignicaf = Mux1H(Seq(f0val(1).asBool -> f0icaf, (~f0val(1) & f0val(0)).asBool -> Cat(f1icaf(0),f0icaf(0))))
val alignicaf = Mux1H(Seq(f0val(1).asBool -> f0icaf, (~f0val(1) & f0val(0)).asBool -> Cat(f1icaf,f0icaf)))
val aligndbecc = Mux1H(Seq(f0val(1).asBool -> f0dbecc, (!f0val(1) & f0val(0)).asBool -> Cat(f1dbecc(0),f0dbecc(0))))
val aligndbecc = Mux1H(Seq(f0val(1).asBool -> Fill(2,f0dbecc), (!f0val(1) & f0val(0)).asBool -> Cat(f1dbecc,f0dbecc)))
/////////////////////////////////////////////////////////
val alignbrend = if(BTB_ENABLE) Mux1H(Seq(f0val(1).asBool()->f0brend, (!f0val(1) & f0val(0)).asBool->Cat(f1brend(0),f0brend(0)))) else 0.U
val alignbrend = Mux1H(Seq(f0val(1).asBool()->f0brend, (!f0val(1) & f0val(0)).asBool->Cat(f1brend(0),f0brend(0))))
val alignpc4 = if(BTB_ENABLE) Mux1H(Seq(f0val(1).asBool()->f0pc4, (!f0val(1) & f0val(0)).asBool->Cat(f1pc4(0),f0pc4(0)))) else 0.U
val alignpc4 = Mux1H(Seq(f0val(1).asBool()->f0pc4, (!f0val(1) & f0val(0)).asBool->Cat(f1pc4(0),f0pc4(0))))
val alignret = if(BTB_ENABLE) Mux1H(Seq(f0val(1).asBool()->f0ret, (!f0val(1) & f0val(0)).asBool->Cat(f1ret(0),f0ret(0)))) else 0.U
val alignret = Mux1H(Seq(f0val(1).asBool()->f0ret, (!f0val(1) & f0val(0)).asBool->Cat(f1ret(0),f0ret(0))))
val alignway = if(BTB_ENABLE) Mux1H(Seq(f0val(1).asBool()->f0way, (!f0val(1) & f0val(0)).asBool->Cat(f1way(0),f0way(0)))) else 0.U
val alignway = Mux1H(Seq(f0val(1).asBool()->f0way, (!f0val(1) & f0val(0)).asBool->Cat(f1way(0),f0way(0))))
val alignhist1 = if(BTB_ENABLE) Mux1H(Seq(f0val(1).asBool()->f0hist1, (!f0val(1) & f0val(0)).asBool->Cat(f1hist1(0),f0hist1(0)))) else 0.U
val alignhist1 = Mux1H(Seq(f0val(1).asBool()->f0hist1, (!f0val(1) & f0val(0)).asBool->Cat(f1hist1(0),f0hist1(0))))
val alignhist0 = if(BTB_ENABLE) Mux1H(Seq(f0val(1).asBool()->f0hist0, (!f0val(1) & f0val(0)).asBool->Cat(f1hist0(0),f0hist0(0)))) else 0.U
val secondpc = if(BTB_ENABLE) Mux1H(Seq(f0val(1).asBool() -> (q0pceff + 1.U), (!f0val(1) & f0val(0)).asBool -> q1pceff)) else 0.U
val firstpc = if(BTB_ENABLE) q0pcfinal else 0.U
val alignindex = Wire(Vec(2,UInt(log2Ceil(BTB_SIZE).W)))
alignindex := (0 until 2).map(i => 0.U)
if(BTB_ENABLE){if(BTB_FULLYA) {
alignindex(0):= f0index(0)
alignindex(1):= Mux(f0val(1).asBool, f0index(1), f1index(0))
} }
/////////////////////////////////////////////////////////
val alignhist0 = Mux1H(Seq(f0val(1).asBool()->f0hist0, (!f0val(1) & f0val(0)).asBool->Cat(f1hist0(0),f0hist0(0))))
val alignfromf1 = !f0val(1) & f0val(0)
io.dec_aln.aln_ib.ifu_i0_pc := q0pcfinal
val secondpc = Mux1H(Seq(f0val(1).asBool()->f0pc_plus1 , (!f0val(1) & f0val(0)).asBool->f1pc))
io.dec_aln.aln_ib.ifu_i0_pc := f0pc
val firstpc = f0pc
io.dec_aln.aln_ib.ifu_i0_pc4 := first4B
@ -425,7 +333,7 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
// Instruction is compressed or not
first4B := aligndata(1,0) === 3.U
val first2B = !first4B
val first2B = ~first4B
io.dec_aln.aln_ib.ifu_i0_valid := Mux1H(Seq(first4B.asBool -> alignval(1), first2B.asBool -> alignval(0)))
@ -433,9 +341,9 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
io.dec_aln.aln_ib.ifu_i0_icaf_type := Mux((first4B & !f0val(1) & f0val(0) & !alignicaf(0) & !aligndbecc(0)).asBool, f1ictype, f0ictype)
val icaf_eff = alignicaf | aligndbecc
val icaf_eff = alignicaf(1) | aligndbecc(1)
io.dec_aln.aln_ib.ifu_i0_icaf_second := first4B & !icaf_eff(0) & icaf_eff(1)
io.dec_aln.aln_ib.ifu_i0_icaf_f1 := first4B & icaf_eff & alignfromf1
io.dec_aln.aln_ib.ifu_i0_dbecc := Mux1H(Seq(first4B.asBool->aligndbecc.orR, first2B.asBool->aligndbecc(0)))
@ -443,74 +351,55 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
// Expander from 16-bit to 32-bit
val decompressed = Module(new ifu_compress_ctl())
io.dec_aln.aln_ib.ifu_i0_instr := Mux1H(Seq((first4B & alignval(1)).asBool -> ifirst,
(first2B & alignval(0)).asBool -> decompressed.io.dout))
io.dec_aln.aln_ib.ifu_i0_instr := Mux1H(Seq(first4B.asBool -> ifirst, first2B.asBool -> decompressed.io.dout))
////////////////////////////////////////////////////////////////////////////////////////////
val firstpc_hash = btb_addr_hash(firstpc)
// Hashing the PC
val firstpc_hash = btb_addr_hash(f0pc)
val secondpc_hash = btb_addr_hash(secondpc)
val firstbrtag_hash = WireInit(UInt(BTB_BTAG_SIZE.W),0.U)
val secondbrtag_hash = WireInit(UInt(BTB_BTAG_SIZE.W),0.U)
if(BTB_ENABLE){if(BTB_FULLYA)
firstbrtag_hash := firstpc else {if(BTB_BTAG_FOLD) firstbrtag_hash := btb_tag_hash_fold(firstpc) else firstbrtag_hash := btb_tag_hash(firstpc)} }
if(BTB_ENABLE){if(BTB_FULLYA)
secondbrtag_hash := secondpc else {if(BTB_BTAG_FOLD) secondbrtag_hash := btb_tag_hash_fold(secondpc) else secondbrtag_hash := btb_tag_hash(secondpc)} }
val firstbrtag_hash = if(BTB_BTAG_FOLD) btb_tag_hash_fold(firstpc) else btb_tag_hash(firstpc)
if(BTB_ENABLE){
io.dec_aln.aln_ib.i0_brp.valid := (first2B & alignbrend(0)) | (first4B & alignbrend(1)) | (first4B & alignval(1) & alignbrend(0))
val secondbrtag_hash = if(BTB_BTAG_FOLD) btb_tag_hash_fold(secondpc) else btb_tag_hash(secondpc)
val i0_brp_pc4 = (first2B & alignpc4(0)) | (first4B & alignpc4(1))
io.dec_aln.aln_ib.i0_brp.valid :=(first2B & alignbrend(0)) | (first4B & alignbrend(1)) | (first4B & alignval(1) & alignbrend(0))
io.dec_aln.aln_ib.i0_brp.bits.ret := (first2B & alignret(0)) | (first4B & alignret(1))
io.dec_aln.aln_ib.i0_brp.bits.ret := (first2B & alignret(0)) | (first4B & alignret(1))
io.dec_aln.aln_ib.i0_brp.bits.way := Mux((first2B | alignbrend(0)).asBool, alignway(0), alignway(1))
val i0_brp_pc4 = (first2B & alignpc4(0)) | (first4B & alignpc4(1))
io.dec_aln.aln_ib.i0_brp.bits.hist := Cat((first2B & alignhist1(0)) | (first4B & alignhist1(1)),
(first2B & alignhist0(0)) | (first4B & alignhist0(1)))
io.dec_aln.aln_ib.i0_brp.bits.way := Mux((first2B | alignbrend(0)).asBool, alignway(0), alignway(1))
val i0_ends_f1 = first4B & alignfromf1
io.dec_aln.aln_ib.i0_brp.bits.toffset := Mux(i0_ends_f1.asBool, f1poffset, f0poffset)
io.dec_aln.aln_ib.i0_brp.bits.hist := Cat((first2B & alignhist1(0)) | (first4B & alignhist1(1)),
(first2B & alignhist0(0)) | (first4B & alignhist0(1)))
io.dec_aln.aln_ib.i0_brp.bits.prett := Mux(i0_ends_f1.asBool, f1prett, f0prett)
val i0_ends_f1 = first4B & alignfromf1
io.dec_aln.aln_ib.i0_brp.bits.toffset := Mux(i0_ends_f1.asBool, f1poffset, f0poffset)
io.dec_aln.aln_ib.i0_brp.bits.br_start_error := (first4B & alignval(1) & alignbrend(0))
io.dec_aln.aln_ib.i0_brp.bits.prett := Mux(i0_ends_f1.asBool, f1prett, f0prett)
io.dec_aln.aln_ib.i0_brp.bits.bank := Mux((first2B | alignbrend(0)).asBool, firstpc(0), secondpc(0))
io.dec_aln.aln_ib.i0_brp.bits.br_start_error := (first4B & alignval(1) & alignbrend(0))
io.dec_aln.aln_ib.i0_brp.bits.br_error := (io.dec_aln.aln_ib.i0_brp.valid & i0_brp_pc4 & first2B) | (io.dec_aln.aln_ib.i0_brp.valid & !i0_brp_pc4 & first4B)
io.dec_aln.aln_ib.i0_brp.bits.bank := Mux((first2B | alignbrend(0)).asBool, firstpc(0), secondpc(0))
io.dec_aln.aln_ib.ifu_i0_bp_index := Mux((first2B | alignbrend(0)).asBool, firstpc_hash, secondpc_hash)
io.dec_aln.aln_ib.ifu_i0_bp_fghr := Mux((first4B & alignfromf1).asBool, f1fghr, f0fghr)
io.dec_aln.aln_ib.ifu_i0_bp_btag := Mux((first2B | alignbrend(0)).asBool, firstbrtag_hash, secondbrtag_hash)
io.dec_aln.aln_ib.i0_brp.bits.br_error := (io.dec_aln.aln_ib.i0_brp.valid & i0_brp_pc4 & first2B) | (io.dec_aln.aln_ib.i0_brp.valid & !i0_brp_pc4 & first4B)
if(BTB_FULLYA){
io.ifu_i0_fa_index := Mux((first2B | alignbrend(0)).asBool, alignindex(0), alignindex(1))
}else{
io.ifu_i0_fa_index := 0.U
}
}else{
io.dec_aln.aln_ib.ifu_i0_bp_index := 0.U
io.dec_aln.aln_ib.ifu_i0_bp_fghr := 0.U
io.dec_aln.aln_ib.ifu_i0_bp_btag := 0.U
io.dec_aln.aln_ib.i0_brp := 0.U.asTypeOf(io.dec_aln.aln_ib.i0_brp)
}
io.dec_aln.aln_ib.ifu_i0_bp_index := Mux((first2B | alignbrend(0)).asBool, firstpc_hash, secondpc_hash)
io.dec_aln.aln_ib.ifu_i0_bp_fghr := Mux((first4B & alignfromf1).asBool, f1fghr, f0fghr)
io.dec_aln.aln_ib.ifu_i0_bp_btag := Mux((first2B | alignbrend(0)).asBool, firstbrtag_hash, secondbrtag_hash)
decompressed.io.din := Mux(first2B.asBool(),aligndata,0.U)
decompressed.io.din := aligndata
val i0_shift = io.dec_i0_decode_d & !error_stall
val i0_shift = io.dec_aln.aln_dec.dec_i0_decode_d & ~error_stall
io.dec_aln.ifu_pmu_instr_aligned := i0_shift
shift_2B := i0_shift & first2B
shift_4B := i0_shift & first4B
////
f0_shift_2B := Mux1H(Seq(shift_2B.asBool -> f0val(0), shift_4B.asBool -> (f0val(0) & !f0val(1))))
f1_shift_2B := f0val(0) & !f0val(1) & shift_4B
}
//object Aligner extends App {
// (new chisel3.stage.ChiselStage).emitVerilog(new ifu_aln_ctl())
//}

View File

@ -9,73 +9,52 @@ import chisel3.experimental.chiselName
@chiselName
class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
val io = IO (new Bundle {
val ic_hit_f = Input(Bool())
val exu_flush_final = Input(Bool())
val ifc_fetch_addr_f = Input(UInt(31.W))
val ifc_fetch_req_f = Input(Bool()) // Fetch request generated by the IFC
val dec_bp = new dec_bp()
val active_clk = Input(Clock())
val ic_hit_f = Input(Bool())
val exu_flush_final = Input(Bool())
val ifc_fetch_addr_f = Input(UInt(31.W))
val ifc_fetch_req_f = Input(Bool()) // Fetch request generated by the IFC
val dec_bp = new dec_bp()
val dec_tlu_flush_lower_wb = Input(Bool())
val exu_bp = Flipped(new exu_bp())
val dec_fa_error_index = Input(UInt(log2Ceil(BTB_SIZE).W))// Fully associative btb error index
val ifu_bp_hit_taken_f = Output(Bool())
val ifu_bp_btb_target_f = Output(UInt(31.W))
val ifu_bp_inst_mask_f = Output(Bool())
val ifu_bp_fghr_f = Output(UInt(BHT_GHR_SIZE.W))
val ifu_bp_way_f = Output(UInt(2.W))
val ifu_bp_ret_f = Output(UInt(2.W))
val ifu_bp_hist1_f = Output(UInt(2.W))
val ifu_bp_hist0_f = Output(UInt(2.W))
val ifu_bp_pc4_f = Output(UInt(2.W))
val ifu_bp_valid_f = Output(UInt(2.W))
val ifu_bp_poffset_f = Output(UInt(12.W))
val ifu_bp_fa_index_f = Output(Vec(2,UInt(log2Ceil(BTB_SIZE).W)))// predicted branch index (fully associative option)
val scan_mode = Input(Bool())
val exu_bp = Flipped(new exu_bp())
val ifu_bp_hit_taken_f = Output(Bool())
val ifu_bp_btb_target_f = Output(UInt(31.W))
val ifu_bp_inst_mask_f = Output(Bool())
val ifu_bp_fghr_f = Output(UInt(BHT_GHR_SIZE.W))
val ifu_bp_way_f = Output(UInt(2.W))
val ifu_bp_ret_f = Output(UInt(2.W))
val ifu_bp_hist1_f = Output(UInt(2.W))
val ifu_bp_hist0_f = Output(UInt(2.W))
val ifu_bp_pc4_f = Output(UInt(2.W))
val ifu_bp_valid_f = Output(UInt(2.W))
val ifu_bp_poffset_f = Output(UInt(12.W))
val scan_mode = Input(Bool())
})
io.ifu_bp_fa_index_f := io.ifu_bp_fa_index_f.map(i=> 0.U)
val BTB_DWIDTH = BTB_TOFFSET_SIZE+ BTB_BTAG_SIZE + 5
val BTB_DWIDTH_TOP = BTB_TOFFSET_SIZE + BTB_BTAG_SIZE + 4
val BTB_FA_INDEX = log2Ceil(BTB_SIZE) - 1
val FA_CMP_LOWER = log2Ceil(ICACHE_LN_SZ)
val FA_TAG_END_UPPER = 5 + BTB_TOFFSET_SIZE + FA_CMP_LOWER - 1 // must cast to int or vcs build fails
val FA_TAG_START_LOWER =3 + BTB_TOFFSET_SIZE + FA_CMP_LOWER
val FA_TAG_END_LOWER = 5 + BTB_TOFFSET_SIZE
val TAG_START = BTB_DWIDTH - 1
val PC4 = 4 // Branch = pc + 4 (BTB Index)
val BOFF = 3 // Branch offset (BTB Index)
val CALL = 2 // Branch CALL (BTB Index)
val RET = 1 // Branch RET (BTB Index)
val BV = 0 // Branch Valid (BTB Index)
val TAG_START = 16+BTB_BTAG_SIZE
val PC4 = 4 // Branch = pc + 4 (BTB Index)
val BOFF = 3 // Branch offset (BTB Index)
val CALL = 2 // Branch CALL (BTB Index)
val RET = 1 // Branch RET (BTB Index)
val BV = 0 // Branch Valid (BTB Index)
val LRU_SIZE = BTB_ARRAY_DEPTH
val NUM_BHT_LOOP = if(BHT_ARRAY_DEPTH > 16) 16 else BHT_ARRAY_DEPTH
val LRU_SIZE = BTB_ARRAY_DEPTH
val NUM_BHT_LOOP = if(BHT_ARRAY_DEPTH > 16) 16 else BHT_ARRAY_DEPTH
val NUM_BHT_LOOP_INNER_HI = if(BHT_ARRAY_DEPTH > 16) BHT_ADDR_LO+3 else BHT_ADDR_HI
val NUM_BHT_LOOP_OUTER_LO = if(BHT_ARRAY_DEPTH > 16) BHT_ADDR_LO+4 else BHT_ADDR_LO
val BHT_NO_ADDR_MATCH = BHT_ARRAY_DEPTH <= 16
val BHT_NO_ADDR_MATCH = BHT_ARRAY_DEPTH <= 16
/////////////////////////////////////////////////////////
val leak_one_f = WireInit(Bool(), 0.U)
val leak_one_f_d1 = WireInit(Bool(), 0.U)
val bht_dir_f = WireInit(UInt(2.W), 0.U)
val dec_tlu_error_wb = WireInit(Bool(), 0.U)
val leak_one_f = WireInit(Bool(), 0.U)
val bht_dir_f = WireInit(UInt(2.W), 0.U)
val dec_tlu_error_wb = WireInit(Bool(), 0.U)
val btb_error_addr_wb = WireInit(UInt((BTB_ADDR_HI-BTB_ADDR_LO+1).W), 0.U)
val btb_vbank0_rd_data_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
val btb_vbank1_rd_data_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
val btb_bank0_rd_data_way0_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
val btb_bank0_rd_data_way1_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
val btb_bank0_rd_data_way0_p1_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
val btb_bank0_rd_data_way1_p1_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
val eoc_mask = WireInit(Bool(), 0.U)
val btb_lru_b0_f = WireInit(UInt(LRU_SIZE.W), init = 0.U)
val dec_tlu_way_wb = WireInit(Bool(), 0.U)
val btb_vlru_rd_f = WireInit(UInt(2.W), 0.U)
val vwayhit_f = WireInit(UInt(2.W), 0.U)
val tag_match_vway1_expanded_f = WireInit(UInt(2.W), 0.U)
val wayhit_f = WireInit(UInt(2.W), 0.U)
val wayhit_p1_f = WireInit(UInt(2.W), 0.U)
val way_raw = WireInit(UInt(2.W), 0.U)
val exu_flush_final_d1 = WireInit(Bool(), 0.U)
val btb_bank0_rd_data_way0_f = WireInit(UInt((TAG_START+1).W), 0.U)
val btb_bank0_rd_data_way1_f = WireInit(UInt((TAG_START+1).W), 0.U)
val btb_bank0_rd_data_way0_p1_f = WireInit(UInt((TAG_START+1).W), 0.U)
val btb_bank0_rd_data_way1_p1_f = WireInit(UInt((TAG_START+1).W), 0.U)
val eoc_mask = WireInit(Bool(), 0.U)
val btb_lru_b0_f = WireInit(UInt(LRU_SIZE.W), init = 0.U)
val dec_tlu_way_wb = WireInit(Bool(), 0.U)
/////////////////////////////////////////////////////////
// Misprediction packet
val exu_mp_valid = io.exu_bp.exu_mp_pkt.bits.misp & !leak_one_f
@ -89,7 +68,6 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
val exu_mp_tgt = io.exu_bp.exu_mp_pkt.bits.toffset
val exu_mp_addr = io.exu_bp.exu_mp_index
val exu_mp_ataken = io.exu_bp.exu_mp_pkt.bits.ataken
val exu_mp_way_f = WireInit(Bool(), 0.U)
// Its a commit or update packet
val dec_tlu_br0_v_wb = io.dec_bp.dec_tlu_br0_r_pkt.valid
@ -129,132 +107,139 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
val branch_error_bank_conflict_p1_f = branch_error_collision_p1_f & dec_tlu_error_wb
// Hashing the PC to generate the index for the btb
val fetch_rd_tag_f = if(BTB_BTAG_FOLD) btb_tag_hash_fold(io.ifc_fetch_addr_f) else btb_tag_hash(io.ifc_fetch_addr_f)
val fetch_rd_tag_p1_f = if(BTB_BTAG_FOLD) btb_tag_hash_fold(Cat(fetch_addr_p1_f,0.U)) else btb_tag_hash(Cat(fetch_addr_p1_f,0.U))
// There is a misprediction and the exu is writing back
val fetch_mp_collision_f = (io.exu_bp.exu_mp_btag === fetch_rd_tag_f) & exu_mp_valid & io.ifc_fetch_req_f & (exu_mp_addr === btb_rd_addr_f)
val fetch_mp_collision_p1_f = (io.exu_bp.exu_mp_btag === fetch_rd_tag_p1_f) & exu_mp_valid & io.ifc_fetch_req_f & (exu_mp_addr === btb_rd_addr_p1_f)
val leak_one_f_d1 = withClock(io.active_clk) {RegNext(leak_one_f, init = 0.U)}
val dec_tlu_way_wb_f = withClock(io.active_clk) {RegNext(dec_tlu_way_wb, init = 0.U)}
val exu_mp_way_f = withClock(io.active_clk) {RegNext(exu_mp_way, init = 0.U)}
val exu_flush_final_d1 = withClock(io.active_clk) {RegNext(io.exu_flush_final, init = 0.U)}
// If there is a flush from the lower pipe wait until the flush gets deasserted from the (decode) side
leak_one_f := (io.dec_bp.dec_tlu_flush_leak_one_wb & io.dec_tlu_flush_lower_wb) | (leak_one_f_d1 & !io.dec_tlu_flush_lower_wb)
if(!BTB_FULLYA) {
val fetch_rd_tag_f = if (BTB_BTAG_FOLD) btb_tag_hash_fold(io.ifc_fetch_addr_f) else btb_tag_hash(io.ifc_fetch_addr_f)
val fetch_rd_tag_p1_f = if (BTB_BTAG_FOLD) btb_tag_hash_fold(Cat(fetch_addr_p1_f, 0.U)) else btb_tag_hash(Cat(fetch_addr_p1_f, 0.U))
// There is a misprediction and the exu is writing back
val fetch_mp_collision_f = (io.exu_bp.exu_mp_btag === fetch_rd_tag_f) & exu_mp_valid & io.ifc_fetch_req_f & (exu_mp_addr === btb_rd_addr_f)
val fetch_mp_collision_p1_f = (io.exu_bp.exu_mp_btag === fetch_rd_tag_p1_f) & exu_mp_valid & io.ifc_fetch_req_f & (exu_mp_addr === btb_rd_addr_p1_f)
// For a tag to match the branch should be valid tag should match and a fetch request should be generated
// Also there should be no bank conflict or leak-one
val tag_match_way0_f = btb_bank0_rd_data_way0_f(BV) & (btb_bank0_rd_data_way0_f(TAG_START, 17) === fetch_rd_tag_f) &
!(dec_tlu_way_wb & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
// Similar to the way-0 -> way-1
val tag_match_way1_f = btb_bank0_rd_data_way1_f(BV) & (btb_bank0_rd_data_way1_f(TAG_START, 17) === fetch_rd_tag_f) &
!(dec_tlu_way_wb & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
// For a tag to match the branch should be valid tag should match and a fetch request should be generated
// Also there should be no bank conflict or leak-one
val tag_match_way0_f = btb_bank0_rd_data_way0_f(BV) & (btb_bank0_rd_data_way0_f(TAG_START,17) === fetch_rd_tag_f) &
!(dec_tlu_way_wb_f & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
// Similar to above matches
val tag_match_way0_p1_f = btb_bank0_rd_data_way0_p1_f(BV) & (btb_bank0_rd_data_way0_p1_f(TAG_START, 17) === fetch_rd_tag_p1_f) &
!(dec_tlu_way_wb & branch_error_bank_conflict_p1_f) & io.ifc_fetch_req_f & !leak_one_f
// Similar to above matches
val tag_match_way1_p1_f = btb_bank0_rd_data_way1_p1_f(BV) & (btb_bank0_rd_data_way1_p1_f(TAG_START, 17) === fetch_rd_tag_p1_f) &
!(dec_tlu_way_wb & branch_error_bank_conflict_p1_f) & io.ifc_fetch_req_f & !leak_one_f
// Similar to the way-0 -> way-1
val tag_match_way1_f = btb_bank0_rd_data_way1_f(BV) & (btb_bank0_rd_data_way1_f(TAG_START,17) === fetch_rd_tag_f) &
!(dec_tlu_way_wb_f & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
// Reordering to avoid multiple hit
val tag_match_way0_expanded_f = Cat(tag_match_way0_f & (btb_bank0_rd_data_way0_f(BOFF) ^ btb_bank0_rd_data_way0_f(PC4)),
tag_match_way0_f & !(btb_bank0_rd_data_way0_f(BOFF) ^ btb_bank0_rd_data_way0_f(PC4)))
// Similar to above matches
val tag_match_way0_p1_f = btb_bank0_rd_data_way0_p1_f(BV) & (btb_bank0_rd_data_way0_p1_f(TAG_START,17) === fetch_rd_tag_p1_f) &
!(dec_tlu_way_wb_f & branch_error_bank_conflict_p1_f) & io.ifc_fetch_req_f & !leak_one_f
// Similar to above matches
val tag_match_way1_p1_f = btb_bank0_rd_data_way1_p1_f(BV) & (btb_bank0_rd_data_way1_p1_f(TAG_START,17) === fetch_rd_tag_p1_f) &
!(dec_tlu_way_wb_f & branch_error_bank_conflict_p1_f) & io.ifc_fetch_req_f & !leak_one_f
val tag_match_way1_expanded_f = Cat(tag_match_way1_f & (btb_bank0_rd_data_way1_f(BOFF) ^ btb_bank0_rd_data_way1_f(PC4)),
tag_match_way1_f & !(btb_bank0_rd_data_way1_f(BOFF) ^ btb_bank0_rd_data_way1_f(PC4)))
// Reordering to avoid multiple hit
val tag_match_way0_expanded_f = Cat(tag_match_way0_f & (btb_bank0_rd_data_way0_f(BOFF) ^ btb_bank0_rd_data_way0_f(PC4)),
tag_match_way0_f & !(btb_bank0_rd_data_way0_f(BOFF) ^ btb_bank0_rd_data_way0_f(PC4)))
val tag_match_way0_expanded_p1_f = Cat(tag_match_way0_p1_f & (btb_bank0_rd_data_way0_p1_f(BOFF) ^ btb_bank0_rd_data_way0_p1_f(PC4)),
tag_match_way0_p1_f & !(btb_bank0_rd_data_way0_p1_f(BOFF) ^ btb_bank0_rd_data_way0_p1_f(PC4)))
val tag_match_way1_expanded_f = Cat(tag_match_way1_f & (btb_bank0_rd_data_way1_f(BOFF) ^ btb_bank0_rd_data_way1_f(PC4)),
tag_match_way1_f & !(btb_bank0_rd_data_way1_f(BOFF) ^ btb_bank0_rd_data_way1_f(PC4)))
val tag_match_way1_expanded_p1_f = Cat(tag_match_way1_p1_f & (btb_bank0_rd_data_way1_p1_f(BOFF) ^ btb_bank0_rd_data_way1_p1_f(PC4)),
tag_match_way1_p1_f & !(btb_bank0_rd_data_way1_p1_f(BOFF) ^ btb_bank0_rd_data_way1_p1_f(PC4)))
val tag_match_way0_expanded_p1_f = Cat(tag_match_way0_p1_f & (btb_bank0_rd_data_way0_p1_f(BOFF) ^ btb_bank0_rd_data_way0_p1_f(PC4)),
tag_match_way0_p1_f & !(btb_bank0_rd_data_way0_p1_f(BOFF) ^ btb_bank0_rd_data_way0_p1_f(PC4)))
// Final hit calculation
wayhit_f := tag_match_way0_expanded_f | tag_match_way1_expanded_f
val tag_match_way1_expanded_p1_f = Cat(tag_match_way1_p1_f & (btb_bank0_rd_data_way1_p1_f(BOFF) ^ btb_bank0_rd_data_way1_p1_f(PC4)),
tag_match_way1_p1_f & !(btb_bank0_rd_data_way1_p1_f(BOFF) ^ btb_bank0_rd_data_way1_p1_f(PC4)))
wayhit_p1_f := tag_match_way0_expanded_p1_f | tag_match_way1_expanded_p1_f
// Final hit calculation
val wayhit_f = tag_match_way0_expanded_f | tag_match_way1_expanded_f
// Chopping off the ways that had a hit btb_vbank0_rd_data_f
// e-> Lower half o-> Upper half
val btb_bank0e_rd_data_f = Mux1H(Seq(tag_match_way0_expanded_f(0).asBool -> btb_bank0_rd_data_way0_f,
tag_match_way1_expanded_f(0).asBool -> btb_bank0_rd_data_way1_f))
val wayhit_p1_f = tag_match_way0_expanded_p1_f | tag_match_way1_expanded_p1_f
val btb_bank0o_rd_data_f = Mux1H(Seq(tag_match_way0_expanded_f(1).asBool -> btb_bank0_rd_data_way0_f,
tag_match_way1_expanded_f(1).asBool -> btb_bank0_rd_data_way1_f))
// Chopping off the ways that had a hit btb_vbank0_rd_data_f
// e-> Lower half o-> Upper half
val btb_bank0e_rd_data_f = Mux1H(Seq(tag_match_way0_expanded_f(0).asBool->btb_bank0_rd_data_way0_f,
tag_match_way1_expanded_f(0).asBool->btb_bank0_rd_data_way1_f))
val btb_bank0e_rd_data_p1_f = Mux1H(Seq(tag_match_way0_expanded_p1_f(0).asBool -> btb_bank0_rd_data_way0_p1_f,
tag_match_way1_expanded_p1_f(0).asBool -> btb_bank0_rd_data_way1_p1_f))
val btb_bank0o_rd_data_f = Mux1H(Seq(tag_match_way0_expanded_f(1).asBool->btb_bank0_rd_data_way0_f,
tag_match_way1_expanded_f(1).asBool->btb_bank0_rd_data_way1_f))
// Making virtual banks, made from pc-bit(1) if it comes from a multiple of 4 we get the lower half of the bank
// and the upper half of the bank-0 in vbank 1
btb_vbank0_rd_data_f := Mux1H(Seq(!io.ifc_fetch_addr_f(0) -> btb_bank0e_rd_data_f,
io.ifc_fetch_addr_f(0) -> btb_bank0o_rd_data_f))
btb_vbank1_rd_data_f := Mux1H(Seq(!io.ifc_fetch_addr_f(0) -> btb_bank0o_rd_data_f,
io.ifc_fetch_addr_f(0) -> btb_bank0e_rd_data_p1_f))
val btb_bank0e_rd_data_p1_f = Mux1H(Seq(tag_match_way0_expanded_p1_f(0).asBool->btb_bank0_rd_data_way0_p1_f,
tag_match_way1_expanded_p1_f(0).asBool->btb_bank0_rd_data_way1_p1_f))
way_raw := tag_match_vway1_expanded_f | (~vwayhit_f & btb_vlru_rd_f)
// Making virtual banks, made from pc-bit(1) if it comes from a multiple of 4 we get the lower half of the bank
// and the upper half of the bank-0 in vbank 1
val btb_vbank0_rd_data_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0)->btb_bank0e_rd_data_f,
io.ifc_fetch_addr_f(0)->btb_bank0o_rd_data_f))
val btb_vbank1_rd_data_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0)->btb_bank0o_rd_data_f,
io.ifc_fetch_addr_f(0)->btb_bank0e_rd_data_p1_f))
// Branch prediction info is sent with the 2byte lane associated with the end of the branch.
// Cases
// BANK1 BANK0
// -------------------------------
// | : | : |
// -------------------------------
// <------------> : PC4 branch, offset, should be in B1 (indicated on [2])
// <------------> : PC4 branch, no offset, indicate PC4, VALID, HIST on [1]
// <------------> : PC4 branch, offset, indicate PC4, VALID, HIST on [0]
// <------> : PC2 branch, offset, indicate VALID, HIST on [1]
// <------> : PC2 branch, no offset, indicate VALID, HIST on [0]
// Branch prediction info is sent with the 2byte lane associated with the end of the branch.
// Cases
// BANK1 BANK0
// -------------------------------
// | : | : |
// -------------------------------
// <------------> : PC4 branch, offset, should be in B1 (indicated on [2])
// <------------> : PC4 branch, no offset, indicate PC4, VALID, HIST on [1]
// <------------> : PC4 branch, offset, indicate PC4, VALID, HIST on [0]
// <------> : PC2 branch, offset, indicate VALID, HIST on [1]
// <------> : PC2 branch, no offset, indicate VALID, HIST on [0]
// Make an LRU value with execution mis-prediction
val mp_wrindex_dec = 1.U << exu_mp_addr
// Make an LRU value with execution mis-prediction
val mp_wrindex_dec = 1.U << exu_mp_addr
// Make an LRU value with current read pc
val fetch_wrindex_dec = 1.U << btb_rd_addr_f
// Make an LRU value with current read pc
val fetch_wrindex_dec = 1.U << btb_rd_addr_f
// Make an LRU value with current read pc + 4
val fetch_wrindex_p1_dec = 1.U << btb_rd_addr_p1_f
// Make an LRU value with current read pc + 4
val fetch_wrindex_p1_dec = 1.U << btb_rd_addr_p1_f
// Checking if the mis-prediction was valid or not and make a new LRU value
val mp_wrlru_b0 = mp_wrindex_dec & Fill(LRU_SIZE, exu_mp_valid)
// Checking if the mis-prediction was valid or not and make a new LRU value
val mp_wrlru_b0 = mp_wrindex_dec & Fill(LRU_SIZE, exu_mp_valid)
// Is the update of the lru valid or not
val lru_update_valid_f = (vwayhit_f(0) | vwayhit_f(1)) & io.ifc_fetch_req_f & !leak_one_f
val vwayhit_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool->wayhit_f,
io.ifc_fetch_addr_f(0).asBool->Cat(wayhit_p1_f(0), wayhit_f(1)))) & Cat(eoc_mask, 1.U(1.W))
val fetch_wrlru_b0 = fetch_wrindex_dec & Fill(LRU_SIZE, lru_update_valid_f)
val fetch_wrlru_p1_b0 = fetch_wrindex_p1_dec & Fill(LRU_SIZE, lru_update_valid_f)
// Is the update of the lru valid or not
val lru_update_valid_f = (vwayhit_f(0) | vwayhit_f(1)) & io.ifc_fetch_req_f & !leak_one_f
val btb_lru_b0_hold = ~mp_wrlru_b0 & ~fetch_wrlru_b0
val fetch_wrlru_b0 = fetch_wrindex_dec & Fill(LRU_SIZE, lru_update_valid_f)
val fetch_wrlru_p1_b0 = fetch_wrindex_p1_dec & Fill(LRU_SIZE, lru_update_valid_f)
// If there is a collision the use the mis-predicted value as output and update accordingly
val use_mp_way = fetch_mp_collision_f
val use_mp_way_p1 = fetch_mp_collision_p1_f
val btb_lru_b0_hold = ~mp_wrlru_b0 & ~fetch_wrlru_b0
// Calculate the lru next value and flop it
val btb_lru_b0_ns: UInt = Mux1H(Seq(!exu_mp_way.asBool -> mp_wrlru_b0,
tag_match_way0_f.asBool -> fetch_wrlru_b0,
tag_match_way0_p1_f.asBool -> fetch_wrlru_p1_b0)) | btb_lru_b0_hold & btb_lru_b0_f
// If there is a collision the use the mis-predicted value as output and update accordingly
val use_mp_way = fetch_mp_collision_f
val use_mp_way_p1 = fetch_mp_collision_p1_f
// Calculate the lru next value and flop it
val btb_lru_b0_ns : UInt = Mux1H(Seq(!exu_mp_way.asBool -> mp_wrlru_b0,
tag_match_way0_f.asBool -> fetch_wrlru_b0,
tag_match_way0_p1_f.asBool -> fetch_wrlru_p1_b0)) | btb_lru_b0_hold & btb_lru_b0_f
val btb_lru_rd_f = Mux(use_mp_way.asBool, exu_mp_way_f, (fetch_wrindex_dec & btb_lru_b0_f).orR)
val btb_lru_rd_f = Mux(use_mp_way.asBool, exu_mp_way_f, (fetch_wrindex_dec & btb_lru_b0_f).orR)
val btb_lru_rd_p1_f = Mux(use_mp_way_p1.asBool, exu_mp_way_f, (fetch_wrindex_p1_dec & btb_lru_b0_f).orR)
val btb_lru_rd_p1_f = Mux(use_mp_way_p1.asBool, exu_mp_way_f, (fetch_wrindex_p1_dec & btb_lru_b0_f).orR)
// Similar to the vbank make vlru
btb_vlru_rd_f := Mux1H(Seq(!io.ifc_fetch_addr_f(0) -> Cat(btb_lru_rd_f, btb_lru_rd_f),
io.ifc_fetch_addr_f(0).asBool -> Cat(btb_lru_rd_p1_f, btb_lru_rd_f)))
// Similar to the vbank make vlru
val btb_vlru_rd_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0) -> Cat(btb_lru_rd_f, btb_lru_rd_f),
io.ifc_fetch_addr_f(0).asBool -> Cat(btb_lru_rd_p1_f, btb_lru_rd_f)))
// virtual way depending on pc value
tag_match_vway1_expanded_f := Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool -> tag_match_way1_expanded_f,
io.ifc_fetch_addr_f(0).asBool -> Cat(tag_match_way1_expanded_p1_f(0), tag_match_way1_expanded_f(1))))
// virtual way depending on pc value
val tag_match_vway1_expanded_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool->tag_match_way1_expanded_f,
io.ifc_fetch_addr_f(0).asBool->Cat(tag_match_way1_expanded_p1_f(0),tag_match_way1_expanded_f(1))))
btb_lru_b0_f := rvdffe(btb_lru_b0_ns, (io.ifc_fetch_req_f|exu_mp_valid).asBool, clock, io.scan_mode)
}
io.ifu_bp_way_f := tag_match_vway1_expanded_f | (~vwayhit_f & btb_vlru_rd_f)
io.ifu_bp_way_f := way_raw
// update the lru
//io.test := btb_lru_b0_ns
btb_lru_b0_f := rvdffe(btb_lru_b0_ns, (io.ifc_fetch_req_f|exu_mp_valid).asBool, clock, io.scan_mode)
//io.test := btb_lru_b0_ns
// Checking if the end of line is near
val eoc_near = io.ifc_fetch_addr_f(ICACHE_BEAT_ADDR_HI-1, 2).andR
// Mask according to eoc-near and make the hit-final
eoc_mask := !eoc_near | (~io.ifc_fetch_addr_f(1,0)).orR()
@ -270,32 +255,31 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
// This is 1-index shifted to that of the btb-data-read so we have 1-bit shifted
btb_sel_data_f := Mux1H(Seq(btb_sel_f(1).asBool-> btb_vbank1_rd_data_f(16,1),
btb_sel_f(0).asBool-> btb_vbank0_rd_data_f(16,1)))
btb_sel_f(0).asBool-> btb_vbank0_rd_data_f(16,1)))
// No lower flush or bp-disabple and a fetch request is generated with virtual way hit
io.ifu_bp_hit_taken_f := (vwayhit_f & hist1_raw).orR & io.ifc_fetch_req_f & !leak_one_f_d1 & !io.dec_bp.dec_tlu_bpred_disable
// If the prediction is a call or ret btb entry then do not check the bht just force a taken with data from the RAS
val bht_force_taken_f = Cat( btb_vbank1_rd_data_f(CALL) | btb_vbank1_rd_data_f(RET) ,
btb_vbank0_rd_data_f(CALL) | btb_vbank0_rd_data_f(RET))
btb_vbank0_rd_data_f(CALL) | btb_vbank0_rd_data_f(RET))
val bht_valid_f = vwayhit_f
val bht_bank1_rd_data_f =WireInit(UInt(2.W), 0.U)
val bht_bank0_rd_data_f =WireInit(UInt(2.W), 0.U)
val bht_bank0_rd_data_p1_f =WireInit(UInt(2.W), 0.U)
// Depending on pc make the virtual bank as commented above
val bht_vbank0_rd_data_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool->bht_bank0_rd_data_f,
io.ifc_fetch_addr_f(0).asBool->bht_bank1_rd_data_f))
io.ifc_fetch_addr_f(0).asBool->bht_bank1_rd_data_f))
val bht_vbank1_rd_data_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool->bht_bank1_rd_data_f,
io.ifc_fetch_addr_f(0).asBool->bht_bank0_rd_data_p1_f))
io.ifc_fetch_addr_f(0).asBool->bht_bank0_rd_data_p1_f))
// Direction containing data of both banks direction
bht_dir_f := Cat((bht_force_taken_f(1) | bht_vbank1_rd_data_f(1)) & bht_valid_f(1),
(bht_force_taken_f(0) | bht_vbank0_rd_data_f(1)) & bht_valid_f(0))
(bht_force_taken_f(0) | bht_vbank0_rd_data_f(1)) & bht_valid_f(0))
// If the branch is taken then pass btb sel else 0
io.ifu_bp_inst_mask_f := (io.ifu_bp_hit_taken_f & btb_sel_f(1)) | !io.ifu_bp_hit_taken_f
@ -308,11 +292,11 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
// pc4: if the branch is pc+4
val pc4_raw = Cat(vwayhit_f(1) & btb_vbank1_rd_data_f(PC4),
vwayhit_f(0) & btb_vbank0_rd_data_f(PC4))
vwayhit_f(0) & btb_vbank0_rd_data_f(PC4))
// Its a call call or ret branch
val pret_raw = Cat(vwayhit_f(1) & !btb_vbank1_rd_data_f(CALL) & btb_vbank1_rd_data_f(RET),
vwayhit_f(0) & !btb_vbank0_rd_data_f(CALL) & btb_vbank0_rd_data_f(RET))
vwayhit_f(0) & !btb_vbank0_rd_data_f(CALL) & btb_vbank0_rd_data_f(RET))
// count number of 1's in bht_valid
val num_valids = bht_valid_f(1) +& bht_valid_f(0)
@ -323,8 +307,8 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
val fghr = WireInit(UInt(BHT_GHR_SIZE.W), 0.U)
val merged_ghr = Mux1H(Seq((num_valids===2.U).asBool->Cat(fghr(BHT_GHR_SIZE-3,0), 0.U, final_h),
(num_valids===1.U).asBool->Cat(fghr(BHT_GHR_SIZE-2,0), final_h),
(num_valids===0.U).asBool->Cat(fghr(BHT_GHR_SIZE-1,0))))
(num_valids===1.U).asBool->Cat(fghr(BHT_GHR_SIZE-2,0), final_h),
(num_valids===0.U).asBool->Cat(fghr(BHT_GHR_SIZE-1,0))))
val exu_flush_ghr = io.exu_bp.exu_mp_fghr
val fghr_ns = Wire(UInt(BHT_GHR_SIZE.W))
@ -333,13 +317,10 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
// If there is a hit and a fetch then use the merged-ghr
// If there is no hit or fetch then hold value
fghr_ns := Mux1H(Seq(exu_flush_final_d1.asBool->exu_flush_ghr,
(!exu_flush_final_d1 & io.ifc_fetch_req_f & io.ic_hit_f & !leak_one_f_d1).asBool -> merged_ghr,
(!exu_flush_final_d1 & !(io.ifc_fetch_req_f & io.ic_hit_f & !leak_one_f_d1)).asBool -> fghr))
leak_one_f_d1 := rvdffie(leak_one_f,clock,reset.asAsyncReset(),io.scan_mode)
//val dec_tlu_way_wb_f = withClock(io.active_clk) {RegNext(dec_tlu_way_wb, init = 0.U)
exu_mp_way_f := rvdffie(exu_mp_way,clock,reset.asAsyncReset(),io.scan_mode)
exu_flush_final_d1 := rvdffie(io.exu_flush_final,clock,reset.asAsyncReset(),io.scan_mode)
fghr := rvdffie(fghr_ns,clock,reset.asAsyncReset(),io.scan_mode)
(!exu_flush_final_d1 & io.ifc_fetch_req_f & io.ic_hit_f & !leak_one_f_d1).asBool -> merged_ghr,
(!exu_flush_final_d1 & !(io.ifc_fetch_req_f & io.ic_hit_f & !leak_one_f_d1)).asBool -> fghr))
fghr := withClock(io.active_clk) {RegNext(fghr_ns, init = 0.U)}
io.ifu_bp_fghr_f := fghr
io.ifu_bp_hist1_f := hist1_raw
@ -351,27 +332,31 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
// block fetch to calculate if there is a hit with fetch request and a taken branch then compute the branch offset
val bloc_f = Cat((bht_dir_f(0) & !fetch_start_f(0)) | (!bht_dir_f(0) & fetch_start_f(0)),
(bht_dir_f(0) & fetch_start_f(0)) | (!bht_dir_f(0) & !fetch_start_f(0)))
(bht_dir_f(0) & fetch_start_f(0)) | (!bht_dir_f(0) & !fetch_start_f(0)))
val use_fa_plus = !bht_dir_f(0) & io.ifc_fetch_addr_f(0) & !btb_rd_pc4_f
val btb_fg_crossing_f = fetch_start_f(0) & btb_sel_f(0) & btb_rd_pc4_f
val bp_total_branch_offset_f = bloc_f(1)^btb_rd_pc4_f
val ifc_fetch_adder_prior = rvdfflie_UInt(io.ifc_fetch_addr_f(30,1), clock,reset.asAsyncReset,(io.ifc_fetch_req_f & !io.ifu_bp_hit_taken_f & io.ic_hit_f).asBool,io.scan_mode,WIDTH =30, LEFT =19 )
val ifc_fetch_adder_prior = rvdffe(io.ifc_fetch_addr_f(30,1), (io.ifc_fetch_req_f & !io.ifu_bp_hit_taken_f & io.ic_hit_f).asBool, clock, io.scan_mode)
io.ifu_bp_poffset_f := btb_rd_tgt_f
val adder_pc_in_f = Mux1H(Seq(use_fa_plus.asBool -> fetch_addr_p1_f,
btb_fg_crossing_f.asBool -> ifc_fetch_adder_prior,
(!btb_fg_crossing_f & !use_fa_plus).asBool-> io.ifc_fetch_addr_f(30,1)))
btb_fg_crossing_f.asBool -> ifc_fetch_adder_prior,
(!btb_fg_crossing_f & !use_fa_plus).asBool-> io.ifc_fetch_addr_f(30,1)))
// Calculate the branch target by adding the offset
val bp_btb_target_adder_f = rvbradder(Cat(adder_pc_in_f(29,0),bp_total_branch_offset_f, 0.U), Cat(btb_rd_tgt_f,0.U))
val rets_out = Wire(Vec(RET_STACK_SIZE, UInt(32.W)))
rets_out := (0 until RET_STACK_SIZE).map(i=>0.U)
// Final target if its a RET then pop else take the target pc
io.ifu_bp_btb_target_f := ((Fill(31,(btb_rd_ret_f & !btb_rd_call_f & rets_out(0)(0) & io.ifu_bp_hit_taken_f)) & rets_out(0)(31,1)) |
(Fill(31,(!(btb_rd_ret_f & !btb_rd_call_f & rets_out(0)(0)) & io.ifu_bp_hit_taken_f)) & bp_btb_target_adder_f(31,1)))
io.ifu_bp_btb_target_f := Mux((btb_rd_ret_f & !btb_rd_call_f & rets_out(0)(0)).asBool,
rets_out(0)(31,1),bp_btb_target_adder_f(31,1))
// Return stack
val bp_rs_call_target_f = rvbradder(Cat(adder_pc_in_f(29,0),bp_total_branch_offset_f, 0.U), Cat(Fill(11, 0.U),~btb_rd_pc4_f, 0.U))
@ -380,13 +365,14 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
val rs_hold = !rs_push & !rs_pop
val rsenable = (0 until RET_STACK_SIZE).map(i=> if(i==0) !rs_hold else if(i==RET_STACK_SIZE-1) rs_push else rs_push | rs_pop)
// Make the input of the RAS
val rets_in = (0 until RET_STACK_SIZE).map(i=> if(i==0)
Mux1H(Seq(rs_push.asBool -> Cat(bp_rs_call_target_f(31,1),1.U),
rs_pop.asBool -> rets_out(1)))
else if(i==RET_STACK_SIZE-1) rets_out(i-1)
else Mux1H(Seq(rs_push.asBool->rets_out(i-1),
rs_pop.asBool ->rets_out(i+1))))
rs_pop.asBool -> rets_out(1)))
else if(i==RET_STACK_SIZE-1) rets_out(i-1)
else Mux1H(Seq(rs_push.asBool->rets_out(i-1),
rs_pop.asBool ->rets_out(i+1))))
// Make flops for poping the data
rets_out := (0 until RET_STACK_SIZE).map(i=>rvdffe(rets_in(i), rsenable(i).asBool, clock, io.scan_mode))
@ -396,7 +382,14 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
// Making the data to write into the BTB according the structure discribed above
val btb_wr_data = Cat(btb_wr_tag, exu_mp_tgt, exu_mp_pc4, exu_mp_boffset, exu_mp_call | exu_mp_ja, exu_mp_ret | exu_mp_ja, btb_valid)
val exu_mp_valid_write = exu_mp_valid & exu_mp_ataken & !io.exu_bp.exu_mp_pkt.valid
val exu_mp_valid_write = exu_mp_valid & exu_mp_ataken
// Enable for write on each way
val btb_wr_en_way0 = ((!exu_mp_way) & exu_mp_valid_write & (!dec_tlu_error_wb)) | ((!dec_tlu_way_wb) & dec_tlu_error_wb)
val btb_wr_en_way1 = (exu_mp_way & exu_mp_valid_write & (!dec_tlu_error_wb)) | (dec_tlu_way_wb & dec_tlu_error_wb)
// Writing is always done from dec or exu check if the dec have a valid data
val btb_wr_addr = Mux(dec_tlu_error_wb.asBool , btb_error_addr_wb, exu_mp_addr)
val middle_of_bank = exu_mp_pc4 ^ exu_mp_boffset
// Enable the clk enable according to the exu misprediction where it is not a RAS
@ -415,121 +408,50 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
val bht_wr_addr2 = br0_hashed_wb
val bht_rd_addr_f = bht_rd_addr_hashed_f
val bht_rd_addr_p1_f = bht_rd_addr_hashed_p1_f
val btb_bank0_rd_data_way0_out = Wire(Vec(LRU_SIZE,UInt(BTB_DWIDTH.W)))
val btb_bank0_rd_data_way1_out = Wire(Vec(LRU_SIZE,UInt(BTB_DWIDTH.W)))
// BTB
// Entry -> Tag[BTB-BTAG-SIZE], toffset[12], pc4, boffset, call, ret, valid
if(!BTB_FULLYA) {
// Enable for write on each way
val btb_wr_en_way0 = ((!exu_mp_way) & exu_mp_valid_write & (!dec_tlu_error_wb)) | ((!dec_tlu_way_wb) & dec_tlu_error_wb)
val btb_wr_en_way1 = (exu_mp_way & exu_mp_valid_write & (!dec_tlu_error_wb)) | (dec_tlu_way_wb & dec_tlu_error_wb)
// Writing is always done from dec or exu check if the dec have a valid data
val btb_wr_addr = Mux(dec_tlu_error_wb.asBool, btb_error_addr_wb, exu_mp_addr)
val btb_bank0_rd_data_way0_out = (0 until LRU_SIZE).map(i=>rvdffe(btb_wr_data, ((btb_wr_addr===i.U) & btb_wr_en_way0).asBool, clock, io.scan_mode))
val btb_bank0_rd_data_way1_out = (0 until LRU_SIZE).map(i=>rvdffe(btb_wr_data, ((btb_wr_addr===i.U) & btb_wr_en_way1).asBool, clock, io.scan_mode))
vwayhit_f := Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool->wayhit_f,
io.ifc_fetch_addr_f(0).asBool->Cat(wayhit_p1_f(0), wayhit_f(1)))) & Cat(eoc_mask, 1.U(1.W))
btb_bank0_rd_data_way0_f := Mux1H((0 until LRU_SIZE).map(i=>(btb_rd_addr_f===i.U).asBool->btb_bank0_rd_data_way0_out(i)))
btb_bank0_rd_data_way1_f := Mux1H((0 until LRU_SIZE).map(i=>(btb_rd_addr_f===i.U).asBool->btb_bank0_rd_data_way1_out(i)))
btb_bank0_rd_data_way0_out := (0 until LRU_SIZE).map(i => rvdffe(btb_wr_data, ((btb_wr_addr === i.U) & btb_wr_en_way0).asBool, clock, io.scan_mode))
btb_bank0_rd_data_way1_out := (0 until LRU_SIZE).map(i => rvdffe(btb_wr_data, ((btb_wr_addr === i.U) & btb_wr_en_way1).asBool, clock, io.scan_mode))
btb_bank0_rd_data_way0_f := Mux1H((0 until LRU_SIZE).map(i => (btb_rd_addr_f === i.U).asBool -> btb_bank0_rd_data_way0_out(i)))
btb_bank0_rd_data_way1_f := Mux1H((0 until LRU_SIZE).map(i => (btb_rd_addr_f === i.U).asBool -> btb_bank0_rd_data_way1_out(i)))
// BTB read muxing
btb_bank0_rd_data_way0_p1_f := Mux1H((0 until LRU_SIZE).map(i => (btb_rd_addr_p1_f === i.U).asBool -> btb_bank0_rd_data_way0_out(i)))
btb_bank0_rd_data_way1_p1_f := Mux1H((0 until LRU_SIZE).map(i => (btb_rd_addr_p1_f === i.U).asBool -> btb_bank0_rd_data_way1_out(i)))
}
// if(BTB_FULLYA){
// val fetch_mp_collision_f = WireInit(Bool(),init = false.B)
// val fetch_mp_collision_p1_f = WireInit(Bool() ,init = false.B)
//
// // Fully Associative tag hash uses bits 31:3. Bits 2:1 are the offset bits used for the 4 tag comp banks
// // Full tag used to speed up lookup. There is one 31:3 cmp per entry, and 4 2:1 cmps per entry.
// val ifc_fetch_addr_p1_f = io.ifc_fetch_addr_f(FA_CMP_LOWER-1,1) + 1.U
//
//
// // val fetch_mp_collision_f = ((io.exu_bp.exu_mp_btag(BTB_BTAG_SIZE-1,0) === io.ifc_fetch_addr_f) & exu_mp_valid & io.ifc_fetch_req_f & ~io.exu_bp.exu_mp_pkt.bits.way)
// // val fetch_mp_collision_p1_f = ( (io.exu_bp.exu_mp_btag(BTB_BTAG_SIZE-1,0) === Cat(io.ifc_fetch_addr_f(30,FA_CMP_LOWER), ifc_fetch_addr_p1_f(FA_CMP_LOWER-1,1))) & exu_mp_valid & io.ifc_fetch_req_f & ~io.exu_bp.exu_mp_pkt.bits.way)
// // val btb_upper_hit = Wire(Vec(BTB_SIZE,Bool()))
// val btb_offset_0 = WireInit(UInt(BTB_SIZE.W) ,init = 0.U)
// val btb_used = WireInit(UInt(BTB_SIZE.W) ,init = 0.U)
// val btb_offset_1 = WireInit(UInt(BTB_SIZE.W) ,init = 0.U)
// val wr0_en = WireInit(UInt(BTB_SIZE.W) ,init = 0.U)
// val btbdata = Wire(Vec(BTB_SIZE,UInt(BTB_DWIDTH.W)))
// btbdata := btbdata.map(i=> 0.U)
// val hit0 = WireInit(UInt(1.W) ,init = 0.U)
// val hit1 = WireInit(UInt(1.W) ,init = 0.U)
//
// // btb_upper_hit := (0 until BTB_SIZE).map(i=> ((btbdata(i)(BTB_DWIDTH_TOP,FA_TAG_END_UPPER) === io.ifc_fetch_addr_f(30,FA_CMP_LOWER)) & btbdata(i)(0) & ~wr0_en(i)))
// // val btb_offset_0 = (0 until BTB_SIZE).map(i=> (btbdata(i)(FA_TAG_START_LOWER,FA_TAG_END_LOWER) === io.ifc_fetch_addr_f(FA_CMP_LOWER-1,1)) & btb_upper_hit(i))
// // val btb_offset_1 = (0 until BTB_SIZE).map(i=> (btbdata(i)(FA_TAG_START_LOWER,FA_TAG_END_LOWER) === ifc_fetch_addr_p1_f(FA_CMP_LOWER-1,1)) & btb_upper_hit(i))
//
// // hit unless we are also writing this entry at the same time
// val hit0_index = MuxCase(1.U, (0 until BTB_SIZE).map(i=> btb_offset_0(i) -> i.U))
// val hit1_index = MuxCase(1.U, (0 until BTB_SIZE).map(i=> btb_offset_1(i) -> i.U))
// // Mux out the 2 potential branches
// btb_vbank0_rd_data_f := (0 until BTB_SIZE ).map(i=> if(btb_offset_1(i) == 1) Mux(fetch_mp_collision_f,btb_wr_data,btbdata(i)) else 0.U ).reverse.reduce(Cat(_,_))
// btb_vbank1_rd_data_f :=(0 until BTB_SIZE).map(i=> if(btb_offset_1(i) == 1) Mux(fetch_mp_collision_p1_f,btb_wr_data,btbdata(i)) else 0.U).reverse.reduce(Cat(_,_))
// val btb_fa_wr_addr0 = MuxCase(1.U, (0 until BTB_SIZE).map(i=> !btb_used(i) -> i.U))
//
// vwayhit_f := Cat(hit1,hit0) & Cat(eoc_mask,1.U)
// way_raw := vwayhit_f | Cat(fetch_mp_collision_p1_f, fetch_mp_collision_f)
// wr0_en := (0 until BTB_SIZE).map(i=> ((btb_fa_wr_addr0(BTB_FA_INDEX,0) === i.asUInt()) & (exu_mp_valid_write & ~io.exu_bp.exu_mp_pkt.bits.way)) |
// ((io.dec_fa_error_index === i.asUInt()) & dec_tlu_error_wb)).reverse.reduce(Cat(_,_))
// btbdata := (0 until BTB_SIZE).map(i=> rvdffe(btb_wr_data,wr0_en(i),clock,io.scan_mode))
//
// io.ifu_bp_fa_index_f(1) := Mux(hit1,hit1_index,0.U)
// io.ifu_bp_fa_index_f(0) := Mux(hit0,hit0_index,0.U)
//
// val btb_used_reset = btb_used.andR()
// val btb_used_ns = Mux1H(Seq(
// vwayhit_f(1).asBool -> (1.U(32.W) << hit1_index(BTB_FA_INDEX,0)),
// vwayhit_f(0).asBool() -> (1.U(32.W) << hit0_index(BTB_FA_INDEX,0)),
// (exu_mp_valid_write & !io.exu_bp.exu_mp_pkt.bits.way & !dec_tlu_error_wb).asBool() -> (1.U(32.W) << btb_fa_wr_addr0(BTB_FA_INDEX,0)),
// btb_used_reset.asBool -> Fill(BTB_SIZE,0.U),
// (!btb_used_reset & dec_tlu_error_wb ).asBool -> (btb_used & ~(1.U(32.W) << io.dec_fa_error_index(BTB_FA_INDEX,0))),
// !(btb_used_reset | dec_tlu_error_wb ).asBool() -> btb_used
// ))
// val write_used = btb_used_reset | io.ifu_bp_hit_taken_f | exu_mp_valid_write | dec_tlu_error_wb
// btb_used := rvdffe(btb_used_ns,write_used.asBool(),clock,io.scan_mode)
// }
// BTB read muxing
btb_bank0_rd_data_way0_p1_f := Mux1H((0 until LRU_SIZE).map(i=>(btb_rd_addr_p1_f===i.U).asBool->btb_bank0_rd_data_way0_out(i)))
btb_bank0_rd_data_way1_p1_f := Mux1H((0 until LRU_SIZE).map(i=>(btb_rd_addr_p1_f===i.U).asBool->btb_bank0_rd_data_way1_out(i)))
val bht_bank_clken = Wire(Vec(2, Vec(BHT_ARRAY_DEPTH/NUM_BHT_LOOP, Bool())))
val bht_bank_clk = Wire(Vec(2, Vec(BHT_ARRAY_DEPTH/NUM_BHT_LOOP, Clock())))
if(RV_FPGA_OPTIMIZE) {
for(i<-0 until 2; k<- 0 until (BHT_ARRAY_DEPTH/NUM_BHT_LOOP)) bht_bank_clk(i)(k) := rvclkhdr(clock, bht_bank_clken(i)(k), io.scan_mode)
// (0 until 2).map(i=>(0 until (BHT_ARRAY_DEPTH/NUM_BHT_LOOP)).map(k=>rvclkhdr(clock, bht_bank_clken(i)(k), io.scan_mode)))
}
val bht_bank_clk = (0 until 2).map(i=>(0 until (BHT_ARRAY_DEPTH/NUM_BHT_LOOP)).map(k=>rvclkhdr(clock, bht_bank_clken(i)(k), io.scan_mode)))
for(i<-0 until 2; k<- 0 until (BHT_ARRAY_DEPTH/NUM_BHT_LOOP)){
// Checking if there is a write enable with address for the BHT
// Checking if there is a write enable with address for the BHT
bht_bank_clken(i)(k) := (bht_wr_en0(i) & ((bht_wr_addr0(BHT_ADDR_HI-BHT_ADDR_LO,NUM_BHT_LOOP_OUTER_LO-2)===k.U) | BHT_NO_ADDR_MATCH.B)) |
(bht_wr_en2(i) & ((bht_wr_addr2(BHT_ADDR_HI-BHT_ADDR_LO,NUM_BHT_LOOP_OUTER_LO-2)===k.U) | BHT_NO_ADDR_MATCH.B))
(bht_wr_en2(i) & ((bht_wr_addr2(BHT_ADDR_HI-BHT_ADDR_LO,NUM_BHT_LOOP_OUTER_LO-2)===k.U) | BHT_NO_ADDR_MATCH.B))
}
// Writing data into the BHT (DEC-side) or (EXU-side)
val bht_bank_wr_data = (0 until 2).map(i=>(0 until BHT_ARRAY_DEPTH/NUM_BHT_LOOP).map(k=>(0 until NUM_BHT_LOOP).map(j=>
Mux((bht_wr_en2(i)&(bht_wr_addr2(NUM_BHT_LOOP_INNER_HI-BHT_ADDR_LO,0)===j.U)&((bht_wr_addr2(BHT_ADDR_HI-BHT_ADDR_LO,NUM_BHT_LOOP_OUTER_LO-BHT_ADDR_LO)===k.U)|BHT_NO_ADDR_MATCH.B)).asBool, bht_wr_data2, bht_wr_data0))))
Mux((bht_wr_en2(i)&(bht_wr_addr2(NUM_BHT_LOOP_INNER_HI-BHT_ADDR_LO,0)===j.U)&(bht_wr_addr2(BHT_ADDR_HI-BHT_ADDR_LO,NUM_BHT_LOOP_OUTER_LO-BHT_ADDR_LO)===k.U)|BHT_NO_ADDR_MATCH.B).asBool, bht_wr_data2, bht_wr_data0))))
val bht_bank_sel = Wire(Vec(2, Vec(BHT_ARRAY_DEPTH/NUM_BHT_LOOP, Vec(NUM_BHT_LOOP, Bool()))))
// We have a 2 way bht with BHT_ARRAY_DEPTH/NUM_BHT_LOOP blocks and NUM_BHT_LOOP->offset in each block
// Make enables of each flop according to the address dividing the address in 2-blocks upper block for BHT-Block and
// the lower block for the offset and run this on both of the ways
// the lower block for the offset and run this on both of the ways
for(i<-0 until 2; k<-0 until BHT_ARRAY_DEPTH/NUM_BHT_LOOP; j<- 0 until NUM_BHT_LOOP){
bht_bank_sel(i)(k)(j) := (bht_wr_en0(i) & (bht_wr_addr0(NUM_BHT_LOOP_INNER_HI-BHT_ADDR_LO,0)===j.asUInt) & ((bht_wr_addr0(BHT_ADDR_HI-BHT_ADDR_LO, NUM_BHT_LOOP_OUTER_LO-BHT_ADDR_LO)===k.asUInt) | BHT_NO_ADDR_MATCH.B)) |
(bht_wr_en2(i) & (bht_wr_addr2(NUM_BHT_LOOP_INNER_HI-BHT_ADDR_LO,0)===j.asUInt) & ((bht_wr_addr2(BHT_ADDR_HI-BHT_ADDR_LO, NUM_BHT_LOOP_OUTER_LO-BHT_ADDR_LO)===k.asUInt) | BHT_NO_ADDR_MATCH.B))
}
// Reading the BHT with i->way, k->block and the j->offset
val bht_bank_rd_data_out = Wire(Vec(2, Vec(BHT_ARRAY_DEPTH, UInt(2.W))))
for(i<-0 until 2; k<-0 until BHT_ARRAY_DEPTH/NUM_BHT_LOOP; j<-0 until NUM_BHT_LOOP){
bht_bank_rd_data_out(i)((16*k)+j) := rvdffs_fpga(bht_bank_wr_data(i)(k)(j), bht_bank_sel(i)(k)(j),bht_bank_clk(i)(k),bht_bank_sel(i)(k)(j),clock)}
bht_bank_rd_data_out(i)((16*k)+j) := withClock(bht_bank_clk(i)(k)){RegEnable(bht_bank_wr_data(i)(k)(j), 0.U, bht_bank_sel(i)(k)(j))}
}
// Make the final read mux
bht_bank0_rd_data_f := Mux1H((0 until BHT_ARRAY_DEPTH).map(i=>(bht_rd_addr_f===i.U).asBool->bht_bank_rd_data_out(0)(i)))
bht_bank1_rd_data_f := Mux1H((0 until BHT_ARRAY_DEPTH).map(i=>(bht_rd_addr_f===i.U).asBool->bht_bank_rd_data_out(1)(i)))
bht_bank0_rd_data_p1_f := Mux1H((0 until BHT_ARRAY_DEPTH).map(i=>(bht_rd_addr_p1_f===i.U).asBool->bht_bank_rd_data_out(0)(i)))
}
//object bp_MAIN extends App {
// println((new chisel3.stage.ChiselStage).emitVerilog(new ifu_bp_ctl()))
//}

View File

@ -23,7 +23,7 @@ class ifu_compress_ctl extends Module with lib{
out(13) := pat(List(15, -14, -13, 11, -10, 0)) | pat(List(15, -14, -13, 11, 6, 0)) | (io.din(14)&(!io.din(0)))
out(12) := pat(List(15, -14, -13, 6, 5, 0)) | pat(List(15, -14, -13, -11, 0)) | pat(List(15, -14, -13, -10, 0)) |
pat(List(-15, -14, 1)) | pat(List(15, 14, 13))
pat(List(-15, -14, 1)) | pat(List(15, 14, 13))
out(6) := (pat(List(15, -14, -6, -5, -4, -3, -2)) & !io.din(0)) | pat(List(-14, 13)) | pat(List(15, 14, 0))
@ -54,7 +54,7 @@ class ifu_compress_ctl extends Module with lib{
val rdrd = pat(List(-14,6,1)) | pat(List(-15,14,11,0)) | pat(List(-14,5,1)) | pat(List(-15,14,10,0)) |
pat(List(-14,4,1)) | pat(List(-15,14,9,0)) | pat(List(-14,3,1)) | pat(List(-15,14,-8,0)) |
pat(List(-14,2,1)) | pat(List(-15,14,7,0)) | pat(List(-15,1)) | pat(List(-15,-13,0))
pat(List(-14,2,1)) | pat(List(-15,14,7,0)) | pat(List(-15,1)) | pat(List(-15,-13,0))
val rdrs1 = pat(List(-14,12,11,1)) | pat(List(-14,12,10,1)) | pat(List(-14,12,9,1)) |
pat(List(-14,12,8,1)) | pat(List(-14,12,7,1)) | pat(List(-14,-12,-6,-5,-4,-3,-2,1)) |
@ -104,7 +104,7 @@ class ifu_compress_ctl extends Module with lib{
val l1_6 = Cat(out(6),out(5),out(4),out(3),out(2),out(1),out(0)).asUInt()
val l1_11 = Cat(out(11),out(10),out(9),out(8),out(7)).asUInt | Mux1H(Seq(rdrd.asBool->rdd,
rdprd.asBool->rdpd, rs2prd.asBool->rs2pd, rdeq1.asBool->1.U(5.W), rdeq2.asBool->2.U(5.W)))
rdprd.asBool->rdpd, rs2prd.asBool->rs2pd, rdeq1.asBool->1.U(5.W), rdeq2.asBool->2.U(5.W)))
val l1_14 = Cat(out(14),out(13),out(12))
@ -132,16 +132,16 @@ class ifu_compress_ctl extends Module with lib{
val l2_31 = l1(31,20) |
Mux1H(Seq(simm5_0.asBool->Cat(repl(7, simm5d(5)), simm5d(4,0)),
uimm9_2.asBool->Cat(0.U(2.W), uimm9d, 0.U(2.W)),
simm9_4.asBool->Cat(repl(3, simm9d(5)), simm9d(4,0), 0.U(4.W)),
ulwimm6_2.asBool->Cat(0.U(5.W), ulwimm6d, 0.U(2.W)),
ulwspimm7_2.asBool->Cat(0.U(4.W), ulwspimm7d, 0.U(2.W)),
uimm5_0.asBool->Cat(0.U(6.W), uimm5d),
sjaloffset11_1.asBool->Cat(sjald(19), sjald(9,0), sjald(10)),
sluimm17_12.asBool->sluimmd(19,8)))
uimm9_2.asBool->Cat(0.U(2.W), uimm9d, 0.U(2.W)),
simm9_4.asBool->Cat(repl(3, simm9d(5)), simm9d(4,0), 0.U(4.W)),
ulwimm6_2.asBool->Cat(0.U(5.W), ulwimm6d, 0.U(2.W)),
ulwspimm7_2.asBool->Cat(0.U(4.W), ulwspimm7d, 0.U(2.W)),
uimm5_0.asBool->Cat(0.U(6.W), uimm5d),
sjaloffset11_1.asBool->Cat(sjald(19), sjald(9,0), sjald(10)),
sluimm17_12.asBool->sluimmd(19,8)))
val l2_19 = l1(19,12) | Mux1H(Seq(sjaloffset11_1.asBool->sjald(19,12),
sluimm17_12.asBool->sluimmd(7,0)))
sluimm17_12.asBool->sluimmd(7,0)))
val l2 = Cat(l2_31, l2_19, l1(11,0))
val sbr8d = Cat(io.din(12),io.din(6),io.din(5),io.din(2),io.din(11),io.din(10),io.din(4),io.din(3),0.U)

Some files were not shown because too many files have changed in this diff Show More