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 ## License
@ -40,22 +40,18 @@ Quasar is a Chiselified version of EL2 SweRV RISC-V Core.
├── generated_rtl # Quasar wrapper ├── generated_rtl # Quasar wrapper
├── testbench ├── testbench
│ ├── asm # Example assembly files │ ├── asm # Example assembly files
│ ├── hex # Canned demo hex files │ └── hex # Canned demo hex files
│ └── tests # Example tests
├── tools # Scripts/Makefiles ├── tools # Scripts/Makefiles
├── tracer_logs # generated log files ├── tracer_logs # generated log files
└── verif └── verif
├── LEC ├── LEC
├── formality_work
└── formality_log # LEC log files
└── setup_files # user_match files
└── sim # Simulation log/dump files └── sim # Simulation log/dump files
## Dependencies ## 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. - 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. 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. - 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 4. Run make with $RV_ROOT/tools/Makefile
## Release Notes for this version ## 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 ### Configurations
@ -99,8 +95,7 @@ $RV_ROOT/design/snapshots/default
├── pd_defines.vh # `defines for physical design ├── pd_defines.vh # `defines for physical design
├── perl_configs.pl # Perl %configs hash for scripting ├── perl_configs.pl # Perl %configs hash for scripting
├── pic_map_auto.h # PIC memory map based on configure size ├── pic_map_auto.h # PIC memory map based on configure size
├── whisper.json # JSON file for swerv-iss └── whisper.json # JSON file for swerv-iss
└── link.ld # default linker control file
``` ```
#### 1. Generate scala parameter #### 1. Generate scala parameter
``` ```
@ -141,9 +136,9 @@ Snapshots are placed in `$BUILD_PATH` directory.
#### 3. Run sbt #### 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: * In the reset_script we do a post verilog-generation changes, these changes are as follows:
* Replace `posedge reset` with `negedge reset` * Replace `posedge reset` with `negedge reset`
@ -162,7 +157,7 @@ The simulation produces output on the screen like:
VerilatorTB: Start of sim VerilatorTB: Start of sim
---------------------------------- ----------------------------------
Hello World from QUASAR @LMDC !! Hello World from Quasar @LM !!
---------------------------------- ----------------------------------
TEST_PASSED TEST_PASSED
@ -185,7 +180,21 @@ You can re-execute simulation using:
``` ```
make -f $RV_ROOT/tools/Makefile verilator 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 If you want to run default configuration on verilator use the following command
``` ```
make -f $RV_ROOT/tools/Makefile make -f $RV_ROOT/tools/Makefile
@ -194,21 +203,6 @@ For VCS use
``` ```
make -f $RV_ROOT/tools/Makefile vcs_all 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: Example:
``` ```
make -f $RV_ROOT/tools/Makefile verilator TEST=cmark 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] 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. 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. 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: 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_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 - coremark benchmark running with code and data in external memories
cmark_dccm - the same as above, running data and stack from DCCM (faster) cmark_dccm - the same as above, running data and stack from DCCM (faster)
cmark_iccm - the same as above with preloaded code to ICCM. cmark_iccm - the same as above with preloaded code to ICCM.
dhry - Run dhrystone. (Scale by 1757 to get DMIPS/MHZ)
``` ```
The `$RV_ROOT/testbench/hex` directory contains precompiled hex files of the tests, ready for simulation in case RISCV SW tools are not installed. 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. **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. `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.** **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" scalaVersion := "2.12.10"
// Making the main-class
mainClass in (Compile, run) := Some("wrapper")
crossScalaVersions := Seq("2.12.10", "2.11.12") crossScalaVersions := Seq("2.12.10", "2.11.12")
resolvers ++= Seq( 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] "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] 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/quasar2/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] Copy resource mappings: 
[debug] [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" outfile = root+"/design/quasar_wrapper.sv"
delete_list1 = ["if (dbg_dm_rst_l)"] 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_list3 = ["if (io_dbg_rst_l)"]
delete_list4 = ["if (reset)"] delete_list4 = ["if (reset)"]
delete_list5 = ["posedge reset"] delete_list5 = ["posedge reset"]
delete_list6 = ["posedge dbg_dm_rst_l"] 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_list8 = ["posedge io_dbg_rst_l"]
delete_list9 = ["if (rst_not)"] delete_list9 = ["if (rst_not)"]
delete_list10 = ["posedge rst_not"] delete_list10 = ["posedge rst_not"]
delete_list11 = ["rvclkhdr"]
fin = open(infile) fin = open(infile)
fout = open(outfile, "w+") fout = open(outfile, "w+")
@ -24,7 +23,7 @@ for line in fin:
line = line.replace(word, "if (~dbg_dm_rst_l)") line = line.replace(word, "if (~dbg_dm_rst_l)")
for word in delete_list2: for word in delete_list2:
line = line.replace(word, "if (~_T_597)") line = line.replace(word, "if (~rst_temp)")
for word in delete_list3: for word in delete_list3:
line = line.replace(word, "if (~io_dbg_rst_l)") 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") line = line.replace(word, "negedge dbg_dm_rst_l")
for word in delete_list7: for word in delete_list7:
line = line.replace(word, "negedge _T_597") line = line.replace(word, "negedge rst_temp")
for word in delete_list8: for word in delete_list8:
line = line.replace(word, "negedge io_dbg_rst_l") line = line.replace(word, "negedge io_dbg_rst_l")
@ -49,10 +48,6 @@ for line in fin:
for word in delete_list10: for word in delete_list10:
line = line.replace(word, "negedge rst_not") line = line.replace(word, "negedge rst_not")
for word in delete_list11:
line = line.replace(word, "rvclkhdr_ch")
fout.write(line) fout.write(line)
fin.close() fin.close()
fout.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 // 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"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -14,8 +14,6 @@
// limitations under the License. // limitations under the License.
// all flops call the rvdff flop // all flops call the rvdff flop
`define RV_FPGA_OPTIMIZE 1
`define RV_PHYSICAL 1
module rvdff #( parameter WIDTH=1, SHORT=0 ) module rvdff #( parameter WIDTH=1, SHORT=0 )
@ -31,7 +29,7 @@ if (SHORT == 1) begin
assign dout = din; assign dout = din;
end end
else begin else begin
`ifdef RV_CLOCKGATE `ifdef CLOCKGATE
always @(posedge tb_top.clk) begin always @(posedge tb_top.clk) begin
#0 $strobe("CG: %0t %m din %x dout %x clk %b width %d",$time,din,dout,clk,WIDTH); #0 $strobe("CG: %0t %m din %x dout %x clk %b width %d",$time,din,dout,clk,WIDTH);
end end
@ -87,85 +85,7 @@ else begin
end end
endmodule endmodule
// _fpga versions module rvdffe #( parameter WIDTH=1, SHORT=0 )
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 )
( (
input logic [WIDTH-1:0] din, input logic [WIDTH-1:0] din,
input logic en, input logic en,
@ -184,8 +104,8 @@ if (SHORT == 1) begin : genblock
end end
else begin : genblock else begin : genblock
`ifndef RV_PHYSICAL `ifndef PHYSICAL
if (WIDTH >= 8 || OVERRIDE==1) begin: genblock if (WIDTH >= 8) begin: genblock
`endif `endif
`ifdef RV_FPGA_OPTIMIZE `ifdef RV_FPGA_OPTIMIZE
@ -195,226 +115,15 @@ else begin : genblock
rvdff #(WIDTH) dff (.*, .clk(l1clk)); rvdff #(WIDTH) dff (.*, .clk(l1clk));
`endif `endif
`ifndef RV_PHYSICAL `ifndef PHYSICAL
end end
else else
$error("%m: rvdffe must be WIDTH >= 8"); $error(" rvdffe width must be >= 8");
`endif `endif
end // else: !if(SHORT == 1) end // else: !if(SHORT == 1)
endmodule // rvdffe 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) module rvsyncss #(parameter WIDTH = 251)
( (
input logic clk, input logic clk,
@ -430,23 +139,6 @@ module rvsyncss #(parameter WIDTH = 251)
endmodule // rvsyncss 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 module rvlsadder
( (
input logic [31:0] rs1, input logic [31:0] rs1,
@ -751,7 +443,7 @@ module rvecc_decode_64 (
endmodule // rvecc_decode_64 endmodule // rvecc_decode_64
module TEC_RV_ICG module gated_flop
( (
input logic SE, EN, CK, input logic SE, EN, CK,
output Q output Q
@ -776,24 +468,5 @@ module TEC_RV_ICG
endmodule 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 // 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"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -20,38 +20,29 @@
//******************************************************************************** //********************************************************************************
module ifu_iccm_mem module ifu_iccm_mem
//`include "parameter.sv"
#( #(
parameter ICCM_BITS, parameter ICCM_BITS,
parameter ICCM_BANK_INDEX_LO, parameter ICCM_BANK_INDEX_LO,
parameter ICCM_INDEX_BITS, parameter ICCM_INDEX_BITS,
parameter ICCM_BANK_HI, parameter ICCM_BANK_HI,
parameter ICCM_NUM_BANKS, 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 iccm_wren,
input logic iccm_rden,
( input logic [ICCM_BITS-1:1] iccm_rw_addr,
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_buf_correct_ecc, // ICCM is doing a single bit error correct cycle 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 iccm_correction_state, // We are under a correction - This is needed to guard replacements when hit
input logic [2:0] iccm_wr_size, // ICCM write size input logic [2:0] iccm_wr_size,
input logic [77:0] iccm_wr_data, // ICCM write data 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 [63:0] iccm_rd_data,
output logic [77:0] iccm_rd_data_ecc, // ICCM read ecc output logic [77:0] iccm_rd_data_ecc,
input logic scan_mode // Scan mode control input logic scan_mode
); );
@ -84,32 +75,15 @@ module ifu_iccm_mem
logic redundant_data1_en; logic redundant_data1_en;
logic r0_addr_en, r1_addr_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_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]; 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)] = iccm_wr_data[38:0];
assign iccm_bank_wr_data_vec[(2*i)+1] = iccm_wr_data[77:39]; assign iccm_bank_wr_data_vec[(2*i)+1] = iccm_wr_data[77:39];
end 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 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 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)); 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]), .WE(wren_bank[i]),
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]), .D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[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)
); );
`else `else
@ -151,18 +114,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]), .WE(wren_bank[i]),
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]), .D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[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)
); );
end // block: iccm end // block: iccm
@ -175,18 +127,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]), .WE(wren_bank[i]),
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]), .D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[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)
); );
end // block: iccm end // block: iccm
@ -199,18 +140,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]), .WE(wren_bank[i]),
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]), .D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[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)
); );
end // block: iccm end // block: iccm
@ -222,18 +152,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]), .WE(wren_bank[i]),
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]), .D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[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)
); );
end // block: iccm end // block: iccm
@ -245,18 +164,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]), .WE(wren_bank[i]),
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]), .D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[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)
); );
end // block: iccm end // block: iccm
@ -268,18 +176,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]), .WE(wren_bank[i]),
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]), .D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[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)
); );
end // block: iccm end // block: iccm
@ -291,18 +188,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]), .WE(wren_bank[i]),
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]), .D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[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)
); );
end // block: iccm end // block: iccm
@ -314,18 +200,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]), .WE(wren_bank[i]),
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]), .D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[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)
); );
end // block: iccm end // block: iccm
@ -337,18 +212,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]), .WE(wren_bank[i]),
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]), .D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[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)
); );
end // block: iccm end // block: iccm
@ -360,18 +224,7 @@ module ifu_iccm_mem
.WE(wren_bank[i]), .WE(wren_bank[i]),
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(iccm_bank_wr_data[i][38:0]), .D(iccm_bank_wr_data[i][38:0]),
.Q(iccm_bank_dout[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)
); );
end // block: iccm end // block: iccm
@ -385,12 +238,12 @@ module ifu_iccm_mem
((addr_bank_inc[ICCM_BITS-1:2]== redundant_address[0][ICCM_BITS-1:2]) & (addr_bank_inc[3:2] == i)))); ((addr_bank_inc[ICCM_BITS-1:2]== redundant_address[0][ICCM_BITS-1:2]) & (addr_bank_inc[3:2] == i))));
rvdff #(1) selred0 (.*, rvdff #(1) selred0 (.*,
.clk(active_clk), .clk(clk),
.din(sel_red0[i]), .din(sel_red0[i]),
.dout(sel_red0_q[i])); .dout(sel_red0_q[i]));
rvdff #(1) selred1 (.*, rvdff #(1) selred1 (.*,
.clk(active_clk), .clk(clk),
.din(sel_red1[i]), .din(sel_red1[i]),
.dout(sel_red1_q[i])); .dout(sel_red1_q[i]));
@ -400,6 +253,7 @@ module ifu_iccm_mem
({39{sel_red0_q[i]}} & redundant_data[0][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]); ({39{~sel_red0_q[i] & ~sel_red1_q[i]}} & iccm_bank_dout[i][38:0]);
end : mem_bank end : mem_bank
// This section does the redundancy for tolerating single bit errors // This section does the redundancy for tolerating single bit errors
// 2x 39 bit data values with address[hi:2] and a valid bit is needed to CAM and sub out the reads/writes to the particular locations // 2x 39 bit data values with address[hi:2] and a valid bit is needed to CAM and sub out the reads/writes to the particular locations
@ -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; 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 rvdffs #() red_lru (.*, // LRU flop for the redundant replacements
.clk(active_clk), .clk(clk),
.en(redundant_lru_en), .en(redundant_lru_en),
.din(redundant_lru_in), .din(redundant_lru_in),
.dout(redundant_lru)); .dout(redundant_lru));
rvdffs #(ICCM_BITS-2) r0_address (.*, // Redundant Row 0 address rvdffs #(ICCM_BITS-2) r0_address (.*, // Redundant Row 0 address
.clk(active_clk), .clk(clk),
.en(r0_addr_en), .en(r0_addr_en),
.din(iccm_rw_addr[ICCM_BITS-1:2]), .din(iccm_rw_addr[ICCM_BITS-1:2]),
.dout(redundant_address[0][ICCM_BITS-1:2])); .dout(redundant_address[0][ICCM_BITS-1:2]));
rvdffs #(ICCM_BITS-2) r1_address (.*, // Redundant Row 0 address rvdffs #(ICCM_BITS-2) r1_address (.*, // Redundant Row 0 address
.clk(active_clk), .clk(clk),
.en(r1_addr_en), .en(r1_addr_en),
.din(iccm_rw_addr[ICCM_BITS-1:2]), .din(iccm_rw_addr[ICCM_BITS-1:2]),
.dout(redundant_address[1][ICCM_BITS-1:2])); .dout(redundant_address[1][ICCM_BITS-1:2]));
rvdffs #(1) r0_valid (.*, rvdffs #(1) r0_valid (.*,
.clk(active_clk), // Redundant Row 0 Valid .clk(clk), // Redundant Row 0 Valid
.en(r0_addr_en), .en(r0_addr_en),
.din(1'b1), .din(1'b1),
.dout(redundant_valid[0])); .dout(redundant_valid[0]));
rvdffs #(1) r1_valid (.*, // Redundant Row 1 Valid rvdffs #(1) r1_valid (.*, // Redundant Row 1 Valid
.clk(active_clk), .clk(clk),
.en(r1_addr_en), .en(r1_addr_en),
.din(1'b1), .din(1'b1),
.dout(redundant_valid[1])); .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]; 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 rvdffs #(39) r0_data (.*, // Redundant Row 1 data
.clk(active_clk), .clk(clk),
.en(redundant_data0_en), .en(redundant_data0_en),
.din(redundant_data0_in[38:0]), .din(redundant_data0_in[38:0]),
.dout(redundant_data[0][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]; 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 rvdffs #(39) r1_data (.*, // Redundant Row 1 data
.clk(active_clk), .clk(clk),
.en(redundant_data1_en), .en(redundant_data1_en),
.din(redundant_data1_in[38:0]), .din(redundant_data1_in[38:0]),
.dout(redundant_data[1][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_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 (.*, .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_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_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_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[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]}; 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 // 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"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with 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 module lsu_dccm_mem
//`include "parameter.sv"
#( #(
parameter DCCM_BYTE_WIDTH, parameter DCCM_BYTE_WIDTH,
parameter DCCM_BITS, parameter DCCM_BITS,
parameter DCCM_NUM_BANKS, parameter DCCM_NUM_BANKS,
parameter DCCM_ENABLE= 'b1,
parameter DCCM_BANK_BITS, parameter DCCM_BANK_BITS,
parameter DCCM_SIZE, parameter DCCM_SIZE,
parameter DCCM_FDATA_WIDTH, parameter DCCM_FDATA_WIDTH )(
parameter DCCM_WIDTH_BITS input logic clk, // clock
) input logic rst_l,
( input logic clk_override, // clock 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 dccm_wren, // write enable input logic dccm_wren, // write enable
input logic dccm_rden, // read enable input logic dccm_rden, // read enable
@ -67,7 +47,6 @@ 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_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_lo, // write data
input logic [DCCM_FDATA_WIDTH-1:0] dccm_wr_data_hi, // 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_lo, // read data from the lo bank
output logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // read data from the hi 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_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 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_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]; 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) // 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 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 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) ? 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,7 +101,6 @@ module lsu_dccm_mem
// end clock gating section // end clock gating section
`ifdef VERILATOR `ifdef VERILATOR
el2_ram #(DCCM_INDEX_DEPTH,39) ram ( el2_ram #(DCCM_INDEX_DEPTH,39) ram (
// Primary ports // Primary ports
.ME(dccm_clken[i]), .ME(dccm_clken[i]),
@ -130,13 +109,10 @@ module lsu_dccm_mem
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[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 if (DCCM_INDEX_DEPTH == 32768) begin : dccm
ram_32768x39 dccm_bank ( ram_32768x39 dccm_bank (
// Primary ports // Primary ports
@ -146,9 +122,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[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 end
@ -161,9 +134,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[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 end
@ -176,9 +146,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[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 end
@ -191,9 +158,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[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 end
@ -206,9 +170,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[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 end
@ -221,9 +182,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[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 end
@ -236,9 +194,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[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 end
@ -251,9 +206,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[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 end
@ -266,37 +218,18 @@ module lsu_dccm_mem
.ADR(addr_bank[i]), .ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]), .D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[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 end
else if (DCCM_INDEX_DEPTH == 128) begin : dccm `endif // VERILATOR
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
end : mem_bank end : mem_bank
// Flops // 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)); 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));
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_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,70 +1,4 @@
//********************************************************************************
// 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 ICACHE_BEAT_BITS,
parameter ICCM_BITS, parameter ICCM_BITS,
@ -95,17 +29,7 @@ module mem#(
parameter DCCM_SIZE, parameter DCCM_SIZE,
parameter DCCM_FDATA_WIDTH, parameter DCCM_FDATA_WIDTH,
parameter ICACHE_TAG_INDEX_LO, parameter ICACHE_TAG_INDEX_LO,
parameter ICACHE_DATA_DEPTH, 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
)
( (
input logic clk, input logic clk,
input logic rst_l, input logic rst_l,
@ -128,89 +52,10 @@ module mem#(
output logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, output logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi,
//`ifdef DCCM_ENABLE //`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 //`endif
//ICCM ports //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_BITS-1:1] iccm_rw_addr,
input logic iccm_buf_correct_ecc, // ICCM is doing a single bit error correct cycle input logic iccm_buf_correct_ecc, // ICCM is doing a single bit error correct cycle
@ -231,70 +76,9 @@ module mem#(
input logic ic_rd_en, 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 [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 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_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_wr_data_1,
input logic [70:0] ic_debug_wr_data, // Debug wr cache. 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 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 [ICACHE_INDEX_HI:3] ic_debug_addr, // Read/Write addresss to the Icache.
@ -317,160 +101,9 @@ module mem#(
); );
iccm_ext_in_pkt_t [ICCM_NUM_BANKS-1:0] iccm_ext_in_pkt; logic [ICACHE_BANKS_WAY-1:0][70:0] ic_wr_data;
dccm_ext_in_pkt_t [DCCM_NUM_BANKS-1:0] dccm_ext_in_pkt; assign ic_wr_data [0] = ic_wr_data_0;
ic_data_ext_in_pkt_t [ICACHE_NUM_WAYS-1:0][ICACHE_BANKS_WAY-1:0] ic_data_ext_in_pkt; assign ic_wr_data [1] = ic_wr_data_1;
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), .* );
// DCCM Instantiation // DCCM Instantiation
if (DCCM_ENABLE == 1) begin: Gen_dccm_enable if (DCCM_ENABLE == 1) begin: Gen_dccm_enable
lsu_dccm_mem #( lsu_dccm_mem #(
@ -479,8 +112,7 @@ module mem#(
.DCCM_NUM_BANKS(DCCM_NUM_BANKS), .DCCM_NUM_BANKS(DCCM_NUM_BANKS),
.DCCM_BANK_BITS(DCCM_BANK_BITS), .DCCM_BANK_BITS(DCCM_BANK_BITS),
.DCCM_SIZE(DCCM_SIZE), .DCCM_SIZE(DCCM_SIZE),
.DCCM_FDATA_WIDTH(DCCM_FDATA_WIDTH), .DCCM_FDATA_WIDTH(DCCM_FDATA_WIDTH)) dccm (
.DCCM_WIDTH_BITS(DCCM_WIDTH_BITS)) dccm (
.clk_override(dccm_clk_override), .clk_override(dccm_clk_override),
.* .*
); );
@ -505,14 +137,7 @@ if ( ICACHE_ENABLE ) begin: icache
.ICACHE_TAG_DEPTH(ICACHE_TAG_DEPTH), .ICACHE_TAG_DEPTH(ICACHE_TAG_DEPTH),
.ICACHE_WAYPACK(ICACHE_WAYPACK), .ICACHE_WAYPACK(ICACHE_WAYPACK),
.ICACHE_TAG_INDEX_LO(ICACHE_TAG_INDEX_LO), .ICACHE_TAG_INDEX_LO(ICACHE_TAG_INDEX_LO),
.ICACHE_DATA_DEPTH(ICACHE_DATA_DEPTH), .ICACHE_DATA_DEPTH(ICACHE_DATA_DEPTH)) icm (
.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 (
.clk_override(icm_clk_override), .clk_override(icm_clk_override),
.* .*
); );
@ -546,4 +171,3 @@ end
endmodule endmodule

View File

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

View File

@ -62,4 +62,3 @@ module el2_btb_ghr_hash #(
endmodule 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,20 +2,24 @@ package dbg
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._
import lib._
import include._ 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 { object state_t {
val idle = 0.U(4.W) val idle = 0.U(3.W)
val halting = 1.U(4.W) val halting = 1.U(3.W)
val halted = 2.U(4.W) val halted = 2.U(3.W)
val core_cmd_start = 3.U(4.W) val cmd_start = 3.U(3.W)
val core_cmd_wait = 4.U(4.W) val cmd_wait = 4.U(3.W)
val sb_cmd_start = 5.U(4.W) val cmd_done = 5.U(3.W)
val sb_cmd_send = 6.U(4.W) val resuming = 6.U(3.W)
val sb_cmd_resp = 7.U(4.W)
val cmd_done = 8.U(4.W)
val resuming = 9.U(4.W)
} }
object sb_state_t { object sb_state_t {
@ -49,13 +53,12 @@ class dbg extends Module with lib with RequireAsyncReset {
val dmi_reg_wr_en = Input(Bool()) val dmi_reg_wr_en = Input(Bool())
val dmi_reg_wdata = Input(UInt(32.W)) val dmi_reg_wdata = Input(UInt(32.W))
val dmi_reg_rdata = Output(UInt(32.W)) val dmi_reg_rdata = Output(UInt(32.W))
val sb_axi = new axi_channels(SB_BUS_TAG) val sb_axi = new axi_channels(SB_BUS_TAG)
val dbg_dec_dma = Flipped(new dec_dbg) val dbg_dec_dma = Flipped(new dec_dbg)
// val dbg_dma = Flipped(new dec_dbg)
val dbg_dma = Flipped(new dbg_dma) val dbg_dma = Flipped(new dbg_dma)
val dbg_bus_clk_en = Input(Bool()) val dbg_bus_clk_en = Input(Bool())
val dbg_rst_l = Input(AsyncReset()) val dbg_rst_l = Input(Bool())
val clk_override = Input(Bool()) val clk_override = Input(Bool())
val scan_mode = Input(Bool()) val scan_mode = Input(Bool())
}) })
@ -72,7 +75,6 @@ class dbg extends Module with lib with RequireAsyncReset {
val sbaddress0_reg_wren1 = WireInit(false.B) val sbaddress0_reg_wren1 = WireInit(false.B)
val dmstatus_reg = WireInit(0.U(32.W)) val dmstatus_reg = WireInit(0.U(32.W))
val dmstatus_havereset = WireInit(false.B) val dmstatus_havereset = WireInit(false.B)
val dmstatus_haveresetn = WireInit(false.B)
val dmstatus_resumeack = WireInit(false.B) val dmstatus_resumeack = WireInit(false.B)
val dmstatus_unavail = WireInit(false.B) val dmstatus_unavail = WireInit(false.B)
val dmstatus_running = WireInit(false.B) val dmstatus_running = WireInit(false.B)
@ -89,64 +91,51 @@ class dbg extends Module with lib with RequireAsyncReset {
val sbcs_sberror_din = WireInit(0.U(3.W)) val sbcs_sberror_din = WireInit(0.U(3.W))
val data1_reg = WireInit(0.U(32.W)) val data1_reg = WireInit(0.U(32.W))
val sbcs_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_free_clken = io.dmi_reg_en | execute_command | (dbg_state =/= state_t.idle) | dbg_state_en | io.dec_tlu_dbg_halted | val dbg_free_clken = io.dmi_reg_en | (dbg_state =/= state_t.idle) | dbg_state_en | io.dec_tlu_dbg_halted | io.clk_override
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 | sb_state_en | (sb_state =/= sb_state_t.sbidle) | 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_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() 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 dontTouch(dbg_dm_rst_l)
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 rst_temp = (dbg_dm_rst_l.asBool() & reset.asBool()).asAsyncReset()
val sbcs_sbbusyerror_wren = (sbcs_wren & io.dmi_reg_wdata(22)) | (sbcs_reg(21) & io.dmi_reg_en & ((io.dmi_reg_wr_en & dontTouch(rst_temp)
(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 sbcs_sbbusyerror_din = (~(sbcs_wren & io.dmi_reg_wdata(22))).asUInt()
val temp_sbcs_22 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) { val temp_sbcs_22 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
RegEnable(sbcs_sbbusyerror_din, 0.U, sbcs_sbbusyerror_wren)} // sbcs_sbbusyerror_reg RegEnable(sbcs_sbbusyerror_din, 0.U, sbcs_sbbusyerror_wren)
} // sbcs_sbbusyerror_reg
val temp_sbcs_21 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) { val temp_sbcs_21 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
RegEnable(sbcs_sbbusy_din, 0.U, sbcs_sbbusy_wren)} // sbcs_sbbusy_reg RegEnable(sbcs_sbbusy_din, 0.U, sbcs_sbbusy_wren)
} // sbcs_sbbusy_reg
val temp_sbcs_20 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) { 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 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) { 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 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) { 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 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))
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), val sbcs_unaligned = (sbcs_reg(19, 17) === "b001".U(3.W)) & sbaddress0_reg(0) |
temp_sbcs_19_15(2,0), temp_sbcs_14_12, "h20".U(7.W), "b01111".U(5.W)) (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_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 sbcs_illegal_size = sbcs_reg(19) 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) | 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) === 2.U(3.W))) & 4.U(4.W) | Fill(4, (sbcs_reg(19, 17) === 3.U(3.W))) & 8.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_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_wren1 = (sb_state === sb_state_t.rsp_rd) & sb_state_en & !sbcs_sberror_wren
@ -154,137 +143,120 @@ class dbg extends Module with lib with RequireAsyncReset {
val sbdata1_reg_wren0 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h3d".U) 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_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 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_din = Fill(32, sbdata0_reg_wren0) & io.dmi_reg_wdata |
val sbdata1_din = Fill(32, sbdata1_reg_wren0) & io.dmi_reg_wdata | Fill(32, sbdata1_reg_wren1) & sb_bus_rdata(63, 32) 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_din = Fill(32, sbdata1_reg_wren0) & io.dmi_reg_wdata |
val sbdata1_reg = withReset(dbg_dm_rst_l) { rvdffe(sbdata1_din, sbdata1_reg_wren, clock, io.scan_mode)} // dbg_sbdata1_reg Fill(32, sbdata1_reg_wren1) & sb_bus_rdata(63, 32)
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_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_wren = sbaddress0_reg_wren0 | sbaddress0_reg_wren1
val sbaddress0_reg_din = Fill(32, sbaddress0_reg_wren0) & io.dmi_reg_wdata | 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)) Fill(32, sbaddress0_reg_wren1) & (sbaddress0_reg + Cat(0.U(28.W), sbaddress0_incr))
sbaddress0_reg := withReset(dbg_dm_rst_l) {
sbaddress0_reg := withReset(dbg_dm_rst_l) { rvdffe(sbaddress0_reg_din, sbaddress0_reg_wren, clock, io.scan_mode)} // dbg_sbaddress0_reg 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 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 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 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 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 dm_temp = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) { 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 RegEnable(
val dm_temp_0 = withClockAndReset(dbg_free_clk, io.dbg_rst_l) { Cat(io.dmi_reg_wdata(31, 30), io.dmi_reg_wdata(28), io.dmi_reg_wdata(1)),
RegEnable(io.dmi_reg_wdata(0), 0.U, dmcontrol_wren)} // dmcontrol_dmactive_ff 0.U, dmcontrol_wren)
} // dmcontrolff
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
val temp = Cat(dm_temp(3, 2), 0.U, dm_temp(1), 0.U(26.W), dm_temp(0), dm_temp_0) 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 dmcontrol_reg := temp
dmcontrol_wren_Q := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) { val dmcontrol_wren_Q = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegNext(dmcontrol_wren, 0.U)} // dmcontrol_wrenff RegNext(dmcontrol_wren, 0.U)
} // dmcontrol_wrenff
dmstatus_reg := Cat(0.U(12.W), Fill(2, dmstatus_havereset), Fill(2, dmstatus_resumeack), 0.U(2.W), Fill(2, dmstatus_unavail), 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))
Fill(2, dmstatus_running), Fill(2, dmstatus_halted), 1.U(1.W), 0.U(3.W), 2.U(4.W))
val dmstatus_resumeack_wren = (dbg_state === state_t.resuming) & io.dec_tlu_resume_ack | dmstatus_resumeack & resumereq & dmstatus_halted 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_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) val dmstatus_havereset_wren = (io.dmi_reg_addr === "h10".U) & io.dmi_reg_wdata(1) & io.dmi_reg_en & io.dmi_reg_wr_en
dmstatus_havereset := ~dmstatus_haveresetn 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() val temp_rst = reset.asBool()
dmstatus_unavail := (dmcontrol_reg(1) | !(temp_rst)).asBool() dmstatus_unavail := (dmcontrol_reg(1) | !(temp_rst)).asBool()
dmstatus_running := ~(dmstatus_unavail | dmstatus_halted) dmstatus_running := ~(dmstatus_unavail | dmstatus_halted)
dmstatus_resumeack := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) { dmstatus_resumeack := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegEnable(dmstatus_resumeack_din, 0.U, dmstatus_resumeack_wren.asBool())} // dmstatus_resumeack_reg RegEnable(dmstatus_resumeack_din, 0.U, dmstatus_resumeack_wren)
} // dmstatus_resumeack_reg
dmstatus_halted := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) { 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 RegNext(io.dec_tlu_dbg_halted & !io.dec_tlu_mpc_halted_only, 0.U)
dmstatus_haveresetn := withClock(dbg_free_clk) { } // dmstatus_halted_reg
RegEnable(true.B, 0.U, dmstatus_haveresetn_wren)} // dmstatus_haveresetn_reg
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 haltsum0_reg = Cat(0.U(31.W), dmstatus_halted)
val abstractcs_reg = WireInit(2.U(32.W))
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)) | 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))
(io.dmi_reg_addr === "h17".U(7.W))) | (io.dmi_reg_addr === "h18".U(7.W))) | (io.dmi_reg_addr === 4.U(7.W)) | 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))
(io.dmi_reg_addr === 5.U(7.W))) val abstractcs_error_sel2 = io.core_dbg_cmd_done & io.core_dbg_cmd_fail
val abstractcs_error_sel1 = execute_command & ~(abstractcs_reg(10,8).orR) & val abstractcs_error_sel3 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h17".U) & !dmstatus_reg(9);
((!((command_reg(31,24) === 0.U(8.W)) | (command_reg(31,24) === 2.U(8.W)))) | // Illegal command val abstractcs_error_sel4 = (io.dmi_reg_addr === "h17".U) & io.dmi_reg_en & io.dmi_reg_wr_en &
(((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) ((io.dmi_reg_wdata(22, 20) =/= "b010".U(3.W)) | ((io.dmi_reg_wdata(31, 24) === "h2".U) && data1_reg(1, 0).orR))
((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_sel5 = (io.dmi_reg_addr === "h16".U) & io.dmi_reg_en & io.dmi_reg_wr_en
val abstractcs_error_sel2 = ((io.core_dbg_cmd_done & io.core_dbg_cmd_fail) | // exception from core val abstractcs_error_selor = abstractcs_error_sel0 | abstractcs_error_sel1 | abstractcs_error_sel2 | abstractcs_error_sel3 | abstractcs_error_sel4 | abstractcs_error_sel5
(execute_command & (command_reg(31,24) === 0.U(8.W)) & // unimplemented regs val abstractcs_error_din = (Fill(3, abstractcs_error_sel0) & "b001".U(3.W)) |
(((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) (Fill(3, abstractcs_error_sel1) & "b010".U(3.W)) |
val abstractcs_error_sel3 = execute_command & (dbg_state =/= state_t.halted) & ~(abstractcs_reg(10,8).orR) (Fill(3, abstractcs_error_sel2) & "b011".U(3.W)) |
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 (Fill(3, abstractcs_error_sel3) & "b100".U(3.W)) |
val abstractcs_error_sel5 = execute_command & (command_reg(31,24) === 2.U(8.W)) & ~(abstractcs_reg(10,8).orR) & (Fill(3, abstractcs_error_sel4) & "b111".U(3.W)) |
(((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 (Fill(3, abstractcs_error_sel5) & (~io.dmi_reg_wdata(10, 8)).asUInt() & abstractcs_reg(10, 8)) |
val abstractcs_error_sel6 = (io.dmi_reg_addr === "h16".U(7.W)) & io.dmi_reg_en & io.dmi_reg_wr_en (Fill(3, (~abstractcs_error_selor).asUInt()) & abstractcs_reg(10, 8))
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) { val abs_temp_12 = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegEnable(abstractcs_busy_din, 0.U, abstractcs_busy_wren)} // dmabstractcs_busy_reg 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) { 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 command_wren = (io.dmi_reg_addr === "h17".U) & io.dmi_reg_en & io.dmi_reg_wr_en & (dbg_state === state_t.halted)
val abstractauto_reg = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) { 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))
RegEnable(io.dmi_reg_wdata(1,0), 0.U, abstractauto_reg_wren)} // dbg_abstractauto_reg 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)) & val data0_reg_wren0 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h4".U) & (dbg_state === state_t.halted)
abstractauto_reg(0)) | ((io.dmi_reg_addr === 5.U(7.W)) & abstractauto_reg(1)))) val data0_reg_wren1 = io.core_dbg_cmd_done & (dbg_state === state_t.cmd_wait) & !command_reg(16)
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 command_postexec_din = (io.dmi_reg_wdata(31,24) === 0.U(8.W)) & io.dmi_reg_wdata(18) val data0_reg_wren = data0_reg_wren0 | data0_reg_wren1
val command_transfer_din = (io.dmi_reg_wdata(31,24) === 0.U(8.W)) & io.dmi_reg_wdata(17) val data0_din = Fill(32, data0_reg_wren0) & io.dmi_reg_wdata | Fill(32, data0_reg_wren1) & io.core_dbg_rddata
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 data0_reg = withReset(dbg_dm_rst_l) {
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) rvdffe(data0_din,data0_reg_wren,clock,io.scan_mode)
} // dbg_data0_reg } // 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_wren = (io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h5".U) & (dbg_state === state_t.halted))
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_din = Fill(32, data1_reg_wren) & io.dmi_reg_wdata
val data1_reg_wren = data1_reg_wren0 | data1_reg_wren1 data1_reg := withReset(dbg_dm_rst_l) {
rvdffe(data1_din, data1_reg_wren, clock, io.scan_mode)
val data1_din = Fill(32, data1_reg_wren0) & io.dmi_reg_wdata | Fill(32, data1_reg_wren1) & dbg_cmd_next_addr(31,0) } // dbg_data1_reg
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 dbg_nxtstate = WireInit(state_t.idle) val dbg_nxtstate = WireInit(state_t.idle)
dbg_nxtstate := state_t.idle dbg_nxtstate := state_t.idle
@ -293,126 +265,74 @@ class dbg extends Module with lib with RequireAsyncReset {
abstractcs_busy_din := false.B abstractcs_busy_din := false.B
io.dbg_halt_req := false.B io.dbg_halt_req := false.B
io.dbg_resume_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
switch(dbg_state) { switch(dbg_state) {
is(state_t.idle) { is(state_t.idle) {
dbg_nxtstate := Mux(dmstatus_reg(9) | io.dec_tlu_mpc_halted_only, state_t.halted, state_t.halting) 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)) 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).asBool() io.dbg_halt_req := (dmcontrol_reg(31) & !dmcontrol_reg(1)).asBool()
} }
is(state_t.halting) { is(state_t.halting) {
dbg_nxtstate := state_t.halted dbg_nxtstate := Mux(dmcontrol_reg(1), state_t.idle, state_t.halted)
dbg_state_en := dmstatus_reg(9) | io.dec_tlu_mpc_halted_only dbg_state_en := dmstatus_reg(9) | dmcontrol_reg(1)
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool() io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31) & (~dmcontrol_reg(1)).asUInt()).asBool()
} }
is(state_t.halted) { 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, dbg_nxtstate := Mux(dmstatus_reg(9) & !dmcontrol_reg(1),
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 Mux(dmcontrol_reg(30) & !dmcontrol_reg(31), state_t.resuming, state_t.cmd_start),
dbg_state_en := dmstatus_reg(9) & resumereq | execute_command | !(dmstatus_reg(9) | io.dec_tlu_mpc_halted_only) 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 |
abstractcs_busy_wren := dbg_state_en & ((dbg_nxtstate === state_t.core_cmd_start) | (dbg_nxtstate === state_t.sb_cmd_start)) 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 abstractcs_busy_din := "b1".U
io.dbg_resume_req := (dbg_state_en & (dbg_nxtstate === state_t.resuming)).asBool() io.dbg_resume_req := (dbg_state_en & (dbg_nxtstate === state_t.resuming)).asBool()
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool() io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31) & (~dmcontrol_reg(1)).asUInt()).asBool()
} }
is(state_t.core_cmd_start) { is(state_t.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_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 | ((command_reg(31, 24) === 0.U(8.W)) & !command_reg(17)) 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)).asBool() io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31) & (~dmcontrol_reg(1)).asUInt()).asBool()
} }
is(state_t.core_cmd_wait) { is(state_t.cmd_wait) {
dbg_nxtstate := state_t.cmd_done dbg_nxtstate := Mux(dmcontrol_reg(1), state_t.idle, state_t.cmd_done)
dbg_state_en := io.core_dbg_cmd_done dbg_state_en := io.core_dbg_cmd_done | dmcontrol_reg(1)
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool() io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31) & (~dmcontrol_reg(1)).asUInt()).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_done) { is(state_t.cmd_done) {
dbg_nxtstate := state_t.halted dbg_nxtstate := Mux(dmcontrol_reg(1), state_t.idle, state_t.halted)
dbg_state_en := true.B dbg_state_en := true.B
abstractcs_busy_wren := dbg_state_en abstractcs_busy_wren := dbg_state_en
abstractcs_busy_din := false.B abstractcs_busy_din := "b0".U
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool() io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31) & (~dmcontrol_reg(1)).asUInt()).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()
} }
is(state_t.resuming) { is(state_t.resuming) {
dbg_nxtstate := state_t.idle; dbg_nxtstate := state_t.idle;
dbg_state_en := dmstatus_reg(17) dbg_state_en := dmstatus_reg(17) | dmcontrol_reg(1)
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool() 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 | 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 === "h5".U(7.W)) & 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 === "h10".U(7.W)) & Cat(0.U(2.W), dmcontrol_reg(29), 0.U, dmcontrol_reg(27,0)) | 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 === "h11".U(7.W)) & dmstatus_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 === "h16".U(7.W)) & abstractcs_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 === "h17".U(7.W)) & command_reg | Fill(32, io.dmi_reg_addr === "h3d".U) & sbdata1_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
dbg_state := withClockAndReset(dbg_free_clk, (dbg_dm_rst_l.asBool() & temp_rst).asAsyncReset()) { dbg_state := withClockAndReset(dbg_free_clk, rst_temp) {
RegEnable(dbg_nxtstate, 0.U, dbg_state_en)} // dbg_state_reg 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 io.dmi_reg_rdata := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
val abmem_addr_core_local = (abmem_addr_in_dccm_region | abmem_addr_in_iccm_region | abmem_addr_in_pic_region) RegEnable(dmi_reg_rdata_din, 0.U, io.dmi_reg_en)
abmem_addr_external := !abmem_addr_core_local } // dmi_rddata_reg
abmem_addr_in_dccm_region := (abmem_addr(31,28) === DCCM_REGION.asUInt) & (DCCM_ENABLE==1).B 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)))
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_dctl.dbg_cmd_wrdata := data0_reg(31, 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)) | 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()
((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_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_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_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 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)
val sb_nxtstate = WireInit(sb_state_t.sbidle) val sb_nxtstate = WireInit(sb_state_t.sbidle)
sb_nxtstate := sb_state_t.sbidle sb_nxtstate := sb_state_t.sbidle
@ -425,7 +345,7 @@ class dbg extends Module with lib with RequireAsyncReset {
switch(sb_state) { switch(sb_state) {
is(sb_state_t.sbidle) { is(sb_state_t.sbidle) {
sb_nxtstate := Mux(sbdata0wr_access, sb_state_t.wait_wr, sb_state_t.wait_rd) 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_wren := sb_state_en
sbcs_sbbusy_din := true.B sbcs_sbbusy_din := true.B
sbcs_sberror_wren := sbcs_wren & io.dmi_reg_wdata(14, 12).orR sbcs_sberror_wren := sbcs_wren & io.dmi_reg_wdata(14, 12).orR
@ -433,23 +353,22 @@ class dbg extends Module with lib with RequireAsyncReset {
} }
is(sb_state_t.wait_rd) { is(sb_state_t.wait_rd) {
sb_nxtstate := Mux(sbcs_unaligned | sbcs_illegal_size, sb_state_t.done, sb_state_t.cmd_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_state_en := io.dbg_bus_clk_en | sbcs_unaligned | sbcs_illegal_size
sbcs_sberror_wren := 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) { is(sb_state_t.wait_wr) {
sb_nxtstate := Mux(sbcs_unaligned | sbcs_illegal_size, sb_state_t.done, sb_state_t.cmd_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_state_en := io.dbg_bus_clk_en | sbcs_unaligned | sbcs_illegal_size
sbcs_sberror_wren := 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) { is(sb_state_t.cmd_rd) {
sb_nxtstate := sb_state_t.rsp_rd sb_nxtstate := sb_state_t.rsp_rd
sb_state_en := sb_bus_cmd_read & io.dbg_bus_clk_en sb_state_en := sb_bus_cmd_read & io.dbg_bus_clk_en
} }
is(sb_state_t.cmd_wr) { is(sb_state_t.cmd_wr) {
sb_nxtstate := Mux(sb_bus_cmd_write_addr & sb_bus_cmd_write_data, sb_state_t.rsp_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))
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 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) { is(sb_state_t.cmd_wr_addr) {
@ -477,88 +396,64 @@ class dbg extends Module with lib with RequireAsyncReset {
sb_state_en := true.B sb_state_en := true.B
sbcs_sbbusy_wren := true.B sbcs_sbbusy_wren := true.B
sbcs_sbbusy_din := false.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) RegEnable(sb_nxtstate, 0.U, sb_state_en)
} // sb_state_reg } // 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_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_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_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_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_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.valid := sb_abmem_cmd_awvalid | sb_cmd_awvalid io.sb_axi.aw.bits.addr := sbaddress0_reg
io.sb_axi.aw.bits.addr := sb_axi_addr
io.sb_axi.aw.bits.id := 0.U io.sb_axi.aw.bits.id := 0.U
io.sb_axi.aw.bits.size := sb_axi_size io.sb_axi.aw.bits.size := sbcs_reg(19, 17)
io.sb_axi.aw.bits.prot := 1.U(3.W) io.sb_axi.aw.bits.prot := 0.U
io.sb_axi.aw.bits.cache := "b1111".U(4.W) io.sb_axi.aw.bits.cache := "b1111".U
io.sb_axi.aw.bits.region := sb_axi_addr(31, 28) io.sb_axi.aw.bits.region := sbaddress0_reg(31, 28)
io.sb_axi.aw.bits.len := 0.U io.sb_axi.aw.bits.len := 0.U
io.sb_axi.aw.bits.burst := "b01".U(2.W) io.sb_axi.aw.bits.burst := "b01".U(2.W)
io.sb_axi.aw.bits.qos := 0.U io.sb_axi.aw.bits.qos := 0.U
io.sb_axi.aw.bits.lock := false.B 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.w.valid := sb_abmem_cmd_wvalid | sb_cmd_wvalid io.sb_axi.w.bits.strb := Fill(8, (sbcs_reg(19, 17) === "h0".U)) & ("h1".U(8.W) << sbaddress0_reg(2, 0)) |
io.sb_axi.w.bits.data := Fill(64, (sb_axi_size === 0.U(3.W))) & Fill(8, (sb_axi_wrdata(7, 0))) | Fill(8, (sbcs_reg(19, 17) === "h1".U)) & ("h3".U(8.W) << Cat(sbaddress0_reg(2, 1), "b0".U)) |
Fill(64, (sb_axi_size === 1.U(3.W))) & Fill(4, sb_axi_wrdata(15, 0)) | Fill(8, (sbcs_reg(19, 17) === "h2".U)) & ("hf".U(8.W) << Cat(sbaddress0_reg(2), "b00".U(2.W))) |
Fill(64, (sb_axi_size === 2.U(3.W))) & Fill(2, (sb_axi_wrdata(31, 0))) | Fill(8, (sbcs_reg(19, 17) === "h3".U)) & "hff".U
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.w.bits.last := true.B
io.sb_axi.ar.valid := sb_abmem_cmd_arvalid | sb_cmd_arvalid io.sb_axi.ar.valid := (sb_state === sb_state_t.cmd_rd).asBool()
io.sb_axi.ar.bits.addr := sb_axi_addr io.sb_axi.ar.bits.addr := sbaddress0_reg
io.sb_axi.ar.bits.id := 0.U io.sb_axi.ar.bits.id := 0.U
io.sb_axi.ar.bits.size := sb_axi_size io.sb_axi.ar.bits.size := sbcs_reg(19, 17)
io.sb_axi.ar.bits.prot := 1.U(3.W) io.sb_axi.ar.bits.prot := 0.U
io.sb_axi.ar.bits.cache := 0.U(4.W) io.sb_axi.ar.bits.cache := 0.U
io.sb_axi.ar.bits.region := sb_axi_addr(31, 28) io.sb_axi.ar.bits.region := sbaddress0_reg(31, 28)
io.sb_axi.ar.bits.len := 0.U io.sb_axi.ar.bits.len := 0.U
io.sb_axi.ar.bits.burst := 1.U(2.W) io.sb_axi.ar.bits.burst := "b01".U(2.W)
io.sb_axi.ar.bits.qos := 0.U io.sb_axi.ar.bits.qos := 0.U
io.sb_axi.ar.bits.lock := false.B io.sb_axi.ar.bits.lock := false.B
io.sb_axi.b.ready := true.B io.sb_axi.b.ready := true.B
io.sb_axi.r.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)) | // io.dbg_dma.dbg_ib.dbg_cmd_addr := io.dbg_dec_dma.dbg_ib.dbg_cmd_addr
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)) | // io.dbg_dma.dbg_dctl.dbg_cmd_wrdata := io.dbg_dec_dma.dbg_dctl.dbg_cmd_wrdata
Fill(64, (sb_axi_size === "h3".U)) & io.sb_axi.r.bits.data(63, 0) // 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 { class dec_IO extends Bundle with lib {
val free_clk = Input(Clock()) val free_clk = Input(Clock())
val active_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 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_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 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_int = Input(Bool()) // NMI pin
val nmi_vec = Input(UInt(31.W)) // [31:1] NMI vector, from pins 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_halt_req = Input(Bool()) // Asynchronous Halt request to CPU
val i_cpu_run_req = Input(Bool()) // Asynchronous Restart 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_resume_ack = Output(Bool()) // Resume acknowledge
val dec_tlu_mpc_halted_only = Output(Bool()) // Core is halted only due to MPC 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_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_done = Output(Bool()) // abstract command is done
val dec_dbg_cmd_fail = Output(Bool()) // abstract command failed (illegal reg address) 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_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_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_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 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 // clock gating overrides from mcgc
val dec_tlu_misc_clk_override = Output(Bool()) // override misc clock domain gating 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_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_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_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_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_tlu_icm_clk_override = Output(Bool()) // override ICCM clock domain gating
val dec_i0_decode_d = Output(Bool())
val scan_mode = Input(Bool()) val scan_mode = Input(Bool())
val ifu_dec = Flipped(new ifu_dec) val ifu_dec = Flipped(new ifu_dec)
val dec_exu = Flipped(new dec_exu) 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_exc_cause_wb1 = WireInit(UInt(5.W),0.U)
val dec_tlu_mtval_wb1 = WireInit(UInt(32.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_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.ifu_ib <> io.ifu_dec.dec_aln.aln_ib
instbuff.io.ib_exu <> io.dec_exu.ib_exu instbuff.io.ib_exu <> io.dec_exu.ib_exu
instbuff.io.dbg_ib <> io.dec_dbg.dbg_ib 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.dec_i0_pc_d := instbuff.io.ib_exu.dec_i0_pc_d
dec_trigger.io.trigger_pkt_any := tlu.io.trigger_pkt_any 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 val dec_i0_trigger_match_d = dec_trigger.io.dec_i0_trigger_match_d
dontTouch(dec_i0_trigger_match_d) dontTouch(dec_i0_trigger_match_d)
decode.io.dec_aln <> io.ifu_dec.dec_aln.aln_dec 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.decode_exu<> io.dec_exu.decode_exu
decode.io.dec_alu<> io.dec_exu.dec_alu decode.io.dec_alu<> io.dec_exu.dec_alu
decode.io.dec_div<> io.dec_exu.dec_div decode.io.dec_div<> io.dec_exu.dec_div
decode.io.dctl_dma <> io.dec_dma.dctl_dma 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_flush_extint := tlu.io.dec_tlu_flush_extint
decode.io.dec_tlu_force_halt := tlu.io.tlu_mem.dec_tlu_force_halt decode.io.dec_tlu_force_halt := tlu.io.tlu_mem.dec_tlu_force_halt
decode.io.dctl_busbuff <> io.lsu_dec.dctl_busbuff 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_trigger_match_m := io.lsu_trigger_match_m
decode.io.lsu_pmu_misaligned_m := io.lsu_pmu_misaligned_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_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_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.dec_debug_fence_d := instbuff.io.dec_debug_fence_d
decode.io.dbg_dctl <> io.dec_dbg.dbg_dctl 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_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_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_dbecc_d := instbuff.io.dec_i0_dbecc_d
decode.io.dec_i0_brp := instbuff.io.dec_i0_brp 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_index := instbuff.io.dec_i0_bp_index
decode.io.dec_i0_bp_fghr := instbuff.io.dec_i0_bp_fghr 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_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_idle_any := io.lsu_idle_any
decode.io.lsu_load_stall_any := io.lsu_load_stall_any decode.io.lsu_load_stall_any := io.lsu_load_stall_any
decode.io.lsu_store_stall_any := io.lsu_store_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.exu_flush_final := io.exu_flush_final
decode.io.dec_i0_instr_d := instbuff.io.dec_i0_instr_d 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.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.active_clk := io.active_clk
decode.io.clk_override := tlu.io.dec_tlu_dec_clk_override decode.io.clk_override := tlu.io.dec_tlu_dec_clk_override
decode.io.scan_mode := io.scan_mode decode.io.scan_mode := io.scan_mode
dec_i0_inst_wb1 := decode.io.dec_i0_inst_wb //for tracer dec_i0_inst_wb1 := decode.io.dec_i0_inst_wb1 //for tracer
dec_i0_pc_wb1 := decode.io.dec_i0_pc_wb //for tracer dec_i0_pc_wb1 := decode.io.dec_i0_pc_wb1 //for tracer
io.lsu_p := decode.io.lsu_p io.lsu_p := decode.io.lsu_p
io.dec_lsu_valid_raw_d := decode.io.dec_lsu_valid_raw_d 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_lsu_offset_d := decode.io.dec_lsu_offset_d
io.dec_pause_state_cg := decode.io.dec_pause_state_cg 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
gpr.io.raddr0 := decode.io.dec_i0_rs1_d gpr.io.raddr0 := decode.io.dec_i0_rs1_d
gpr.io.raddr1 := decode.io.dec_i0_rs2_d gpr.io.raddr1 := decode.io.dec_i0_rs2_d
gpr.io.wen0 := decode.io.dec_i0_wen_r 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.wd0 := decode.io.dec_i0_wdata_r
gpr.io.wen1 := decode.io.dec_nonblock_load_wen gpr.io.wen1 := decode.io.dec_nonblock_load_wen
gpr.io.waddr1 := decode.io.dec_nonblock_load_waddr 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.wen2 := io.exu_div_wren
gpr.io.waddr2 := decode.io.div_waddr_wb gpr.io.waddr2 := decode.io.div_waddr_wb
gpr.io.wd2 := io.exu_div_result gpr.io.wd2 := io.exu_div_result
gpr.io.scan_mode := io.scan_mode gpr.io.scan_mode := io.scan_mode
io.dec_exu.gpr_exu <> gpr.io.gpr_exu io.dec_exu.gpr_exu <> gpr.io.gpr_exu
tlu.io.tlu_mem <> io.ifu_dec.dec_mem_ctrl tlu.io.tlu_mem <> io.ifu_dec.dec_mem_ctrl
tlu.io.tlu_ifc <> io.ifu_dec.dec_ifc tlu.io.tlu_ifc <> io.ifu_dec.dec_ifc
tlu.io.tlu_bp <> io.ifu_dec.dec_bp tlu.io.tlu_bp <> io.ifu_dec.dec_bp
tlu.io.tlu_exu <> io.dec_exu.tlu_exu tlu.io.tlu_exu <> io.dec_exu.tlu_exu
tlu.io.tlu_dma <> io.dec_dma.tlu_dma 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.free_clk := io.free_clk
tlu.io.scan_mode := io.scan_mode tlu.io.scan_mode := io.scan_mode
tlu.io.rst_vec := io.rst_vec 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_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_tlu_packet_r := decode.io.dec_tlu_packet_r
tlu.io.dec_illegal_inst := decode.io.dec_illegal_inst 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.exu_i0_br_way_r := io.exu_i0_br_way_r
tlu.io.dbg_halt_req := io.dbg_halt_req tlu.io.dbg_halt_req := io.dbg_halt_req
tlu.io.dbg_resume_req := io.dbg_resume_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_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_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_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.rv_trace_pkt.rv_i_insn_ip := decode.io.dec_i0_inst_wb1
io.trace_rv_trace_pkt.rv_i_address_ip := Cat(decode.io.dec_i0_pc_wb, 0.U) io.rv_trace_pkt.rv_i_address_ip := Cat(decode.io.dec_i0_pc_wb1, 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.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.trace_rv_trace_pkt.rv_i_exception_ip := tlu.io.dec_tlu_int_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.trace_rv_trace_pkt.rv_i_ecause_ip := tlu.io.dec_tlu_exc_cause_wb1(4,0) io.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.rv_trace_pkt.rv_i_interrupt_ip := Cat(tlu.io.dec_tlu_int_valid_wb1, 0.U)
io.trace_rv_trace_pkt.rv_i_tval_ip := tlu.io.dec_tlu_mtval_wb1 io.rv_trace_pkt.rv_i_tval_ip := tlu.io.dec_tlu_mtval_wb1
// debug command read data // debug command read data
io.dec_dbg_rddata := decode.io.dec_i0_wdata_r 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(_&_) pat.reduce(_&_)
} }
io.out.alu := pattern(List(30,24,23,-22,-21,-20,14,-5,4)) | pattern(List(29,-27,-24,4)) | io.out.alu := io.ins(2) | io.ins(6) | (!io.ins(25)&io.ins(4)) | (!io.ins(5)&io.ins(4))
pattern(List(-25,-13,-12,4)) | pattern(List(-30,-25,13,12)) | pattern(List(27,25,14,4)) | io.out.rs1 := pattern(List(-14,-13,-2)) | pattern(List(-13,11,-2)) |
pattern(List(29,27,-14,4)) | pattern(List(29,-14,5,4)) | pattern(List(-27,-25,14,4)) | pattern(List(19,13,-2)) | pattern(List(-13,10,-2)) |
pattern(List(30,-29,-13,4)) | pattern(List(-30,-27,-25,4)) | pattern(List(13,-5,4)) | pattern(List(18,13,-2)) | pattern(List(-13,9,-2)) |
pattern(List(-12,-5,4)) | pattern(List(2)) | pattern(List(6)) | pattern(List(30,24,23,22,21,20,-5,4)) | pattern(List(17,13,-2)) | pattern(List(-13,8,-2)) |
pattern(List(-30,29,-24,-23,22,21,20,-5,4)) | pattern(List(-30,24,-23,-22,-21,-20,-5,4)) pattern(List(16,13,-2)) | pattern(List(-13,7,-2)) |
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)) 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.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)) |
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)) 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.rd := pattern(List(-5,-2)) | pattern(List(5,2)) | pattern(List(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.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.pc := (!io.ins(5) & !io.ins(3) & io.ins(2)) | (io.ins(5) & io.ins(3))
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.load := pattern(List(-5,-4,-2)) io.out.load := pattern(List(-5,-4,-2))
io.out.store := pattern(List(-6,5,-4)) io.out.store := pattern(List(-6,5,-4))
io.out.lsu := pattern(List(-6,-4,-2)) io.out.lsu := pattern(List(-6,-4,-2))
io.out.add := pattern(List(-14,-13,-12,-5,4)) | pattern(List(-5,-3,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)) 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)) |
io.out.sub := pattern(List(30,-14,-12,-6,5,4,-2)) | pattern(List(-29,-25,-14,13,-6,4,-2)) | pattern(List(-14,13,-5,4,-2)) | pattern(List(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(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)) |
io.out.land := pattern(List(-27,-25,14,13,12,-6,-2)) | pattern(List(14,13,12,-5,-2)) pattern(List(5,4,2)) | pattern(List(-13,-12,6,4)) |
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)) | io.out.lxor := pattern(List(-25,14,-13,-12,4,-2)) | pattern(List(14,-13,-12,-5,4,-2))
pattern(List(-13,-12,6,4)) | pattern(List(14,13,-12,-5,-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.lxor := pattern(List(-29,-27,-25,14,-13,-12,4,-2)) | pattern(List(14,-13,-12,-5,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.sll := pattern(List(-29,-27,-25,-14,-13,12,-6,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)) |
io.out.sra := pattern(List(30,-29,-27,-13,12,-6,4,-2)) pattern(List(25,14,12,-6,5,-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.condbr := pattern(List(6,-4,-2)) io.out.condbr := pattern(List(6,-4,-2))
io.out.beq := pattern(List(-14,-12,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.bne := pattern(List(-14,12,6,-4,-2))
io.out.bge := pattern(List(14,12,5,-4,-2)) io.out.bge := pattern(List(14,12,5,-4,-2))
io.out.blt := 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.jal := pattern(List(6,2))
io.out.by := pattern(List(-13,-12,-6,-4,-2)) io.out.by := pattern(List(-13,-12,-6,-4,-2))
io.out.half := pattern(List(12,-6,-4,-2)) io.out.half := pattern(List(12,-6,-4,-2))
io.out.word := pattern(List(13,-6,-4)) io.out.word := pattern(List(13,-6,-4))
io.out.csr_read := pattern(List(13,6,4)) | pattern(List(7,6,4)) |
io.out.csr_read := pattern(List(13,6,4)) | pattern(List(7,6,4)) | pattern(List(8,6,4)) | pattern(List(8,6,4)) | pattern(List(9,6,4)) | pattern(List(10,6,4)) |
pattern(List(9,6,4)) | pattern(List(10,6,4)) | pattern(List(11,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)) | 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)) 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))
io.out.csr_write := pattern(List(-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)) |
io.out.csr_imm := pattern(List(14,-13,6,4)) | pattern(List(15,14,6,4)) | pattern(List(16,14,6,4)) | pattern(List(16,14,6,4)) | pattern(List(17,14,6,4)) |
pattern(List(17,14,6,4)) | pattern(List(18,14,6,4)) | pattern(List(19,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)) |
io.out.presync := pattern(List(-5,3)) | pattern(List(-13,7,6,4)) | pattern(List(-13,8,6,4)) | pattern(List(17,-12,6,4)) | pattern(List(18,-12,6,4)) |
pattern(List(-13,9,6,4)) | pattern(List(-13,10,6,4)) | pattern(List(-13,11,6,4)) | pattern(List(19,-12,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.ebreak := pattern(List(-22,20,-13,-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.ecall := pattern(List(-21,-20,-13,-12,6,4))
io.out.mret := pattern(List(29,-13,-12,6,4)) io.out.mret := pattern(List(29,-13,-12,6,4))
io.out.mul := pattern(List(25,-14,-6,5,4,-2))
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)) | io.out.rs1_sign := pattern(List(25,-14,13,-12,-6,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(25,-14,-13,12,-6,4,-2))
pattern(List(30,27,13,-6,5,4,-2)) | pattern(List(29,27,22,-20,14,-13,12,-5,4,-2)) | io.out.rs2_sign := pattern(List(25,-14,-13,12,-6,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.low := pattern(List(25,-14,-13,-12,5,4,-2)) io.out.low := pattern(List(25,-14,-13,-12,5,4,-2))
io.out.div := pattern(List(25,14,-6,5,-2))
io.out.div := pattern(List(-27,25,14,-6,5,-2)) io.out.rem := pattern(List(25,14,13,-6,5,-2))
io.out.rem := pattern(List(-27,25,14,13,-6,5,-2))
io.out.fence := pattern(List(-5,3)) io.out.fence := pattern(List(-5,3))
io.out.fence_i := pattern(List(12,-5,3)) io.out.fence_i := pattern(List(12,-5,3))
io.out.pm_alu := pattern(List(28,22,-13,-12,4)) | pattern(List(4,2)) |
io.out.clz := pattern(List(30,-27,-24,-22,-21,-20,-14,-13,12,-5,4,-2)) pattern(List(-25,-6,4)) | pattern(List(-5,4))
io.out.presync := pattern(List(-5,3)) | pattern(List(-13,7,6,4)) |
io.out.ctz := pattern(List(30,-27,-24,-22,20,-14,-13,12,-5,4,-2)) pattern(List(-13,8,6,4)) | pattern(List(-13,9,6,4)) |
pattern(List(-13,10,6,4)) | pattern(List(-13,11,6,4)) |
io.out.pcnt := pattern(List(30,-27,-24,21,-14,-13,12,-5,4,-2)) pattern(List(15,13,6,4)) | pattern(List(16,13,6,4)) |
pattern(List(17,13,6,4)) | pattern(List(18,13,6,4)) |
io.out.sext_b := pattern(List(30,-27,22,-20,-14,-13,12,-5,4,-2)) pattern(List(19,13,6,4))
io.out.postsync := pattern(List(12,-5,3)) | pattern(List(-22,-13,-12,6,4)) |
io.out.sext_h := pattern(List(30,-27,22,20,-14,-13,12,-5,4,-2)) pattern(List(-13,7,6,4)) | pattern(List(-13,8,6,4)) |
pattern(List(-13,9,6,4)) | pattern(List(-13,10,6,4)) |
io.out.slo := pattern(List(-30,29,-27,-14,-13,12,-6,4,-2)) pattern(List(-13,11,6,4)) | pattern(List(15,13,6,4)) |
pattern(List(16,13,6,4)) | pattern(List(17,13,6,4)) |
io.out.sro := pattern(List(-30,29,-27,14,-13,12,-6,4,-2)) 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)) |
io.out.min := pattern(List(27,25,14,-12,-6,5,-2)) 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.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)) |
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,-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,-30,-29,-28,-27,-26,-25,-6,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,-29,-28,-27,-26,-25,-14,-13,-12,-6,-3,-2,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,-29,-28,-27,-26,-25,14,-13,12,-6,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,-30,-29,-28,-27,-26,-6,5,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(-14,-13,-12,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(14,6,5,-4,-3,-2,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(-12,-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,5,-4,-3,-2,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(12,6,5,4,-3,-2,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,-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,-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(-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,-2,1,0)) | pattern(List(13,-6,-5,4,-3,1,0)) | pattern(List(-6,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)) |
object dec_dec extends App { pattern(List(-14,-12,-6,-4,-3,-2,1,0)) |
(new chisel3.stage.ChiselStage).emitVerilog(new dec_dec_ctl()) 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 dctl_dma = new dctl_dma //connection with dma
val dec_aln = Flipped(new aln_dec) //connection with aligner val dec_aln = Flipped(new aln_dec) //connection with aligner
val dbg_dctl = new dbg_dctl() //connection with dbg 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_flush_extint = Input(Bool())
val dec_tlu_force_halt = Input(Bool()) // invalidate nonblock load cam on a force halt event val dec_tlu_force_halt = Input(Bool()) // invalidate nonblock load cam on a force halt event
val dec_i0_inst_wb1 = Output(UInt(32.W)) // 32b instruction at wb+1 for trace encoder
val dec_i0_inst_wb = 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_pc_wb = 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_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_wr_pause_r = Input(Bool()) // pause instruction at r
val dec_tlu_pipelining_disable = Input(Bool()) // pipeline disable - presync, i0 decode only 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_tlu_flush_leak_one_r = Input(Bool()) // leak1 instruction
val dec_debug_fence_d = Input(Bool()) // debug fence 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_d = Input(Bool()) // icache access fault
val dec_i0_icaf_f1_d = Input(Bool()) // i0 instruction access fault at decode for f1 fetch group
val dec_i0_icaf_second_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_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_dbecc_d = Input(Bool()) // icache/iccm double-bit error
val dec_i0_brp = Flipped(Valid(new br_pkt_t)) // branch packet 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_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_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_btag = Input(UInt(BTB_BTAG_SIZE.W)) // BP tag
val dec_i0_pc_d = Input(UInt(31.W)) // pc
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 lsu_idle_any = Input(Bool()) // lsu idle: if fence instr & !!!!!!!!!!!!!!!!!!!!!!!!!lsu_idle then stall decode 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_load_stall_any = Input(Bool()) // stall any load at decode
val lsu_store_stall_any = Input(Bool()) // stall any store at decode6 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 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_i0_instr_d = Input(UInt(32.W)) // inst at decode
val dec_ib0_valid_d = Input(Bool()) // inst valid at decode val dec_ib0_valid_d = Input(Bool()) // inst valid at decode
val free_clk = Input(Clock())
val active_clk = Input(Clock()) // Clock only while core active. Through two clock headers. For flops without second clock header built in. val active_clk = Input(Clock()) // clk except for halt / pause
val free_l2clk = Input(Clock()) // Clock always. Through one clock header. For flops with second header built in. val clk_override = Input(Bool()) // test stuff
val clk_override = Input(Bool()) // Override non-functional clock gating
val dec_i0_rs1_d = Output(UInt(5.W)) // rs1 logical source val dec_i0_rs1_d = Output(UInt(5.W)) // rs1 logical source
val dec_i0_rs2_d = Output(UInt(5.W)) 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_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_wen_r = Output(Bool()) // i0 write enable
val dec_i0_wdata_r = Output(UInt(32.W)) // i0 write data 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 lsu_p = Valid(new lsu_pkt_t) // load/store packet
val div_waddr_wb = Output(UInt(5.W)) // DIV write address to GPR val div_waddr_wb = Output(UInt(5.W)) // DIV write address to GPR
val dec_lsu_valid_raw_d = Output(Bool()) 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_packet_r = Output(new trap_pkt_t) // trap packet
val dec_tlu_i0_pc_r = Output(UInt(31.W)) // i0 trap pc 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_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_instr_decoded = Output(Bool()) // number of instructions decode this cycle encoded
val dec_pmu_decode_stall = Output(Bool()) // decode is stalled val dec_pmu_decode_stall = Output(Bool()) // decode is stalled
val dec_pmu_presync_stall = Output(Bool()) // decode has presync stall val dec_pmu_presync_stall = Output(Bool()) // decode has presync stall
@ -112,7 +90,6 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val dec_pause_state_cg = Output(Bool()) // pause state for clock-gating val dec_pause_state_cg = Output(Bool()) // pause state for clock-gating
val dec_div_active = Output(Bool()) // non-block divide is active val dec_div_active = Output(Bool()) // non-block divide is active
val scan_mode = Input(Bool()) val scan_mode = Input(Bool())
val dec_i0_decode_d = Output(Bool())
}) })
//packets zero initialization //packets zero initialization
io.decode_exu.mul_p := 0.U.asTypeOf(io.decode_exu.mul_p) io.decode_exu.mul_p := 0.U.asTypeOf(io.decode_exu.mul_p)
@ -196,32 +173,23 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val i0_immed_d = WireInit(UInt(32.W), 0.U) val i0_immed_d = WireInit(UInt(32.W), 0.U)
val i0_result_x = 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_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 data_gate_clk = rvclkhdr(clock,data_gate_en.asBool(),io.scan_mode)
val lsu_pmu_misaligned_r = rvdffie(io.lsu_pmu_misaligned_m, io.free_l2clk, reset.asAsyncReset(), io.scan_mode) // End - Data gating
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 i0_brp_valid = io.dec_i0_brp.valid & !leak1_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.misp := 0.U
io.decode_exu.dec_i0_predict_p_d.bits.ataken := 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.boffset := 0.U
@ -236,48 +204,23 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
// no toffset error for a pret // 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_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_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 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_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.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_index_d := io.dec_i0_bp_index
io.decode_exu.i0_predict_btag_d := io.dec_i0_bp_btag 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 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.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.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 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
}
// end // end
// on br error turn anything into a nop // on br error turn anything into a nop
// on i0 instruction fetch access fault turn anything into a nop // on i0 instruction fetch access fault turn anything into a nop
// nop => alu rs1 imm12 rd lor // nop => alu rs1 imm12 rd lor
val i0_icaf_d = io.dec_i0_icaf_d | io.dec_i0_dbecc_d
val i0_instr_error = i0_icaf_d val i0_instr_error = i0_icaf_d;
i0_dp := i0_dp_raw i0_dp := i0_dp_raw
when((i0_br_error_all | i0_instr_error).asBool){ when((i0_br_error_all | i0_instr_error).asBool){
i0_dp := 0.U.asTypeOf(i0_dp) 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 io.decode_exu.dec_i0_select_pc_d := i0_dp.pc
// branches that can be predicted // 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_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_predict_t = (io.dec_i0_brp.bits.hist(1) & i0_brp_valid) & i0_predict_br
val i0_ap_pc2 = !io.dec_i0_pc4_d val i0_ap_pc2 = !io.dec_i0_pc4_d
@ -301,7 +244,6 @@ 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_nt := i0_predict_nt
io.decode_exu.i0_ap.predict_t := i0_predict_t io.decode_exu.i0_ap.predict_t := i0_predict_t
io.decode_exu.i0_ap.add := i0_dp.add io.decode_exu.i0_ap.add := i0_dp.add
io.decode_exu.i0_ap.sub := i0_dp.sub io.decode_exu.i0_ap.sub := i0_dp.sub
io.decode_exu.i0_ap.land := i0_dp.land io.decode_exu.i0_ap.land := i0_dp.land
@ -316,31 +258,6 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
io.decode_exu.i0_ap.bne := i0_dp.bne io.decode_exu.i0_ap.bne := i0_dp.bne
io.decode_exu.i0_ap.blt := i0_dp.blt io.decode_exu.i0_ap.blt := i0_dp.blt
io.decode_exu.i0_ap.bge := i0_dp.bge 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_write := i0_csr_write_only_d
io.decode_exu.i0_ap.csr_imm := i0_dp.csr_imm io.decode_exu.i0_ap.csr_imm := i0_dp.csr_imm
io.decode_exu.i0_ap.jal := i0_jal io.decode_exu.i0_ap.jal := i0_jal
@ -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){ 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 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){ when(io.dec_tlu_force_halt){
cam_in(i).valid := 0.U 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 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 -> CSRRW,
(!csr_read & csr_write).asBool -> CSRWRITE, (!csr_read & csr_write).asBool -> CSRWRITE,
( csr_read & !csr_write).asBool -> CSRREAD, ( 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.pm_alu -> ALU,
i0_dp.store -> STORE, i0_dp.store -> STORE,
i0_dp.load -> LOAD, 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 // 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_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_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 // 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.rs1_sign := i0_dp.rs1_sign
io.decode_exu.mul_p.bits.rs2_sign := i0_dp.rs2_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.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) io.lsu_p := 0.U.asTypeOf(io.lsu_p)
when (io.decode_exu.dec_extint_stall){ 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.word := 1.U(1.W)
io.lsu_p.bits.fast_int := 1.U(1.W) io.lsu_p.bits.fast_int := 1.U(1.W)
io.lsu_p.valid := 1.U(1.W) io.lsu_p.valid := 1.U(1.W)
}.otherwise { }.otherwise {
io.lsu_p.valid := lsu_decode_d io.lsu_p.valid := lsu_decode_d
io.lsu_p.bits.load := i0_dp.load 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.by := i0_dp.by
io.lsu_p.bits.half := i0_dp.half io.lsu_p.bits.half := i0_dp.half
io.lsu_p.bits.word := i0_dp.word 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.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_d := store_data_bypass_d
io.lsu_p.bits.store_data_bypass_m := store_data_bypass_m 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 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 ed as csr_read above 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 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 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 val csr_write_d = i0_csr_write & i0_legal_decode_d.asBool
i0_csr_write_only_d := i0_csr_write & !i0_dp.csr_read 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 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 ed as csr_write above //dec_csr_wen_unq_d assigned 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 := i0(31,20)
io.dec_csr_rdaddr_d := Fill(12,io.dec_csr_any_unq_d) & i0(31,20) io.dec_csr_wraddr_r := r_d.bits.csrwaddr //r_d is a dest_pkt
io.dec_csr_wraddr_r := Fill(12,(r_d.bits.csrwen & r_d.valid)) & r_d.bits.csrwaddr //r_d is a dest_pkt
// make sure csr doesn't write same cycle as dec_tlu_flush_lower_wb // make sure csr doesn't write same cycle as dec_tlu_flush_lower_wb
// also use valid so it's flushable // 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. // 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_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)} 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)} val csr_imm_x = withClock(io.active_clk){RegNext(i0_dp.csr_imm, init=0.U)}
// perform the update operation if any // 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 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 & any_csr_d.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( val csr_mask_x = Mux1H(Seq(
csr_imm_x.asBool -> Cat(repl(27,0.U),csrimm_x(4,0)), 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 // 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 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_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 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 //pause for clock gating
io.dec_pause_state_cg := (pause_state & (!tlu_wr_pause_r1 && !tlu_wr_pause_r2)) io.dec_pause_state_cg := (pause_state & (!tlu_wr_pause_r1 && !tlu_wr_pause_r2))
// end pause // 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)), 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)) 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 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 // 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 val pause_stall = pause_state
// for csr write only data is produced by the alu // 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_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) 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 // 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 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)) 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 // 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 val illegal_inst_en = shift_illegal & !illegal_lockout
io.dec_illegal_inst := rvdffe(i0_inst_d,illegal_inst_en,clock,io.scan_mode) 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_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 val i0_div_prior_div_stall = i0_dp.div & io.dec_div_active
//stalls signals //stalls signals
val i0_block_raw_d = (i0_dp.csr_read & prior_csr_write) | io.decode_exu.dec_extint_stall | pause_stall | 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 val i0_exublock_d = i0_block_raw_d
//decode valid //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_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 val i0_exulegal_decode_d = i0_exudecode_d & i0_legal
// performance monitor signals // performance monitor signals
io.dec_pmu_instr_decoded := io.dec_i0_decode_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_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_ib0_valid_d io.dec_pmu_postsync_stall := postsync_stall.asBool
io.dec_pmu_presync_stall := presync_stall.asBool & io.dec_ib0_valid_d io.dec_pmu_presync_stall := presync_stall.asBool
val prior_inflight_x = x_d.valid val prior_inflight_x = x_d.valid
val prior_inflight_wb = r_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) val prior_inflight_eff = Mux(i0_dp.div,prior_inflight_x,prior_inflight)
presync_stall := (i0_presync & prior_inflight_eff) presync_stall := (i0_presync & prior_inflight_eff)
postsync_stall := withClock(data_gate_clk){RegNext(ps_stall_in, 0.U)}
// illegals will postsync // 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.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 lsu_decode_d := i0_legal_decode_d & i0_dp.lsu
mul_decode_d := i0_exulegal_decode_d & i0_dp.mul mul_decode_d := i0_exulegal_decode_d & i0_dp.mul
div_decode_d := i0_exulegal_decode_d & i0_dp.div 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 io.dec_tlu_i0_valid_r := r_d.valid & !io.dec_tlu_flush_lower_wb
//traps for TLU (tlu stuff) //traps for TLU (tlu stuff)
d_t.legal := i0_legal_decode_d d_t.legal := i0_legal_decode_d
d_t.icaf := i0_icaf_d & i0_legal_decode_d // dbecc is icaf exception 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.icaf_type := io.dec_i0_icaf_type_d
d_t.fence_i := (i0_dp.fence_i | debug_fence_i) & i0_legal_decode_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_divide := 0.U(1.W)
d_t.pmu_lsu_misaligned := 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 := x_t
x_t_in.i0trigger := x_t.i0trigger & ~(repl(4,io.dec_tlu_flush_lower_wb)) 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 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 io.dec_tlu_packet_r.pmu_divide := r_d.bits.i0div & r_d.valid
// end tlu stuff // 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.rs2 := i0(24,20)
i0r.rd := i0(11,7) 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_jalimm20 = i0_dp.jal & i0_dp.imm20 // H:jal (used at line 915)
val i0_uiimm20 = !i0_dp.jal & i0_dp.imm20 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( 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.imm12 -> Cat(repl(20,i0(31)),i0(31,20)), // jalr
i0_dp.shimm5 -> Cat(repl(27,0.U),i0(24,20)), 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_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_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 (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) i0_legal_decode_d := io.dec_aln.dec_i0_decode_d & i0_legal
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_d_c.mul := i0_dp.mul & i0_legal_decode_d i0_d_c.mul := i0_dp.mul & i0_legal_decode_d
i0_d_c.load := i0_dp.load & 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_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)} 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_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) 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_x_data_en := ( i0_pipe_en(3) | io.clk_override)
i0_r_data_en := ( i0_pipe_en(2) | 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_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_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) io.decode_exu.dec_ctl_en := Cat(i0_x_ctl_en, i0_r_ctl_en)
d_d.bits.i0rd := i0r.rd d_d.bits.i0rd := i0r.rd
d_d.bits.i0v := i0_rd_en_d & i0_legal_decode_d 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.i0load := i0_dp.load & i0_legal_decode_d
d_d.bits.i0store := i0_dp.store & 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.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.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.csrwonly := i0_csr_write_only_d & io.dec_aln.dec_i0_decode_d
d_d.bits.csrwaddr := Mux(d_d.bits.csrwen, i0(31,20), 0.U) 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)) val x_d_in = Wire(Valid(new dest_pkt_t))
x_d_in := x_d 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.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 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 := r_d
r_d_in.bits.i0rd := r_d.bits.i0rd 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.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 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 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 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_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 io.dec_i0_wdata_r := i0_result_corr_r
val i0_result_r_raw = rvdffe(i0_result_x,i0_r_data_en.asBool,clock,io.scan_mode)
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)
if ( LOAD_TO_USE_PLUS1) { if ( LOAD_TO_USE_PLUS1) {
i0_result_x := io.decode_exu.exu_i0_result_x 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) 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 io.dec_div.dec_div_cancel := nonblock_div_cancel.asBool
val i0_div_decode_d = i0_legal_decode_d & i0_dp.div 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 // 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)) | 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.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 ///div end
//for tracing instruction //for tracing instruction
val i0_wb_en = i0_wb_data_en 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 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_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.asBool,clock,io.scan_mode)
val i0_inst_r = rvdffe(i0_inst_x,(i0_r_data_en & trace_enable),clock,io.scan_mode)
val i0_inst_wb_in = i0_inst_r 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_inst_wb = rvdffe(i0_inst_wb_in,i0_wb_en.asBool,clock,io.scan_mode)
val i0_pc_wb = rvdffe(io.dec_tlu_i0_pc_r,(i0_wb_en & trace_enable),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_wb1 := rvdffe(i0_pc_wb,i0_wb1_en.asBool,clock,io.scan_mode)
io.dec_i0_pc_wb := i0_pc_wb val dec_i0_pc_r = rvdffe(io.dec_alu.exu_i0_pc_x,i0_r_data_en.asBool,clock,io.scan_mode)
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_tlu_i0_pc_r := dec_i0_pc_r io.dec_tlu_i0_pc_r := dec_i0_pc_r
@ -913,11 +764,20 @@ 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))) 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_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(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_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_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.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.load).asBool -> i0(31,20),

View File

@ -10,8 +10,6 @@ class dec_ib_ctl_IO extends Bundle with param{
val ifu_ib = Flipped(new aln_ib) val ifu_ib = Flipped(new aln_ib)
val ib_exu = Flipped(new ib_exu) val ib_exu = Flipped(new ib_exu)
val dbg_ib = new dbg_ib 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_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_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 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_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_fghr =Output(UInt(BHT_GHR_SIZE.W)) // BP FGHR
val dec_i0_bp_btag =Output(UInt(BTB_BTAG_SIZE.W)) // BP tag 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_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_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 val dec_debug_fence_d =Output(UInt(1.W)) // debug fence inst
} }
class dec_ib_ctl extends Module with param{ class dec_ib_ctl extends Module with param{
val io=IO(new dec_ib_ctl_IO) 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_dbecc_d :=io.ifu_ib.ifu_i0_dbecc
io.dec_i0_icaf_d :=io.ifu_ib.ifu_i0_icaf io.dec_i0_icaf_d :=io.ifu_ib.ifu_i0_icaf
io.ib_exu.dec_i0_pc_d :=io.ifu_ib.ifu_i0_pc 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_index :=io.ifu_ib.ifu_i0_bp_index
io.dec_i0_bp_fghr :=io.ifu_ib.ifu_i0_bp_fghr 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_btag :=io.ifu_ib.ifu_i0_bp_btag
io.dec_i0_bp_fa_index := io.ifu_i0_fa_index
// GPR accesses // GPR accesses
// put reg to read on rs1 // 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_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_read =debug_valid & !io.dbg_ib.dbg_cmd_write
val debug_write =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_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_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) val debug_read_csr = debug_read & (io.dbg_ib.dbg_cmd_type===1.U)
@ -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_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) 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._
import chisel3.util._ import chisel3.util._
import include._ import include._
//import dbg._ import dbg._
import scala.collection._ import scala.collection._
import lib._ 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 dma_bus_clk_en = Input(Bool()) // slave bus clock enable
val clk_override = Input(Bool()) val clk_override = Input(Bool())
val scan_mode = 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_done = Output(Bool())
val dma_dbg_cmd_fail = 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_dec_dma = new dec_dbg()
val dbg_dma = new dbg_dma() val dbg_dma = new dbg_dma()
val dec_dma = Flipped(new dec_dma()) val dec_dma = Flipped(new dec_dma())
val lsu_dma = Flipped(new lsu_dma) val iccm_dma_rvalid = Input(Bool()) // iccm data valid for DMA read
val ifu_dma = Flipped(new ifu_dma)// AXI Write Channel 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 dma_axi = Flipped(new axi_channels(DMA_BUS_TAG))
val lsu_dma = Flipped(new lsu_dma)
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_byteen = WireInit(UInt(8.W), 0.U)
val bus_cmd_sz = WireInit(UInt(3.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 bus_cmd_addr = WireInit(UInt(32.W), 0.U)
val dma_free_clk = rvoclkhdr(clock,dma_free_clken,io.scan_mode)
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 bus_cmd_wdata = WireInit(UInt(64.W), 0.U)
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 bus_cmd_tag = WireInit(UInt(DMA_BUS_TAG.W), 0.U)
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 bus_cmd_mid = WireInit(UInt((DMA_BUS_ID:Int).W), 0.U)
val fifo_dbg_in = io.dbg_dec_dma.dbg_ib.dbg_cmd_valid
val bus_cmd_sent = WireInit(Bool(), false.B) val bus_cmd_prty = WireInit(UInt(DMA_BUS_PRTY.W), 0.U)
val WrPtr = WireInit(UInt(DEPTH_PTR.W), 0.U)
val RdPtr = WireInit(UInt(DEPTH_PTR.W), 0.U) val bus_posted_write_done = WireInit(UInt(1.W), 0.U)
val dma_address_error = WireInit(Bool(), false.B)
val dma_alignment_error = WireInit(Bool(), false.B) 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_cmd_en = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
val fifo_data_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_reset = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
val fifo_error_en = WireInit(UInt(DMA_BUF_DEPTH.W),0.U) val fifo_valid = 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 fifo_rpend = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
val RspPtr = WireInit(UInt((log2Ceil(DMA_BUF_DEPTH)).W), 0.U)
val bus_posted_write_done = WireInit(UInt(1.W), 0.U) val fifo_done_bus = WireInit(UInt(DMA_BUF_DEPTH.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_write = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
val fifo_done = 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_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(_,_)) 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)))))) (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))) (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)))))))
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)))))))
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(_,_)) 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)) (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) (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))})
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))}) (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))})
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_prty(i) := withClock(dma_buffer_c1_clk) {RegEnable(bus_cmd_prty, 0.U, fifo_cmd_en(i))})
// Pointer logic // Pointer logic
val NxtWrPtr = Mux((WrPtr === (DEPTH-1).U), 0.U, WrPtr+ 1.U) NxtWrPtr := Mux((WrPtr === (DMA_BUF_DEPTH - 1).U).asBool, 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) 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 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 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 RspPtrEn = (io.dma_dbg_cmd_done | (bus_rsp_sent | bus_posted_write_done) & io.dma_bus_clk_en) 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) {
RdPtr := withClock(dma_free_clk) { RegEnable(NxtRdPtr, 0.U, RdPtrEn.asBool) } 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) RspPtr := withClock(dma_free_clk) {
val fifo_full = fifo_full_spec_bus 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 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) val dma_fifo_ready = ~(fifo_full | dbg_dma_bubble_bus)
// Error logic // 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) === 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) === 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 ((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) === 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 (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 (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 //Dbg outputs
io.dbg_dma.dma_dbg_ready := fifo_empty & io.dbg_dma.dbg_dma_bubble
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_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 io.dma_dbg_cmd_fail := fifo_error(RspPtr).orR
val dma_dbg_sz = fifo_sz(RspPtr)(1,0) 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
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))
// 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 ))
// Block the decode if fifo full // 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 // Core outputs
dma_mem_req := fifo_valid(RdPtr) & ~fifo_rpend(RdPtr) & ~fifo_done(RdPtr) & ~(dma_address_error | dma_alignment_error | dma_dbg_cmd_error)
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.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.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.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_addr_int := fifo_addr(RdPtr)
dma_mem_sz_int := fifo_sz(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 := 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_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 & ((dma_mem_byteen(7,0) === "h0f".U) | (dma_mem_byteen(7,0) === "hf0".U)), 2.U, dma_mem_sz_int(2,0))
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) 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_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_lsc_ctl.dma_mem_wdata := fifo_data(RdPtr)
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
// PMU outputs // 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_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 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 // 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) fifo_full_spec_bus := withClock(dma_bus_clk) {
dma_dbg_cmd_done_q := withClock(io.free_clk){ RegNext(io.dma_dbg_cmd_done,0.U)} 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 // Write channel buffer
val wrbuf_en = io.dma_axi.aw.valid & io.dma_axi.aw.ready 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_data_en = io.dma_axi.w.valid & io.dma_axi.w.ready
val wrbuf_cmd_sent = bus_cmd_sent & bus_cmd_write val wrbuf_cmd_sent = bus_cmd_sent & bus_cmd_write
val wrbuf_rst = wrbuf_cmd_sent & ~wrbuf_en val wrbuf_rst = wrbuf_cmd_sent.asBool & !wrbuf_en
val wrbuf_data_rst = wrbuf_cmd_sent & ~wrbuf_data_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_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_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_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_byteen = withClock(dma_bus_clk) {
RegEnable(io.dma_axi.w.bits.strb, 0.U, wrbuf_data_en)
}
// Read channel buffer // 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_en = io.dma_axi.ar.valid & io.dma_axi.ar.ready
val rdbuf_tag = rvdffs_fpga(io.dma_axi.ar.bits.id,rdbuf_en,dma_bus_clk,io.dma_bus_clk_en,clock) val rdbuf_cmd_sent = bus_cmd_sent & !bus_cmd_write
val rdbuf_sz = rvdffs_fpga(io.dma_axi.ar.bits.size,rdbuf_en,dma_bus_clk,io.dma_bus_clk_en,clock) val rdbuf_rst = rdbuf_cmd_sent.asBool & !rdbuf_en
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) 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.aw.ready := ~(wrbuf_vld & !wrbuf_cmd_sent)
io.dma_axi.w.ready := ~(wrbuf_data_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) io.dma_axi.ar.ready := ~(rdbuf_vld & !rdbuf_cmd_sent)
//Generate a single request from read/write channel //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_valid := (wrbuf_vld & wrbuf_data_vld) | rdbuf_vld
bus_cmd_sent := bus_cmd_valid & dma_fifo_ready bus_cmd_sent := bus_cmd_valid & dma_fifo_ready.asUInt
bus_cmd_write := axi_mstr_sel bus_cmd_write := axi_mstr_sel
bus_cmd_posted_write := 0.U bus_cmd_posted_write := 0.U;
bus_cmd_addr := Mux(axi_mstr_sel, wrbuf_addr, rdbuf_addr) bus_cmd_addr := Mux(axi_mstr_sel.asBool, wrbuf_addr, rdbuf_addr)
bus_cmd_sz := Mux(axi_mstr_sel, wrbuf_sz, rdbuf_sz) bus_cmd_sz := Mux(axi_mstr_sel.asBool, wrbuf_sz, rdbuf_sz)
bus_cmd_wdata := wrbuf_data bus_cmd_wdata := wrbuf_data
bus_cmd_byteen := wrbuf_byteen bus_cmd_byteen := wrbuf_byteen
bus_cmd_tag := Mux(axi_mstr_sel, wrbuf_tag, rdbuf_tag) bus_cmd_tag := Mux(axi_mstr_sel.asBool, wrbuf_tag, rdbuf_tag)
bus_cmd_mid := 0.U bus_cmd_mid := 0.U
bus_cmd_prty := 0.U bus_cmd_prty := 0.U
// Sel=1 -> write has higher priority // 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) ) 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_in = ~axi_mstr_priority
val axi_mstr_prty_en = bus_cmd_sent 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) 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_rdata = fifo_data(RspPtr)
val axi_rsp_write = fifo_write(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_error = Mux(fifo_error(RspPtr)(0), 2.U, Mux(fifo_error(RspPtr)(1), 3.U, 0.U));
val axi_rsp_tag = fifo_tag(RspPtr) val axi_rsp_tag = fifo_tag(RspPtr)
// AXI response channel signals // AXI response channel signals
io.dma_axi.b.valid := axi_rsp_valid & axi_rsp_write 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.resp := axi_rsp_error(1,0)
io.dma_axi.b.bits.id := axi_rsp_tag io.dma_axi.b.bits.id := axi_rsp_tag
io.dma_axi.r.valid := axi_rsp_valid & ~axi_rsp_write 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.resp := axi_rsp_error
io.dma_axi.r.bits.data := axi_rsp_rdata io.dma_axi.r.bits.data := axi_rsp_rdata(63,0)
io.dma_axi.r.bits.last := 1.U io.dma_axi.r.bits.last := 1.U
io.dma_axi.r.bits.id := axi_rsp_tag io.dma_axi.r.bits.id := axi_rsp_tag
bus_posted_write_done := 0.U bus_posted_write_done := 0.U
bus_rsp_valid := (io.dma_axi.b.valid | io.dma_axi.r.valid) 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) 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.dma_active := wrbuf_vld | rdbuf_vld | (fifo_valid.orR) 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
object DMA extends App { io.ifu_dma.dma_mem_ctl.dma_mem_wdata := io.lsu_dma.dma_lsc_ctl.dma_mem_wdata
println((new chisel3.stage.ChiselStage).emitVerilog(new dma_ctrl)) 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 val exu_div_wren = Output(UInt(1.W)) // Divide write enable to GPR
//debug //debug
val dbg_cmd_wrdata = Input(UInt(32.W)) // Debug data to primary I0 RS1 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 //lsu
val lsu_exu = Flipped(new lsu_exu()) val lsu_exu = Flipped(new lsu_exu())
//ifu_ifc //ifu_ifc
val exu_flush_path_final = Output(UInt(31.W)) // Target for the oldest flush source 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 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 i0_taken_d = Wire(UInt(1.W))
val mul_valid_x = Wire(UInt(1.W)) val mul_valid_x = Wire(UInt(1.W))
val i0_valid_d = 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_predict_newp_d = Wire(Valid(new predict_pkt_t()))
val i0_flush_path_d = Wire(UInt(31.W)) val i0_flush_path_d = Wire(UInt(31.W))
val i0_predict_p_d = Wire(Valid(new predict_pkt_t())) val i0_predict_p_d = Wire(Valid(new predict_pkt_t()))
@ -53,47 +54,52 @@ class exu extends Module with lib with RequireAsyncReset{
i0_pp_r.bits.toffset := 0.U i0_pp_r.bits.toffset := 0.U
val x_data_en = io.dec_exu.decode_exu.dec_data_en(1) 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 = 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 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 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 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 i0_flush_path_x =rvdffe(i0_flush_path_d,x_data_en.asBool,clock,io.scan_mode)
val predpipe_x =rvdffe(predpipe_d,x_data_en_q2.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)
val predpipe_r =rvdffe(predpipe_x ,r_data_en_q2.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 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_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_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_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) 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) i0_pp_r :=rvdffe(i0_predict_p_x,r_ctl_en.asBool,clock,io.scan_mode)
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 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 =rvdffppe_UInt(i0_pred_correct_upper_x ,clock,reset.asAsyncReset(),r_ctl_en.asBool,io.scan_mode,WIDTH=1) 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 =rvdffpcie(i0_flush_path_x ,r_data_en.asBool,reset.asAsyncReset(),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 =rvdffpcie(io.dec_exu.decode_exu.pred_correct_npc_x(30,6) ,r_data_en.asBool,reset.asAsyncReset(),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) 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) when (BHT_SIZE.asUInt===32.U || BHT_SIZE.asUInt===64.U){
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) 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( 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(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.lsu_exu.lsu_result_m, io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(1).asBool -> io.dec_exu.decode_exu.exu_i0_result_x
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
)) ))
val i0_rs2_bypass_data_d = Mux1H(Seq( 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(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.lsu_exu.lsu_result_m, io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(1).asBool -> io.dec_exu.decode_exu.exu_i0_result_x
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
)) ))
val i0_rs1_d = Mux1H(Seq( val i0_rs1_d = Mux1H(Seq(
@ -102,7 +108,6 @@ class exu extends Module with lib with RequireAsyncReset{
(!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).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 (!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 & io.dec_exu.decode_exu.dec_i0_rs2_en_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs2_d,
@ -112,14 +117,14 @@ class exu extends Module with lib with RequireAsyncReset{
dontTouch(i0_rs2_d) dontTouch(i0_rs2_d)
io.lsu_exu.exu_lsu_rs1_d:=Mux1H(Seq( 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_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 & io.dec_exu.decode_exu.dec_qual_lsu_d).asBool -> i0_rs1_bypass_data_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 & io.dec_exu.decode_exu.dec_qual_lsu_d).asBool -> Cat(io.dec_exu.tlu_exu.dec_tlu_meihap,0.U(2.W)) (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( 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_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 & 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).asBool -> i0_rs2_bypass_data_d
)) ))
val muldiv_rs1_d=Mux1H(Seq( val muldiv_rs1_d=Mux1H(Seq(
@ -127,14 +132,21 @@ class exu extends Module with lib with RequireAsyncReset{
(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()) val i_alu=Module(new exu_alu_ctl())
i_alu.io.dec_alu <> io.dec_exu.dec_alu i_alu.io.dec_alu <> io.dec_exu.dec_alu
i_alu.io.scan_mode :=io.scan_mode i_alu.io.scan_mode :=io.scan_mode
i_alu.io.enable :=x_data_en i_alu.io.enable :=x_ctl_en
i_alu.io.pp_in :=i0_predict_newp_d i_alu.io.pp_in :=i0_predict_newp_d
i_alu.io.flush_upper_x :=i0_flush_upper_x 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.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.a_in :=i0_rs1_d.asSInt
i_alu.io.b_in :=i0_rs2_d i_alu.io.b_in :=i0_rs2_d
@ -150,16 +162,16 @@ class exu extends Module with lib with RequireAsyncReset{
val i_mul = Module(new exu_mul_ctl()) val i_mul = Module(new exu_mul_ctl())
i_mul.io.scan_mode := io.scan_mode 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 := 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
i_mul.io.rs1_in := muldiv_rs1_d & Fill(32,io.dec_exu.decode_exu.mul_p.valid) i_mul.io.rs2_in := muldiv_rs2_d
i_mul.io.rs2_in := i0_rs2_d & Fill(32,io.dec_exu.decode_exu.mul_p.valid)
val mul_result_x = i_mul.io.result_x val mul_result_x = i_mul.io.result_x
val i_div = Module(new exu_div_ctl()) val i_div = Module(new exu_div_ctl())
i_div.io.dec_div <> io.dec_exu.dec_div 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.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_wren := i_div.io.exu_div_wren
io.exu_div_result := i_div.io.exu_div_result io.exu_div_result := i_div.io.exu_div_result
@ -176,7 +188,7 @@ 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) 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 // maintain GHR at D
ghr_d_ns:=Mux1H(Seq( 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 -> Cat(ghr_d(BHT_GHR_SIZE-2,0),i0_taken_d),
@ -190,7 +202,7 @@ class exu extends Module with lib with RequireAsyncReset{
io.dec_exu.tlu_exu.exu_i0_br_valid_r := i0_pp_r.valid 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.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.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_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_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_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.dec_exu.tlu_exu.exu_i0_br_start_error_r := i0_pp_r.bits.br_start_error
@ -202,7 +214,7 @@ class exu extends Module with lib with RequireAsyncReset{
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) 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.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.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.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.pcall := final_predict_mp.bits.pcall
@ -217,32 +229,7 @@ class exu extends Module with lib with RequireAsyncReset{
io.exu_bp.exu_mp_index := final_predpipe_mp(PREDPIPESIZE-BHT_GHR_SIZE-1,BTB_BTAG_SIZE) 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_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_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)
else {
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.dec_exu.tlu_exu.exu_npc_r := Mux(i0_pred_correct_upper_r===1.U, pred_correct_npc_r, i0_flush_path_upper_r) 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 io = IO(new Bundle{
val dec_alu = new dec_alu() 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 dec_i0_pc_d = Input(UInt(31.W)) // for pc=pc+2,4 calculations
val scan_mode = Input(UInt(1.W)) // Scan control val scan_mode = Input(UInt(1.W)) // Scan control
val flush_upper_x = Input(UInt(1.W)) // Branch flush from previous cycle 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 pred_correct_out = Output(UInt(1.W)) // NPC control
val predict_p_out = Valid(new predict_pkt_t) // Predicted branch structure 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 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 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
val result = WireInit(UInt(32.W),0.U) 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) io.result_ff := rvdffe(result,io.enable,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 ))
val bm = Mux( io.i0_ap.sub.asBool, ~io.b_in, io.b_in) //H:b modified 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) 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 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 val ov = (!io.a_in(31) & !bm(31) & aout(31)) | ( io.a_in(31) & bm(31) & !aout(31) ) //overflow check from last bits
@ -156,142 +47,30 @@ class exu_alu_ctl extends Module with lib with RequireAsyncReset{
val lout = Mux1H(Seq( val lout = Mux1H(Seq(
io.dec_alu.dec_csr_ren_d -> io.csr_rddata_in.asSInt , io.dec_alu.dec_csr_ren_d.asBool -> io.b_in.asSInt, //read enable read rs2
(io.i0_ap.land & !ap_zbb).asBool -> (Cat(0.U(1.W),io.a_in).asSInt & io.b_in.asSInt) , io.i0_ap.land.asBool -> (io.a_in & io.b_in.asSInt), //and rs1 and 2
(io.i0_ap.lor & !ap_zbb).asBool -> (Cat(0.U(1.W),io.a_in).asSInt | io.b_in.asSInt) , io.i0_ap.lor.asBool -> (io.a_in | 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.lxor.asBool -> (io.a_in ^ 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 shift_amount = Mux1H(Seq ( 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.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.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)) , 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)) ))
val shift_mask = WireInit(UInt(32.W),0.U) 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) 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((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)
val shift_long = WireInit(UInt(63.W),0.U) 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 val sout = ( shift_long(31,0) & 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 bitmanip_sext_result = Mux1H(Seq(ap_sext_b -> Cat( Fill(24,io.a_in(7)) ,io.a_in(7,0)), val sel_shift = io.i0_ap.sll | io.i0_ap.srl | io.i0_ap.sra
ap_sext_h -> Cat( Fill(16,io.a_in(15)),io.a_in(15,0))) ) val sel_adder = (io.i0_ap.add | io.i0_ap.sub) & !io.i0_ap.slt
// * * * * * * * * * * * * * * * * * * 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_pc = io.i0_ap.jal | io.pp_in.bits.pcall | io.pp_in.bits.pja | io.pp_in.bits.pret 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) 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 // 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)) 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)) | result := lout(31,0) | Cat(0.U(31.W),slt_one) | (Mux1H(Seq(
(Fill(32,sel_adder) & aout(31,0)) | sel_shift.asBool -> sout(31,0),
(Fill(32,sel_pc) & pcout ) | sel_adder.asBool -> aout(31,0),
(Fill(32,io.i0_ap.csr_write) & csr_write_data(31,0)) | sel_pc.asBool -> pcout,
Cat(0.U(31.W), slt_one) | io.i0_ap.csr_write.asBool -> csr_write_data(31,0))))
(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))))
// *** branch handling *** // *** 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.ataken := actual_taken; // send a control signal telling it branch taken or not
io.predict_p_out.bits.hist := newhist io.predict_p_out.bits.hist := newhist
} }

View File

@ -1,6 +1,6 @@
package exu package exu
import chisel3.{util, _} import chisel3._
import chisel3.experimental.chiselName import chisel3.experimental.chiselName
import chisel3.util._ import chisel3.util._
import include._ import include._
@ -16,86 +16,6 @@ class exu_div_ctl extends Module with RequireAsyncReset with lib {
val exu_div_wren = Output(UInt(1.W)) val exu_div_wren = Output(UInt(1.W))
val dec_div = new dec_div() 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 run_state = WireInit(0.U(1.W)) val run_state = WireInit(0.U(1.W))
val count = WireInit(0.U(6.W)) val count = WireInit(0.U(6.W))
val m_ff = WireInit(0.U(33.W)) val m_ff = WireInit(0.U(33.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 rem_ff = WireInit(0.U(1.W))
val add = WireInit(0.U(1.W)) val add = WireInit(0.U(1.W))
val a_eff = WireInit(0.U(33.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 rem_correct = WireInit(0.U(1.W))
val valid_ff_x = WireInit(0.U(1.W)) val valid_ff_x = WireInit(0.U(1.W))
val finish_ff = 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 count_in = WireInit(0.U(6.W))
val dividend_eff = WireInit(0.U(32.W)) val dividend_eff = WireInit(0.U(32.W))
val a_shift = WireInit(0.U(33.W)) val a_shift = WireInit(0.U(33.W))
val shortq = WireInit(0.U(6.W)) val valid_x = valid_ff_x & !io.dec_div.dec_div_cancel
val valid_x = valid_ff_x & !io.cancel
// START - short circuit logic for small numbers {{ // START - short circuit logic for small numbers {{
// small number divides - any 4b / 4b is done in 1 cycle (divisor != 0) // 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) ((q_ff(31,0) === 0.U) & (m_ff(31,0) =/= 0.U) & !rem_ff & valid_x)
def pat(x : List[Int], y : List[Int]) = { 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 pat1 = (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(_&_) val pat2 = (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 pat1 & pat2
} }
val smallnum = Cat( val smallnum = Cat(
@ -168,7 +87,7 @@ class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset wi
short_dividend := Cat (sign_ff & q_ff(31),q_ff(31,0)) 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 ( Mux1H(Seq (
!short_dividend(32).asBool -> (short_dividend(31,24) =/= Fill(8,0.U)), !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))
@ -182,7 +101,7 @@ class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset wi
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 ( Mux1H(Seq (
!m_ff(32).asBool -> (m_ff(31,24) =/= Fill(8,0.U)), !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))
@ -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_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 = Fill(4,shortq_enable) & shortq_raw
val shortq_shift_ff = Cat(0.U(1.W),Mux1H(Seq (
val shortq_shift_ff = Mux1H(Seq (
shortq_shift_xx(3).asBool -> "b11111".U, shortq_shift_xx(3).asBool -> "b11111".U,
shortq_shift_xx(2).asBool -> "b11000".U, shortq_shift_xx(2).asBool -> "b11000".U,
shortq_shift_xx(1).asBool -> "b10000".U, shortq_shift_xx(1).asBool -> "b10000".U,
shortq_shift_xx(0).asBool -> "b01000".U shortq_shift_xx(0).asBool -> "b01000".U
))) ))
// *** End Short *** }} // *** End Short *** }}
val finish = smallnum_case | Mux(!rem_ff ,count === 32.U(6.W) ,count === 33.U(6.W)) 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 div_clken = io.dec_div.div_p.valid | run_state | finish | finish_ff
val run_in = (io.valid_in | run_state) & !finish & !io.cancel 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.cancel & !shortq_enable)) & (count + Cat(0.U,shortq_shift_ff(4,0)) + (1.U)(6.W)) 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.valid_out := finish_ff & !io.cancel //io.test := count_in
val sign_eff = io.signed_in & (io.divisor_in =/= 0.U(32.W))
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( q_in := Mux1H(Seq(
(!run_state).asBool -> Cat(0.U(1.W),io.dividend_in) , (!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(4,0)) , (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)) (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)) 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 ) 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( a_eff := Mux1H(Seq(
rem_correct.asBool -> a_ff , 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 -> 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_shift := Fill(33,run_state) & a_eff
a_in := Fill(33,run_state) & (a_shift + m_eff + Cat(0.U(32.W),!add)) 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 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 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)) 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), smallnum_case_ff.asBool -> Cat(0.U(28.W), smallnum_ff),
rem_ff.asBool -> a_ff_eff , rem_ff.asBool -> a_ff_eff ,
(!smallnum_case_ff & !rem_ff).asBool -> q_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)
val exu_div_cgc = rvclkhdr(clock,div_clken.asBool,io.scan_mode)
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)
} }
/////////////////////////////////////////////// 1 BIT FULL DIVIDER////////////////////////////////// q_ff := rvdffe(q_in, qff_enable.asBool,clock,io.scan_mode)
class exu_div_new_1bit_fullshortq extends Module with RequireAsyncReset with lib { a_ff := rvdffe(a_in, aff_enable.asBool,clock,io.scan_mode)
val io = IO(new Bundle{ 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)
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 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
}
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)
} }

View File

@ -4,7 +4,7 @@ import chisel3._
import chisel3.util._ import chisel3.util._
import include._ import include._
import lib._ import lib._
import chisel3.stage.ChiselStage
class exu_mul_ctl extends Module with RequireAsyncReset with lib { class exu_mul_ctl extends Module with RequireAsyncReset with lib {
val io = IO(new Bundle{ 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 prod_x = WireInit(SInt(66.W), 0.S)
val low_x = WireInit(0.U(1.W)) 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 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 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 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) rs2_x := rvdffe (rs2_ext_in, mul_x_enable.asBool,clock,io.scan_mode)
prod_x := rs1_x * rs2_x prod_x := rs1_x * rs2_x
io.result_x := Mux1H (Seq(!low_x.asBool -> prod_x(63,32), low_x.asBool -> prod_x(31,0)))
// * * * * * * * * * * * * * * * * * * 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
}
object mul extends App {
println((new ChiselStage).emitVerilog(new exu_mul_ctl))}

View File

@ -9,14 +9,9 @@ import include._
@chiselName @chiselName
class ifu extends Module with lib with RequireAsyncReset { class ifu extends Module with lib with RequireAsyncReset {
val io = IO(new Bundle{ 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_final = Input(Bool())
val exu_flush_path_final = Input(UInt(31.W)) val exu_flush_path_final = Input(UInt(31.W))
val free_l2clk = Input(Clock()) val free_clk = Input(Clock())
val active_clk = Input(Clock()) val active_clk = Input(Clock())
val ifu_dec = new ifu_dec() // IFU and DEC interconnects val ifu_dec = new ifu_dec() // IFU and DEC interconnects
val exu_ifu = new exu_ifu() // IFU and EXU 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) val ifc_ctl = Module(new ifu_ifc_ctl)
// IFC wiring Inputs // 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.scan_mode := io.scan_mode
ifc_ctl.io.ic_hit_f := mem_ctl.io.ic_hit_f ifc_ctl.io.ic_hit_f := mem_ctl.io.ic_hit_f
ifc_ctl.io.ifu_fb_consume1 := aln_ctl.io.ifu_fb_consume1 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.ifu_bp_ret_f := bp_ctl.io.ifu_bp_ret_f
aln_ctl.io.exu_flush_final := io.exu_flush_final aln_ctl.io.exu_flush_final := io.exu_flush_final
aln_ctl.io.dec_aln <> io.ifu_dec.dec_aln 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_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_val := mem_ctl.io.ifu_fetch_val
aln_ctl.io.ifu_fetch_pc := ifc_ctl.io.ifc_fetch_addr_f aln_ctl.io.ifu_fetch_pc := ifc_ctl.io.ifc_fetch_addr_f
// BP wiring Inputs // BP wiring Inputs
bp_ctl.io.scan_mode := io.scan_mode 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.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_addr_f := ifc_ctl.io.ifc_fetch_addr_f
bp_ctl.io.ifc_fetch_req_f := ifc_ctl.io.ifc_fetch_req_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_bp <> io.exu_ifu.exu_bp
bp_ctl.io.exu_flush_final := io.exu_flush_final 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_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 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.active_clk := io.active_clk
mem_ctl.io.exu_flush_final := io.exu_flush_final mem_ctl.io.exu_flush_final := io.exu_flush_final
mem_ctl.io.dec_mem_ctrl <> io.ifu_dec.dec_mem_ctrl 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

@ -9,27 +9,9 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
val scan_mode = Input(Bool()) val scan_mode = Input(Bool())
val active_clk = Input(Clock()) val active_clk = Input(Clock())
val ifu_async_error_start = Input(Bool()) // Error coming from mem-ctl 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 iccm_rd_ecc_double_err = Input(Bool()) // ICCM double error coming from mem-ctl
val ic_access_fault_f = Input(UInt(2.W)) // Access fault in I$ 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 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_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_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 val ifu_bp_poffset_f = Input(UInt(12.W)) // Offset to the current PC for branch
@ -40,6 +22,7 @@ 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_valid_f = Input(UInt(2.W)) // Valid Branch prediction
val ifu_bp_ret_f = Input(UInt(2.W)) // BP ret val ifu_bp_ret_f = Input(UInt(2.W)) // BP ret
val exu_flush_final = Input(Bool()) // Miss prediction 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_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_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_fetch_pc = Input(UInt(31.W)) // Current PC
@ -48,11 +31,10 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
val ifu_fb_consume2 = Output(Bool()) // FP used 2 val ifu_fb_consume2 = Output(Bool()) // FP used 2
}) })
val MHI = 1 + (BTB_ENABLE * (43+BHT_GHR_SIZE)) val MHI = 46+BHT_GHR_SIZE // 54
val MSIZE = 2 + (BTB_ENABLE * (43+BHT_GHR_SIZE)) val MSIZE = 47+BHT_GHR_SIZE // 55
val BRDATA_SIZE = if(BTB_ENABLE) 16+log2Ceil(BTB_SIZE) * 2 * BTB_FULLYA else 2 val BRDATA_SIZE = 12
val BRDATA_WIDTH = if(BTB_ENABLE) 8+log2Ceil(BTB_SIZE)*BTB_FULLYA else 1 val error_stall_in = WireInit(Bool(),0.U)
val alignval = WireInit(UInt(2.W), 0.U) val alignval = WireInit(UInt(2.W), 0.U)
val q0final = WireInit(UInt(32.W), 0.U) val q0final = WireInit(UInt(32.W), 0.U)
val q1final = WireInit(UInt(16.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_f2_f0 = WireInit(Bool(), init = 0.U)
val shift_f1_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 f0icaf = WireInit(Bool(), init = 0.U)
val f1icaf = WireInit(UInt(2.W), init = 0.U) val f1icaf = WireInit(Bool(), init = 0.U)
val sf0val = WireInit(UInt(2.W), 0.U) val sf0val = WireInit(UInt(2.W), 0.U)
val sf1val = 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 misc1 = WireInit(UInt((MHI+1).W), 0.U)
val misc2 = 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 brdata1 = WireInit(UInt(12.W), init = 0.U)
val brdata0 = WireInit(UInt(BRDATA_SIZE.W), init = 0.U) val brdata0 = WireInit(UInt(12.W), init = 0.U)
val brdata2 = WireInit(UInt(BRDATA_SIZE.W), init = 0.U) val brdata2 = WireInit(UInt(12.W), init = 0.U)
val q0 = WireInit(UInt(32.W), init = 0.U) val q0 = WireInit(UInt(32.W), init = 0.U)
val q1 = WireInit(UInt(32.W), init = 0.U) val q1 = WireInit(UInt(32.W), init = 0.U)
@ -112,24 +94,29 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
val first4B = WireInit(Bool(), 0.U) val first4B = WireInit(Bool(), 0.U)
val shift_2B = WireInit(Bool(), 0.U) val shift_2B = WireInit(Bool(), 0.U)
val f0_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 // 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)} 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)} 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 q2off = withClock(io.active_clk) {RegNext(q2off_in, init = 0.U)}
val q1off = withClock(io.active_clk) {RegNext(q1off_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)} val q0off = withClock(io.active_clk) {RegNext(q0off_in, init = 0.U)}
// Instrution PC to the FP
// Flop the stall until flush val f2pc = rvdffe(io.ifu_fetch_pc, f2_wr_en.asBool, clock, io.scan_mode)
error_stall := rvdffie(error_stall_in,clock,reset.asAsyncReset(),io.scan_mode) val f1pc = rvdffe(f1pc_in, f1_shift_wr_en.asBool, clock, io.scan_mode)
val f2val = rvdffie(f2val_in,clock,reset.asAsyncReset(),io.scan_mode) val f0pc = rvdffe(f0pc_in, f0_shift_wr_en.asBool, clock, 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)
// Branch data to the FP // Branch data to the FP
if(BTB_ENABLE){
brdata2 := rvdffe(brdata_in, qwen(2), clock, io.scan_mode) brdata2 := rvdffe(brdata_in, qwen(2), clock, io.scan_mode)
brdata1 := rvdffe(brdata_in, qwen(1), clock, io.scan_mode) brdata1 := rvdffe(brdata_in, qwen(1), clock, io.scan_mode)
brdata0 := rvdffe(brdata_in, qwen(0), clock, io.scan_mode) brdata0 := rvdffe(brdata_in, qwen(0), clock, io.scan_mode)
@ -137,30 +124,22 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
misc2 := rvdffe(misc_data_in, qwen(2), clock, io.scan_mode) misc2 := rvdffe(misc_data_in, qwen(2), clock, io.scan_mode)
misc1 := rvdffe(misc_data_in, qwen(1), 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) 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)
}
// Instruction in the FP // Instruction in the FP
q2 := rvdffe(io.ifu_fetch_data_f, qwen(2), 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) 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) 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) // Shift FP logic
val q1pc = rvdffe(io.ifu_fetch_pc, qwen(1),clock,io.scan_mode) f2_wr_en := fetch_to_f2
val q0pc = rvdffe(io.ifu_fetch_pc, qwen(0),clock,io.scan_mode) 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) 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, 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(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, (qren(2) & io.ifu_fb_consume1 & !io.exu_flush_final).asBool -> 0.U,
@ -169,7 +148,7 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
(qren(2) & io.ifu_fb_consume2 & !io.exu_flush_final).asBool -> 1.U, (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)) (!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, wrptr_in := Mux1H(Seq((qwen(0) & !io.exu_flush_final).asBool -> 1.U,
(qwen(1) & !io.exu_flush_final).asBool -> 2.U, (qwen(1) & !io.exu_flush_final).asBool -> 2.U,
(qwen(2) & !io.exu_flush_final).asBool -> 0.U, (qwen(2) & !io.exu_flush_final).asBool -> 0.U,
@ -187,8 +166,6 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
(!qwen(0) & (rdptr===2.U)).asBool -> (q0off.asUInt | f1_shift_2B), (!qwen(0) & (rdptr===2.U)).asBool -> (q0off.asUInt | f1_shift_2B),
(!qwen(0) & (rdptr===1.U)).asBool -> q0off)) (!qwen(0) & (rdptr===1.U)).asBool -> q0off))
// Shift FP logic
val q0ptr = Mux1H(Seq((rdptr===0.U)->q0off, val q0ptr = Mux1H(Seq((rdptr===0.U)->q0off,
(rdptr===1.U)->q1off, (rdptr===1.U)->q1off,
(rdptr===2.U)->q2off)) (rdptr===2.U)->q2off))
@ -199,13 +176,8 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
val q1sel = Cat(q1ptr, !q1ptr) val q1sel = Cat(q1ptr, !q1ptr)
// Misc data error, access-fault, type of fault, target, offset and ghr value // Misc data error, access-fault, type of fault, target, offset and ghr value
misc_data_in := Cat(io.iccm_rd_ecc_double_err, io.ic_access_fault_f, io.ic_access_fault_type_f,
if(BTB_ENABLE){ io.ifu_bp_btb_target_f, io.ifu_bp_poffset_f, io.ifu_bp_fghr_f)
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
}
val misceff = Mux1H(Seq(qren(0).asBool() -> Cat(misc1, misc0), val misceff = Mux1H(Seq(qren(0).asBool() -> Cat(misc1, misc0),
qren(1).asBool()->Cat(misc2, misc1), qren(1).asBool()->Cat(misc2, misc1),
@ -214,111 +186,48 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
val misc1eff = misceff(misceff.getWidth-1,MHI+1) val misc1eff = misceff(misceff.getWidth-1,MHI+1)
val misc0eff = misceff(MHI, 0) 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 f1dbecc = misc1eff(misc1eff.getWidth-1)
val f0prett = if(BTB_ENABLE) misc0eff(misc0eff.getWidth-3, misc0eff.getWidth-33) else 0.U f1icaf := misc1eff(misc1eff.getWidth-2)
val f0poffset = if(BTB_ENABLE) misc0eff(misc0eff.getWidth-34, misc0eff.getWidth-45) else 0.U val f1ictype = misc1eff(misc1eff.getWidth-3,misc1eff.getWidth-4)
val f0fghr = if(BTB_ENABLE) misc0eff(BHT_GHR_SIZE-1, 0) else 0.U 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 f0dbecc = misc0eff(misc1eff.getWidth-1)
val f0brend = WireInit(UInt(2.W), 0.U) f0icaf := misc0eff(misc1eff.getWidth-2)
val f0way = WireInit(UInt(2.W), 0.U) val f0ictype = misc0eff(misc1eff.getWidth-3,misc1eff.getWidth-4)
val f0pc4 = WireInit(UInt(2.W), 0.U) val f0prett = misc0eff(misc1eff.getWidth-5,misc1eff.getWidth-35)
val f0hist0 = WireInit(UInt(2.W), 0.U) val f0poffset = misc0eff(BHT_GHR_SIZE+11, BHT_GHR_SIZE)
val f0hist1 = WireInit(UInt(2.W), 0.U) val f0fghr = misc0eff(BHT_GHR_SIZE-1, 0)
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)
// Branch information
val f0dbecc = WireInit(UInt(2.W), 0.U) 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),
val f1dbecc = WireInit(UInt(2.W), 0.U) 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),
val f0index = Wire(Vec(2,UInt(log2Ceil(BTB_SIZE).W))) io.ifu_bp_valid_f(0),io.ifu_bp_ret_f(0))
val f1index = Wire(Vec(2,UInt(log2Ceil(BTB_SIZE).W))) // Effective branch information
f0index := (0 until 2).map(i => 0.U) val brdataeff = Mux1H(Seq(qren(0).asBool->Cat(brdata1,brdata0),
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(1).asBool->Cat(brdata2,brdata1),
qren(2).asBool->Cat(brdata0,brdata2))) 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))
f0ret := Cat(brdata0final(17) , brdata0final(0)) val (brdata0eff,brdata1eff) = (brdataeff(11,0) , brdataeff(23,12))
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))
f1ret := Cat(brdata1final(17) , brdata1final(0)) val brdata0final = Mux1H(Seq(q0sel(0).asBool -> brdata0eff, q0sel(1).asBool -> brdata0eff(11,6)))
f1brend := Cat(brdata1final(18), brdata1final(1)) val brdata1final = Mux1H(Seq(q1sel(0).asBool -> brdata1eff, q1sel(1).asBool -> brdata1eff(11,6)))
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))
}else{ val f0ret = Cat(brdata0final(6),brdata0final(0))
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), val f0brend = Cat(brdata0final(7),brdata0final(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)) val f0way = Cat(brdata0final(8),brdata0final(2))
f0ret := Cat(brdata0final(8) , brdata0final(0)) val f0pc4 = Cat(brdata0final(9),brdata0final(3))
f0brend := Cat(brdata0final(9) , brdata0final(1)) val f0hist0 = Cat(brdata0final(10),brdata0final(4))
f0way := Cat(brdata0final(10), brdata0final(2)) val f0hist1 = Cat(brdata0final(11),brdata0final(5))
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)) val f1ret = Cat(brdata1final(6),brdata1final(0))
f1brend := Cat(brdata1final(9) , brdata1final(1)) val f1brend = Cat(brdata1final(7),brdata1final(1))
f1way := Cat(brdata1final(10), brdata1final(2)) val f1way = Cat(brdata1final(8),brdata1final(2))
f1pc4 := Cat(brdata1final(11), brdata1final(3)) val f1pc4 = Cat(brdata1final(9),brdata1final(3))
f1hist0 := Cat(brdata1final(12), brdata1final(4)) val f1hist0 = Cat(brdata1final(10),brdata1final(4))
f1hist1 := Cat(brdata1final(13), brdata1final(5)) val f1hist1 = Cat(brdata1final(11),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))
}
f2_valid := f2val(0) f2_valid := f2val(0)
@ -347,6 +256,21 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
fetch_to_f2 := (!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, 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))
@ -369,54 +293,38 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
qren(2).asBool->Cat(q0,q2))) qren(2).asBool->Cat(q0,q2)))
val (q1eff, q0eff) = (qeff(63,32), qeff(31,0)) val (q1eff, q0eff) = (qeff(63,32), qeff(31,0))
q0final := Mux1H(Seq(q0sel(0).asBool->q0eff, q0final := Mux1H(Seq(q0sel(0).asBool->q0eff, q0sel(1).asBool->q0eff(31,16)))
q0sel(1).asBool->q0eff(31,16)))
q1final := Mux1H(Seq(q1sel(0).asBool->q1eff(15,0), q1sel(1).asBool->q1eff(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 // 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))) 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 = Mux1H(Seq(f0val(1).asBool()->f0brend, (!f0val(1) & f0val(0)).asBool->Cat(f1brend(0),f0brend(0))))
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 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 alignhist0 = Mux1H(Seq(f0val(1).asBool()->f0hist0, (!f0val(1) & f0val(0)).asBool->Cat(f1hist0(0),f0hist0(0))))
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 alignfromf1 = !f0val(1) & f0val(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 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 // Instruction is compressed or not
first4B := aligndata(1,0) === 3.U 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))) 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) 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))) io.dec_aln.aln_ib.ifu_i0_dbecc := Mux1H(Seq(first4B.asBool->aligndbecc.orR, first2B.asBool->aligndbecc(0)))
@ -443,28 +351,23 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
// Expander from 16-bit to 32-bit // Expander from 16-bit to 32-bit
val decompressed = Module(new ifu_compress_ctl()) val decompressed = Module(new ifu_compress_ctl())
io.dec_aln.aln_ib.ifu_i0_instr := Mux1H(Seq((first4B & alignval(1)).asBool -> ifirst, io.dec_aln.aln_ib.ifu_i0_instr := Mux1H(Seq(first4B.asBool -> ifirst, first2B.asBool -> decompressed.io.dout))
(first2B & alignval(0)).asBool -> decompressed.io.dout))
//////////////////////////////////////////////////////////////////////////////////////////// // Hashing the PC
val firstpc_hash = btb_addr_hash(firstpc) val firstpc_hash = btb_addr_hash(f0pc)
val secondpc_hash = btb_addr_hash(secondpc) val secondpc_hash = btb_addr_hash(secondpc)
val firstbrtag_hash = WireInit(UInt(BTB_BTAG_SIZE.W),0.U) val firstbrtag_hash = if(BTB_BTAG_FOLD) btb_tag_hash_fold(firstpc) else btb_tag_hash(firstpc)
val secondbrtag_hash = WireInit(UInt(BTB_BTAG_SIZE.W),0.U)
if(BTB_ENABLE){if(BTB_FULLYA) val secondbrtag_hash = if(BTB_BTAG_FOLD) btb_tag_hash_fold(secondpc) else btb_tag_hash(secondpc)
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)} }
if(BTB_ENABLE){
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.valid :=(first2B & alignbrend(0)) | (first4B & alignbrend(1)) | (first4B & alignval(1) & alignbrend(0))
val i0_brp_pc4 = (first2B & alignpc4(0)) | (first4B & alignpc4(1))
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))
val i0_brp_pc4 = (first2B & alignpc4(0)) | (first4B & alignpc4(1))
io.dec_aln.aln_ib.i0_brp.bits.way := Mux((first2B | alignbrend(0)).asBool, alignway(0), alignway(1)) io.dec_aln.aln_ib.i0_brp.bits.way := Mux((first2B | alignbrend(0)).asBool, alignway(0), alignway(1))
io.dec_aln.aln_ib.i0_brp.bits.hist := Cat((first2B & alignhist1(0)) | (first4B & alignhist1(1)), io.dec_aln.aln_ib.i0_brp.bits.hist := Cat((first2B & alignhist1(0)) | (first4B & alignhist1(1)),
@ -482,35 +385,21 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
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.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.ifu_i0_bp_index := Mux((first2B | alignbrend(0)).asBool, firstpc_hash, secondpc_hash) 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_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.ifu_i0_bp_btag := Mux((first2B | alignbrend(0)).asBool, firstbrtag_hash, secondbrtag_hash)
if(BTB_FULLYA){ decompressed.io.din := aligndata
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)
}
val i0_shift = io.dec_aln.aln_dec.dec_i0_decode_d & ~error_stall
decompressed.io.din := Mux(first2B.asBool(),aligndata,0.U)
val i0_shift = io.dec_i0_decode_d & !error_stall
io.dec_aln.ifu_pmu_instr_aligned := i0_shift io.dec_aln.ifu_pmu_instr_aligned := i0_shift
shift_2B := i0_shift & first2B shift_2B := i0_shift & first2B
shift_4B := i0_shift & first4B shift_4B := i0_shift & first4B
////
f0_shift_2B := Mux1H(Seq(shift_2B.asBool -> f0val(0), shift_4B.asBool -> (f0val(0) & !f0val(1)))) 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 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,6 +9,7 @@ import chisel3.experimental.chiselName
@chiselName @chiselName
class ifu_bp_ctl extends Module with lib with RequireAsyncReset { class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
val io = IO (new Bundle { val io = IO (new Bundle {
val active_clk = Input(Clock())
val ic_hit_f = Input(Bool()) val ic_hit_f = Input(Bool())
val exu_flush_final = Input(Bool()) val exu_flush_final = Input(Bool())
val ifc_fetch_addr_f = Input(UInt(31.W)) val ifc_fetch_addr_f = Input(UInt(31.W))
@ -16,7 +17,6 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
val dec_bp = new dec_bp() val dec_bp = new dec_bp()
val dec_tlu_flush_lower_wb = Input(Bool()) val dec_tlu_flush_lower_wb = Input(Bool())
val exu_bp = Flipped(new exu_bp()) 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_hit_taken_f = Output(Bool())
val ifu_bp_btb_target_f = Output(UInt(31.W)) val ifu_bp_btb_target_f = Output(UInt(31.W))
val ifu_bp_inst_mask_f = Output(Bool()) val ifu_bp_inst_mask_f = Output(Bool())
@ -28,19 +28,10 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
val ifu_bp_pc4_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_valid_f = Output(UInt(2.W))
val ifu_bp_poffset_f = Output(UInt(12.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 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 TAG_START = 16+BTB_BTAG_SIZE
val PC4 = 4 // Branch = pc + 4 (BTB Index) val PC4 = 4 // Branch = pc + 4 (BTB Index)
val BOFF = 3 // Branch offset (BTB Index) val BOFF = 3 // Branch offset (BTB Index)
val CALL = 2 // Branch CALL (BTB Index) val CALL = 2 // Branch CALL (BTB Index)
@ -54,28 +45,16 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
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 = WireInit(Bool(), 0.U)
val leak_one_f_d1 = WireInit(Bool(), 0.U)
val bht_dir_f = WireInit(UInt(2.W), 0.U) val bht_dir_f = WireInit(UInt(2.W), 0.U)
val dec_tlu_error_wb = WireInit(Bool(), 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_error_addr_wb = WireInit(UInt((BTB_ADDR_HI-BTB_ADDR_LO+1).W), 0.U)
val btb_bank0_rd_data_way0_f = WireInit(UInt((TAG_START+1).W), 0.U)
val btb_vbank0_rd_data_f = WireInit(UInt((BTB_DWIDTH).W), 0.U) val btb_bank0_rd_data_way1_f = WireInit(UInt((TAG_START+1).W), 0.U)
val btb_vbank1_rd_data_f = WireInit(UInt((BTB_DWIDTH).W), 0.U) val btb_bank0_rd_data_way0_p1_f = WireInit(UInt((TAG_START+1).W), 0.U)
val btb_bank0_rd_data_way0_f = WireInit(UInt((BTB_DWIDTH).W), 0.U) val btb_bank0_rd_data_way1_p1_f = WireInit(UInt((TAG_START+1).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 eoc_mask = WireInit(Bool(), 0.U)
val btb_lru_b0_f = WireInit(UInt(LRU_SIZE.W), init = 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 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)
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////
// Misprediction packet // Misprediction packet
val exu_mp_valid = io.exu_bp.exu_mp_pkt.bits.misp & !leak_one_f 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_tgt = io.exu_bp.exu_mp_pkt.bits.toffset
val exu_mp_addr = io.exu_bp.exu_mp_index 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_ataken = io.exu_bp.exu_mp_pkt.bits.ataken
val exu_mp_way_f = WireInit(Bool(), 0.U)
// Its a commit or update packet // Its a commit or update packet
val dec_tlu_br0_v_wb = io.dec_bp.dec_tlu_br0_r_pkt.valid val dec_tlu_br0_v_wb = io.dec_bp.dec_tlu_br0_r_pkt.valid
@ -129,30 +107,36 @@ 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 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 // Hashing the PC to generate the index for the btb
// 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_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)) 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 // 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_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 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)
// For a tag to match the branch should be valid tag should match and a fetch request should be generated // 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 // 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) & 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 !(dec_tlu_way_wb_f & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
// Similar to the way-0 -> way-1 // 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) & 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 !(dec_tlu_way_wb_f & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
// Similar to above matches // 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) & 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 !(dec_tlu_way_wb_f & branch_error_bank_conflict_p1_f) & io.ifc_fetch_req_f & !leak_one_f
// Similar to above matches // 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) & 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 !(dec_tlu_way_wb_f & branch_error_bank_conflict_p1_f) & io.ifc_fetch_req_f & !leak_one_f
// Reordering to avoid multiple hit // 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)), 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)),
@ -168,9 +152,9 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
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)))
// Final hit calculation // Final hit calculation
wayhit_f := tag_match_way0_expanded_f | tag_match_way1_expanded_f val wayhit_f = tag_match_way0_expanded_f | tag_match_way1_expanded_f
wayhit_p1_f := tag_match_way0_expanded_p1_f | tag_match_way1_expanded_p1_f val wayhit_p1_f = tag_match_way0_expanded_p1_f | tag_match_way1_expanded_p1_f
// Chopping off the ways that had a hit btb_vbank0_rd_data_f // Chopping off the ways that had a hit btb_vbank0_rd_data_f
// e-> Lower half o-> Upper half // e-> Lower half o-> Upper half
@ -185,13 +169,11 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
// Making virtual banks, made from pc-bit(1) if it comes from a multiple of 4 we get the lower half of the bank // 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 // 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, 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)) 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, 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)) io.ifc_fetch_addr_f(0)->btb_bank0e_rd_data_p1_f))
way_raw := tag_match_vway1_expanded_f | (~vwayhit_f & btb_vlru_rd_f)
// Branch prediction info is sent with the 2byte lane associated with the end of the branch. // Branch prediction info is sent with the 2byte lane associated with the end of the branch.
// Cases // Cases
// BANK1 BANK0 // BANK1 BANK0
@ -217,6 +199,9 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
// Checking if the mis-prediction was valid or not and make a new LRU value // 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) val mp_wrlru_b0 = mp_wrindex_dec & Fill(LRU_SIZE, exu_mp_valid)
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))
// Is the update of the lru valid or not // 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 lru_update_valid_f = (vwayhit_f(0) | vwayhit_f(1)) & io.ifc_fetch_req_f & !leak_one_f
@ -240,21 +225,21 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
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 // 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), 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))) io.ifc_fetch_addr_f(0).asBool -> Cat(btb_lru_rd_p1_f, btb_lru_rd_f)))
// virtual way depending on pc value // 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, 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)))) 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 // update the lru
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 //io.test := btb_lru_b0_ns
// Checking if the end of line is near // Checking if the end of line is near
val eoc_near = io.ifc_fetch_addr_f(ICACHE_BEAT_ADDR_HI-1, 2).andR 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 // Mask according to eoc-near and make the hit-final
eoc_mask := !eoc_near | (~io.ifc_fetch_addr_f(1,0)).orR() eoc_mask := !eoc_near | (~io.ifc_fetch_addr_f(1,0)).orR()
@ -292,7 +277,6 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
val bht_vbank1_rd_data_f = Mux1H(Seq(!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 // 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_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))
@ -335,11 +319,8 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
fghr_ns := Mux1H(Seq(exu_flush_final_d1.asBool->exu_flush_ghr, 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 -> merged_ghr,
(!exu_flush_final_d1 & !(io.ifc_fetch_req_f & io.ic_hit_f & !leak_one_f_d1)).asBool -> fghr)) (!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) fghr := withClock(io.active_clk) {RegNext(fghr_ns, 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)
io.ifu_bp_fghr_f := fghr io.ifu_bp_fghr_f := fghr
io.ifu_bp_hist1_f := hist1_raw io.ifu_bp_hist1_f := hist1_raw
@ -357,7 +338,9 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
val btb_fg_crossing_f = fetch_start_f(0) & btb_sel_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 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 io.ifu_bp_poffset_f := btb_rd_tgt_f
val adder_pc_in_f = Mux1H(Seq(use_fa_plus.asBool -> fetch_addr_p1_f, val adder_pc_in_f = Mux1H(Seq(use_fa_plus.asBool -> fetch_addr_p1_f,
@ -369,9 +352,11 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
val rets_out = Wire(Vec(RET_STACK_SIZE, UInt(32.W))) val rets_out = Wire(Vec(RET_STACK_SIZE, UInt(32.W)))
rets_out := (0 until RET_STACK_SIZE).map(i=>0.U) rets_out := (0 until RET_STACK_SIZE).map(i=>0.U)
// Final target if its a RET then pop else take the target pc // 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)) | io.ifu_bp_btb_target_f := Mux((btb_rd_ret_f & !btb_rd_call_f & rets_out(0)(0)).asBool,
(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))) rets_out(0)(31,1),bp_btb_target_adder_f(31,1))
// Return stack // 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)) 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,6 +365,7 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
val rs_hold = !rs_push & !rs_pop 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) 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 // Make the input of the RAS
val rets_in = (0 until RET_STACK_SIZE).map(i=> if(i==0) 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), Mux1H(Seq(rs_push.asBool -> Cat(bp_rs_call_target_f(31,1),1.U),
@ -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 // 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 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 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 // 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_wr_addr2 = br0_hashed_wb
val bht_rd_addr_f = bht_rd_addr_hashed_f val bht_rd_addr_f = bht_rd_addr_hashed_f
val bht_rd_addr_p1_f = bht_rd_addr_hashed_p1_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 // BTB
// Entry -> Tag[BTB-BTAG-SIZE], toffset[12], pc4, boffset, call, ret, valid // 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_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_wr_addr = Mux(dec_tlu_error_wb.asBool, btb_error_addr_wb, exu_mp_addr) 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_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_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_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 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_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))) 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)
// }
val bht_bank_clken = Wire(Vec(2, Vec(BHT_ARRAY_DEPTH/NUM_BHT_LOOP, Bool()))) val bht_bank_clken = Wire(Vec(2, Vec(BHT_ARRAY_DEPTH/NUM_BHT_LOOP, Bool())))
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)))
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)))
}
for(i<-0 until 2; k<- 0 until (BHT_ARRAY_DEPTH/NUM_BHT_LOOP)){ 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_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) // 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=> 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())))) 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 // 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 // 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){ 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_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)) (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 // 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)))) 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){ 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 // 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_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_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))) 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

@ -9,8 +9,8 @@ class ifu_ifc_ctl extends Module with lib with RequireAsyncReset {
val io = IO(new Bundle{ val io = IO(new Bundle{
val exu_flush_final = Input(Bool()) // Miss Prediction for EXU val exu_flush_final = Input(Bool()) // Miss Prediction for EXU
val exu_flush_path_final = Input(UInt(31.W)) // Replay PC val exu_flush_path_final = Input(UInt(31.W)) // Replay PC
val free_l2clk = Input(Clock()) val free_clk = Input(Clock())
// val active_clk = Input(Clock()) val active_clk = Input(Clock())
val scan_mode = Input(Bool()) val scan_mode = Input(Bool())
val ic_hit_f = Input(Bool()) val ic_hit_f = Input(Bool())
val ifu_ic_mb_empty = Input(Bool()) // Miss buffer of mem-ctl empty val ifu_ic_mb_empty = Input(Bool()) // Miss buffer of mem-ctl empty
@ -60,27 +60,21 @@ class ifu_ifc_ctl extends Module with lib with RequireAsyncReset {
val idle_E :: fetch_E :: stall_E :: wfm_E :: Nil = Enum(4) val idle_E :: fetch_E :: stall_E :: wfm_E :: Nil = Enum(4)
val dma_stall = io.ic_dma_active | dma_iccm_stall_any_f val dma_stall = io.ic_dma_active | dma_iccm_stall_any_f
dma_iccm_stall_any_f := withClock(io.free_clk) {RegNext(io.dma_ifc.dma_iccm_stall_any, init=0.U)}
miss_a := withClock(io.free_clk) {RegNext(miss_f, init=0.U)}
dma_iccm_stall_any_f := rvdffie(io.dma_ifc.dma_iccm_stall_any,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)
miss_a := rvdffie(miss_f,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)
if(BTB_ENABLE) {
val sel_last_addr_bf = !io.exu_flush_final & (!io.ifc_fetch_req_f | !io.ic_hit_f) val sel_last_addr_bf = !io.exu_flush_final & (!io.ifc_fetch_req_f | !io.ic_hit_f)
val sel_btb_addr_bf = !io.exu_flush_final & io.ifc_fetch_req_f & io.ifu_bp_hit_taken_f & io.ic_hit_f val sel_btb_addr_bf = !io.exu_flush_final & io.ifc_fetch_req_f & io.ifu_bp_hit_taken_f & io.ic_hit_f
val sel_next_addr_bf = !io.exu_flush_final & io.ifc_fetch_req_f & !io.ifu_bp_hit_taken_f & io.ic_hit_f val sel_next_addr_bf = !io.exu_flush_final & io.ifc_fetch_req_f & !io.ifu_bp_hit_taken_f & io.ic_hit_f
// TODO: Make an assertion for the 1H-Mux under here
// Next PC calculation // Next PC calculation
io.ifc_fetch_addr_bf := Mux1H(Seq(io.exu_flush_final.asBool -> io.exu_flush_path_final, // Replay PC io.ifc_fetch_addr_bf := Mux1H(Seq(io.exu_flush_final.asBool -> io.exu_flush_path_final, // Replay PC
sel_last_addr_bf.asBool -> io.ifc_fetch_addr_f, // Hold the current PC sel_last_addr_bf.asBool -> io.ifc_fetch_addr_f, // Hold the current PC
sel_btb_addr_bf.asBool -> io.ifu_bp_btb_target_f, // Take the predicted PC sel_btb_addr_bf.asBool -> io.ifu_bp_btb_target_f, // Take the predicted PC
sel_next_addr_bf.asBool -> fetch_addr_next)) // PC+4 sel_next_addr_bf.asBool -> fetch_addr_next)) // PC+4
}
else{
val sel_last_addr_bf = !io.exu_flush_final & (!io.ifc_fetch_req_f | !io.ic_hit_f)
val sel_next_addr_bf = !io.exu_flush_final & io.ifc_fetch_req_f & io.ic_hit_f
// Next PC calculation
io.ifc_fetch_addr_bf := Mux1H(Seq(io.exu_flush_final.asBool -> io.exu_flush_path_final, // Replay PC
sel_last_addr_bf.asBool -> io.ifc_fetch_addr_f, // Hold the current PC
sel_next_addr_bf.asBool -> fetch_addr_next)) // PC+4
}
val address_upper = io.ifc_fetch_addr_f(30,1)+1.U val address_upper = io.ifc_fetch_addr_f(30,1)+1.U
fetch_addr_next_0 := !(address_upper(ICACHE_TAG_INDEX_LO-2) ^ io.ifc_fetch_addr_f(ICACHE_TAG_INDEX_LO-1)) & io.ifc_fetch_addr_f(0) fetch_addr_next_0 := !(address_upper(ICACHE_TAG_INDEX_LO-2) ^ io.ifc_fetch_addr_f(ICACHE_TAG_INDEX_LO-1)) & io.ifc_fetch_addr_f(0)
@ -107,7 +101,7 @@ class ifu_ifc_ctl extends Module with lib with RequireAsyncReset {
val next_state_0 = (!goto_idle & leave_idle) | (state(0) & !goto_idle) val next_state_0 = (!goto_idle & leave_idle) | (state(0) & !goto_idle)
state := rvdffie(Cat(next_state_1, next_state_0),io.free_l2clk,reset.asAsyncReset(),io.scan_mode) state := withClock(io.active_clk) {RegNext(Cat(next_state_1, next_state_0), init = 0.U)}
flush_fb := io.exu_flush_final flush_fb := io.exu_flush_final
@ -130,11 +124,12 @@ class ifu_ifc_ctl extends Module with lib with RequireAsyncReset {
wfm := state === 3.U(2.W) wfm := state === 3.U(2.W)
fb_full_f_ns := fb_write_ns(3) fb_full_f_ns := fb_write_ns(3)
val fb_full_f = rvdffie(fb_full_f_ns,io.free_l2clk,reset.asAsyncReset(),io.scan_mode) val fb_full_f = withClock(io.active_clk) {RegNext(fb_full_f_ns, init = 0.U)}
fb_write_f := rvdffie(fb_write_ns,io.free_l2clk,reset.asAsyncReset(),io.scan_mode) fb_write_f := withClock(io.active_clk) {RegNext(fb_write_ns, 0.U)}
io.dec_ifc.ifu_pmu_fetch_stall := wfm | (io.ifc_fetch_req_bf_raw & io.dec_ifc.ifu_pmu_fetch_stall := wfm | (io.ifc_fetch_req_bf_raw &
((fb_full_f & !(io.ifu_fb_consume2 | io.ifu_fb_consume1 | io.exu_flush_final)) | dma_stall)) ((fb_full_f & !(io.ifu_fb_consume2 | io.ifu_fb_consume1 | io.exu_flush_final)) | dma_stall))
// Checking the next PC range and its region to access the ICCM or I$ // Checking the next PC range and its region to access the ICCM or I$
val (iccm_acc_in_region_bf, iccm_acc_in_range_bf) = if(ICCM_ENABLE) val (iccm_acc_in_region_bf, iccm_acc_in_range_bf) = if(ICCM_ENABLE)
rvrangecheck(ICCM_SADR, ICCM_SIZE, Cat(io.ifc_fetch_addr_bf,0.U)) rvrangecheck(ICCM_SADR, ICCM_SIZE, Cat(io.ifc_fetch_addr_bf,0.U))
@ -147,7 +142,7 @@ class ifu_ifc_ctl extends Module with lib with RequireAsyncReset {
io.ifc_region_acc_fault_bf := !iccm_acc_in_range_bf & iccm_acc_in_region_bf io.ifc_region_acc_fault_bf := !iccm_acc_in_range_bf & iccm_acc_in_region_bf
io.ifc_fetch_uncacheable_bf := ~io.dec_ifc.dec_tlu_mrac_ff(Cat(io.ifc_fetch_addr_bf(30,27), 0.U)) io.ifc_fetch_uncacheable_bf := ~io.dec_ifc.dec_tlu_mrac_ff(Cat(io.ifc_fetch_addr_bf(30,27), 0.U))
io.ifc_fetch_req_f := rvdffie(io.ifc_fetch_req_bf,io.free_l2clk,reset.asAsyncReset(),io.scan_mode) io.ifc_fetch_req_f := withClock(io.active_clk){RegNext(io.ifc_fetch_req_bf, init=0.U)}
io.ifc_fetch_addr_f := rvdffpcie(io.ifc_fetch_addr_bf, io.exu_flush_final|io.ifc_fetch_req_f,reset.asAsyncReset(), clock, io.scan_mode) io.ifc_fetch_addr_f := rvdffe(io.ifc_fetch_addr_bf, io.exu_flush_final|io.ifc_fetch_req_f, clock, io.scan_mode)
} }

View File

@ -1,11 +1,14 @@
package ifu package ifu
import chisel3._ import chisel3._
import chisel3.internal.naming.chiselName
import chisel3.util._ import chisel3.util._
import lib._ import lib._
import include._ import include._
import scala.math.pow
class mem_ctl_io extends Bundle with lib{ class mem_ctl_io extends Bundle with lib{
val free_l2clk = Input(Clock()) val free_clk = Input(Clock())
val active_clk = Input(Clock()) val active_clk = Input(Clock())
val exu_flush_final = Input(Bool()) val exu_flush_final = Input(Bool())
val dec_mem_ctrl = new dec_mem_ctrl val dec_mem_ctrl = new dec_mem_ctrl
@ -37,11 +40,11 @@ class mem_ctl_io extends Bundle with lib{
val iccm_ready = Output(Bool()) val iccm_ready = Output(Bool())
val dec_tlu_flush_lower_wb = Input(Bool()) val dec_tlu_flush_lower_wb = Input(Bool())
val iccm_rd_ecc_double_err = Output(UInt(2.W)) val iccm_rd_ecc_double_err = Output(Bool())
val iccm_dma_sb_error = Output(Bool()) val iccm_dma_sb_error = Output(Bool())
val ic_hit_f = Output(Bool()) val ic_hit_f = Output(Bool())
val ic_access_fault_f = Output(UInt(2.W)) val ic_access_fault_f = Output(Bool())
val ic_access_fault_type_f = Output(UInt(2.W)) val ic_access_fault_type_f = Output(UInt(2.W))
val ifu_async_error_start = Output(Bool()) val ifu_async_error_start = Output(Bool())
val ic_fetch_val_f = Output(UInt(2.W)) val ic_fetch_val_f = Output(UInt(2.W))
@ -57,42 +60,43 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
val err_idle_C :: ic_wff_C :: ecc_wff_C :: ecc_cor_C :: dma_sb_err_C :: Nil = Enum(5) val err_idle_C :: ic_wff_C :: ecc_wff_C :: ecc_cor_C :: dma_sb_err_C :: Nil = Enum(5)
val iccm_single_ecc_error = WireInit(UInt(2.W), 0.U) val iccm_single_ecc_error = WireInit(UInt(2.W), 0.U)
val ifc_fetch_req_f = WireInit(Bool(), 0.B) val ifc_fetch_req_f = WireInit(Bool(), false.B)
val miss_pending = WireInit(Bool(), 0.B) val miss_pending = WireInit(Bool(), false.B)
val scnd_miss_req = WireInit(Bool(), 0.B) val scnd_miss_req = WireInit(Bool(), false.B)
val dma_iccm_req_f = WireInit(Bool(), 0.B) val dma_iccm_req_f = WireInit(Bool(), false.B)
val iccm_correct_ecc = WireInit(Bool(), 0.B) val iccm_correct_ecc = WireInit(Bool(), false.B)
val perr_state = WireInit(UInt(3.W), 0.U) val perr_state = WireInit(UInt(3.W), 0.U)
val err_stop_state = WireInit(UInt(2.W), 0.U) val err_stop_state = WireInit(UInt(2.W), 0.U)
val err_stop_fetch = WireInit(Bool(), 0.B) val err_stop_fetch = WireInit(Bool(), false.B)
val miss_state = WireInit(UInt(3.W), 0.U) val miss_state = WireInit(UInt(3.W), 0.U)
val miss_nxtstate = WireInit(UInt(3.W), 0.U) val miss_nxtstate = WireInit(UInt(3.W), 0.U)
val miss_state_en = WireInit(Bool(), 0.B) val miss_state_en = WireInit(Bool(), false.B)
val bus_ifu_bus_clk_en = WireInit(Bool(), 0.B) val ifu_bus_rsp_valid = WireInit(Bool(), false.B)
val uncacheable_miss_ff = WireInit(Bool(), 0.B) val bus_ifu_bus_clk_en = WireInit(Bool(), false.B)
val ic_act_miss_f = WireInit(Bool(), 0.B) val ifu_bus_rsp_ready = WireInit(Bool(), false.B)
val ic_byp_hit_f = WireInit(Bool(), 0.B) val uncacheable_miss_ff = WireInit(Bool(), false.B)
val ic_act_miss_f = WireInit(Bool(), false.B)
val ic_byp_hit_f = WireInit(Bool(), false.B)
val bus_new_data_beat_count = WireInit(UInt(ICACHE_BEAT_BITS.W), 0.U) val bus_new_data_beat_count = WireInit(UInt(ICACHE_BEAT_BITS.W), 0.U)
val bus_ifu_wr_en_ff = WireInit(Bool(), 0.B) val bus_ifu_wr_en_ff = WireInit(Bool(), false.B)
val last_beat = WireInit(Bool(), 0.B) val last_beat = WireInit(Bool(), false.B)
val last_data_recieved_ff = WireInit(Bool(), 0.B) val last_data_recieved_ff = WireInit(Bool(), false.B)
val stream_eol_f = WireInit(Bool(), 0.B) val stream_eol_f = WireInit(Bool(), false.B)
val ic_miss_under_miss_f = WireInit(Bool(), 0.B) val ic_miss_under_miss_f = WireInit(Bool(), false.B)
val ic_ignore_2nd_miss_f = WireInit(Bool(), 0.B) val ic_ignore_2nd_miss_f = WireInit(Bool(), false.B)
val ic_debug_rd_en_ff = WireInit(Bool(), 0.B) val ic_debug_rd_en_ff = WireInit(Bool(), false.B)
val debug_data_clk = rvclkhdr(clock, ic_debug_rd_en_ff, io.scan_mode) val debug_data_clk = rvclkhdr(clock, ic_debug_rd_en_ff, io.scan_mode)
val flush_final_f = rvdffie(io.exu_flush_final,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.free_l2clk){RegNext(io.exu_flush_final, 0.U)} val flush_final_f = withClock(io.free_clk){RegNext(io.exu_flush_final, 0.U)}
val fetch_bf_f_c1_clken = io.ifc_fetch_req_bf_raw | ifc_fetch_req_f | miss_pending | io.exu_flush_final | scnd_miss_req val fetch_bf_f_c1_clken = io.ifc_fetch_req_bf_raw | ifc_fetch_req_f | miss_pending | io.exu_flush_final | scnd_miss_req
val debug_c1_clken = io.ic.debug_rd_en | io.ic.debug_wr_en val debug_c1_clken = io.ic.debug_rd_en | io.ic.debug_wr_en
val fetch_bf_f_c1_clk = if(RV_FPGA_OPTIMIZE) 0.B.asClock() else rvclkhdr(clock, fetch_bf_f_c1_clken, io.scan_mode) val debug_c1_clk = rvclkhdr(clock, debug_c1_clken, io.scan_mode)
val debug_c1_clk = if(RV_FPGA_OPTIMIZE) 0.B.asClock() else rvclkhdr(clock, debug_c1_clken, io.scan_mode) val fetch_bf_f_c1_clk = rvclkhdr(clock, fetch_bf_f_c1_clken, io.scan_mode)
io.iccm_dma_sb_error := iccm_single_ecc_error.orR() & dma_iccm_req_f.asBool() io.iccm_dma_sb_error := iccm_single_ecc_error.orR() & dma_iccm_req_f.asBool()
io.ifu_async_error_start := io.dec_mem_ctrl.ifu_iccm_rd_ecc_single_err | io.dec_mem_ctrl.ifu_ic_error_start io.ifu_async_error_start := io.dec_mem_ctrl.ifu_iccm_rd_ecc_single_err | io.dec_mem_ctrl.ifu_ic_error_start
io.ic_dma_active := iccm_correct_ecc | (perr_state === dma_sb_err_C) | (err_stop_state === err_stop_fetch_C) | err_stop_fetch | io.dec_mem_ctrl.dec_tlu_flush_err_wb io.ic_dma_active := iccm_correct_ecc | (perr_state === dma_sb_err_C) | (err_stop_state === err_stop_fetch_C) | err_stop_fetch | io.dec_mem_ctrl.dec_tlu_flush_err_wb
val scnd_miss_req_in = io.ifu_axi.r.valid & bus_ifu_bus_clk_en & io.ifu_axi.r.ready & (bus_new_data_beat_count.andR) & val scnd_miss_req_in = ifu_bus_rsp_valid & bus_ifu_bus_clk_en & ifu_bus_rsp_ready & (bus_new_data_beat_count.andR) &
!uncacheable_miss_ff & ((miss_state === scnd_miss_C)|(miss_nxtstate === scnd_miss_C)) & !io.exu_flush_final !uncacheable_miss_ff & ((miss_state === scnd_miss_C)|(miss_nxtstate === scnd_miss_C)) & !io.exu_flush_final
val ifu_bp_hit_taken_q_f = io.ifu_bp_hit_taken_f & io.ic_hit_f val ifu_bp_hit_taken_q_f = io.ifu_bp_hit_taken_f & io.ic_hit_f
@ -141,7 +145,7 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
miss_state_en := (bus_ifu_wr_en_ff & last_beat) | io.exu_flush_final | io.dec_mem_ctrl.dec_tlu_force_halt miss_state_en := (bus_ifu_wr_en_ff & last_beat) | io.exu_flush_final | io.dec_mem_ctrl.dec_tlu_force_halt
} }
} }
miss_state := withClock(io.active_clk){RegEnable(miss_nxtstate, 0.U, miss_state_en.asBool)} miss_state := withClock(io.free_clk){RegEnable(miss_nxtstate, 0.U, miss_state_en.asBool)}
// Calculation all the relevant signals for the miss FSM // Calculation all the relevant signals for the miss FSM
val crit_byp_hit_f = WireInit(Bool(), 0.U) val crit_byp_hit_f = WireInit(Bool(), 0.U)
val way_status_mb_scnd_ff = WireInit(UInt(ICACHE_STATUS_BITS.W), 0.U) val way_status_mb_scnd_ff = WireInit(UInt(ICACHE_STATUS_BITS.W), 0.U)
@ -161,13 +165,13 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
val sel_hold_imb_scnd = ((miss_state === scnd_miss_C) | ic_miss_under_miss_f) & !flush_final_f val sel_hold_imb_scnd = ((miss_state === scnd_miss_C) | ic_miss_under_miss_f) & !flush_final_f
val way_status_mb_scnd_in = Mux(miss_state === scnd_miss_C, way_status_mb_scnd_ff, way_status) val way_status_mb_scnd_in = Mux(miss_state === scnd_miss_C, way_status_mb_scnd_ff, way_status)
val tagv_mb_scnd_in = Mux(miss_state === scnd_miss_C, tagv_mb_scnd_ff, Fill(ICACHE_NUM_WAYS, !reset_all_tags & !io.exu_flush_final) & io.ic.tag_valid) val tagv_mb_scnd_in = Mux(miss_state === scnd_miss_C, tagv_mb_scnd_ff, Fill(ICACHE_NUM_WAYS, !reset_all_tags) & io.ic.tag_valid)
val uncacheable_miss_scnd_in = Mux(sel_hold_imb_scnd.asBool, uncacheable_miss_scnd_ff, io.ifc_fetch_uncacheable_bf) val uncacheable_miss_scnd_in = Mux(sel_hold_imb_scnd.asBool, uncacheable_miss_scnd_ff, io.ifc_fetch_uncacheable_bf)
uncacheable_miss_scnd_ff := rvdff_fpga(uncacheable_miss_scnd_in,fetch_bf_f_c1_clk,fetch_bf_f_c1_clken,clock)//withClock(fetch_bf_f_c1_clk){RegNext(uncacheable_miss_scnd_in, 0.U)} uncacheable_miss_scnd_ff := withClock(fetch_bf_f_c1_clk){RegNext(uncacheable_miss_scnd_in, 0.U)}
val imb_scnd_in = Mux(sel_hold_imb_scnd.asBool, imb_scnd_ff, io.ifc_fetch_addr_bf) val imb_scnd_in = Mux(sel_hold_imb_scnd.asBool, imb_scnd_ff, io.ifc_fetch_addr_bf)
imb_scnd_ff := rvdffpcie(imb_scnd_in,fetch_bf_f_c1_clken,reset.asAsyncReset(),clock,io.scan_mode)//withClock(fetch_bf_f_c1_clk){RegNext(imb_scnd_in, 0.U)} imb_scnd_ff := withClock(fetch_bf_f_c1_clk){RegNext(imb_scnd_in, 0.U)}
way_status_mb_scnd_ff := rvdff_fpga(way_status_mb_scnd_in,fetch_bf_f_c1_clk,fetch_bf_f_c1_clken,clock)//withClock(fetch_bf_f_c1_clk){RegNext(way_status_mb_scnd_in, 0.U)} way_status_mb_scnd_ff := withClock(fetch_bf_f_c1_clk){RegNext(way_status_mb_scnd_in, 0.U)}
tagv_mb_scnd_ff := rvdff_fpga(tagv_mb_scnd_in,fetch_bf_f_c1_clk,fetch_bf_f_c1_clken,clock)//withClock(fetch_bf_f_c1_clk){RegNext(tagv_mb_scnd_in, 0.U)} tagv_mb_scnd_ff := withClock(fetch_bf_f_c1_clk){RegNext(tagv_mb_scnd_in, 0.U)}
val ic_req_addr_bits_hi_3 = bus_rd_addr_count val ic_req_addr_bits_hi_3 = bus_rd_addr_count
val ic_wr_addr_bits_hi_3 = ifu_bus_rid_ff & Fill(ICACHE_BEAT_BITS, bus_ifu_wr_en_ff) val ic_wr_addr_bits_hi_3 = ifu_bus_rid_ff & Fill(ICACHE_BEAT_BITS, bus_ifu_wr_en_ff)
@ -201,45 +205,45 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
val replace_way_mb_any = Wire(Vec(ICACHE_NUM_WAYS, UInt(1.W))) val replace_way_mb_any = Wire(Vec(ICACHE_NUM_WAYS, UInt(1.W)))
val tagv_mb_ff = WireInit(UInt(ICACHE_NUM_WAYS.W), 0.U) val tagv_mb_ff = WireInit(UInt(ICACHE_NUM_WAYS.W), 0.U)
val tagv_mb_in = Mux(scnd_miss_req.asBool, tagv_mb_scnd_ff | (Fill(ICACHE_NUM_WAYS, scnd_miss_index_match) & replace_way_mb_any.reverse.reduce(Cat(_,_))), val tagv_mb_in = Mux(scnd_miss_req.asBool, tagv_mb_scnd_ff | (Fill(ICACHE_NUM_WAYS, scnd_miss_index_match) & replace_way_mb_any.reverse.reduce(Cat(_,_))),
Mux(miss_pending.asBool, tagv_mb_ff, io.ic.tag_valid & Fill(ICACHE_NUM_WAYS, !reset_all_tags & !io.exu_flush_final))) Mux(miss_pending.asBool, tagv_mb_ff, io.ic.tag_valid & Fill(ICACHE_NUM_WAYS, !reset_all_tags)))
val scnd_miss_req_q = WireInit(Bool(), 0.B) val scnd_miss_req_q = WireInit(Bool(), false.B)
val reset_ic_ff = WireInit(Bool(), 0.B) val reset_ic_ff = WireInit(Bool(), false.B)
val reset_ic_in = miss_pending & !scnd_miss_req_q & (reset_all_tags | reset_ic_ff) val reset_ic_in = miss_pending & !scnd_miss_req_q & (reset_all_tags | reset_ic_ff)
reset_ic_ff := rvdffie(reset_ic_in,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.free_clk){RegNext(reset_ic_in, false.B)} reset_ic_ff := withClock(io.free_clk){RegNext(reset_ic_in, false.B)}
val fetch_uncacheable_ff = rvdffie(io.ifc_fetch_uncacheable_bf,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.active_clk){RegNext(io.ifc_fetch_uncacheable_bf, 0.U)} val fetch_uncacheable_ff = withClock(io.active_clk){RegNext(io.ifc_fetch_uncacheable_bf, 0.U)}
ifu_fetch_addr_int_f := rvdffpcie(io.ifc_fetch_addr_bf,fetch_bf_f_c1_clken,reset.asAsyncReset(),clock,io.scan_mode) // withClock(fetch_bf_f_c1_clk){RegNext(io.ifc_fetch_addr_bf, 0.U)} ifu_fetch_addr_int_f := withClock(fetch_bf_f_c1_clk){RegNext(io.ifc_fetch_addr_bf, 0.U)}
val vaddr_f = ifu_fetch_addr_int_f(ICACHE_BEAT_ADDR_HI-1, 0) val vaddr_f = ifu_fetch_addr_int_f(ICACHE_BEAT_ADDR_HI-1, 0)
uncacheable_miss_ff := rvdff_fpga(uncacheable_miss_in,fetch_bf_f_c1_clk,fetch_bf_f_c1_clken,clock)//withClock(fetch_bf_f_c1_clk){RegNext(uncacheable_miss_in, 0.U)} uncacheable_miss_ff := withClock(fetch_bf_f_c1_clk){RegNext(uncacheable_miss_in, 0.U)}
imb_ff := rvdffpcie(imb_in,fetch_bf_f_c1_clken,reset.asAsyncReset(),clock,io.scan_mode)//withClock(fetch_bf_f_c1_clk){RegNext(imb_in, 0.U)} imb_ff := withClock(fetch_bf_f_c1_clk){RegNext(imb_in, 0.U)}
val miss_addr = WireInit(UInt((31-ICACHE_BEAT_ADDR_HI).W), 0.U) val miss_addr = WireInit(UInt((31-ICACHE_BEAT_ADDR_HI).W), 0.U)
val miss_addr_in = Mux(!miss_pending, imb_ff(30, ICACHE_BEAT_ADDR_HI), val miss_addr_in = Mux(!miss_pending, imb_ff(30, ICACHE_BEAT_ADDR_HI),
Mux(scnd_miss_req_q.asBool, imb_scnd_ff(30, ICACHE_BEAT_ADDR_HI), miss_addr)) Mux(scnd_miss_req_q.asBool, imb_scnd_ff(30, ICACHE_BEAT_ADDR_HI), miss_addr))
val busclk_reset = if(RV_FPGA_OPTIMIZE) 0.B.asClock() else rvclkhdr(clock, bus_ifu_bus_clk_en | ic_act_miss_f | io.dec_mem_ctrl.dec_tlu_force_halt, io.scan_mode) val busclk_reset = rvclkhdr(clock, bus_ifu_bus_clk_en | ic_act_miss_f | io.dec_mem_ctrl.dec_tlu_force_halt, io.scan_mode)
miss_addr := withClock(busclk_reset) {RegNext(miss_addr_in, 0.U)}
miss_addr := rvdfflie_UInt(miss_addr_in,clock,reset.asAsyncReset(),bus_ifu_bus_clk_en | ic_act_miss_f | io.dec_mem_ctrl.dec_tlu_force_halt,io.scan_mode)//withClock(busclk_reset) {RegNext(miss_addr_in, 0.U)} way_status_mb_ff := withClock(fetch_bf_f_c1_clk){RegNext(way_status_mb_in, 0.U)}
way_status_mb_ff := rvdff_fpga(way_status_mb_in,fetch_bf_f_c1_clk,fetch_bf_f_c1_clken,clock)//withClock(fetch_bf_f_c1_clk){RegNext(way_status_mb_in, 0.U)} tagv_mb_ff := withClock(fetch_bf_f_c1_clk){RegNext(tagv_mb_in, 0.U)}
tagv_mb_ff := rvdff_fpga(tagv_mb_in,fetch_bf_f_c1_clk,fetch_bf_f_c1_clken,clock)//withClock(fetch_bf_f_c1_clk){RegNext(tagv_mb_in, 0.U)}
val stream_miss_f = WireInit(Bool(), 0.U) val stream_miss_f = WireInit(Bool(), 0.U)
val ifc_fetch_req_qual_bf = io.ifc_fetch_req_bf & !((miss_state===crit_wrd_rdy_C) & flush_final_f) & !stream_miss_f val ifc_fetch_req_qual_bf = io.ifc_fetch_req_bf & !((miss_state===crit_wrd_rdy_C) & flush_final_f) & !stream_miss_f
val ifc_fetch_req_f_raw = rvdffie(ifc_fetch_req_qual_bf,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.active_clk){RegNext(ifc_fetch_req_qual_bf, 0.U)} val ifc_fetch_req_f_raw = withClock(io.active_clk){RegNext(ifc_fetch_req_qual_bf, 0.U)}
ifc_fetch_req_f := ifc_fetch_req_f_raw & !io.exu_flush_final ifc_fetch_req_f := ifc_fetch_req_f_raw & !io.exu_flush_final
ifc_iccm_access_f := rvdff_fpga(io.ifc_iccm_access_bf,fetch_bf_f_c1_clk,fetch_bf_f_c1_clken,clock)//withClock(fetch_bf_f_c1_clk){RegNext(io.ifc_iccm_access_bf, 0.U)} ifc_iccm_access_f := withClock(fetch_bf_f_c1_clk){RegNext(io.ifc_iccm_access_bf, 0.U)}
val ifc_region_acc_fault_final_bf = WireInit(Bool(), 0.U) val ifc_region_acc_fault_final_bf = WireInit(Bool(), 0.U)
ifc_region_acc_fault_final_f := rvdff_fpga(ifc_region_acc_fault_final_bf,fetch_bf_f_c1_clk,fetch_bf_f_c1_clken,clock)// withClock(fetch_bf_f_c1_clk){RegNext(ifc_region_acc_fault_final_bf, 0.U)} ifc_region_acc_fault_final_f := withClock(fetch_bf_f_c1_clk){RegNext(ifc_region_acc_fault_final_bf, 0.U)}
val ifc_region_acc_fault_f = rvdff_fpga(io.ifc_region_acc_fault_bf,fetch_bf_f_c1_clk,fetch_bf_f_c1_clken,clock)//withClock(fetch_bf_f_c1_clk){RegNext(io.ifc_region_acc_fault_bf, 0.U)} val ifc_region_acc_fault_f = withClock(fetch_bf_f_c1_clk){RegNext(io.ifc_region_acc_fault_bf, 0.U)}
val ifu_ic_req_addr_f = Cat(miss_addr, ic_req_addr_bits_hi_3) val ifu_ic_req_addr_f = Cat(miss_addr, ic_req_addr_bits_hi_3)
io.ifu_ic_mb_empty := (((miss_state===hit_u_miss_C) | (miss_state===stream_C)) & !(bus_ifu_wr_en_ff & last_beat)) | !miss_pending io.ifu_ic_mb_empty := (((miss_state===hit_u_miss_C) | (miss_state===stream_C)) & !(bus_ifu_wr_en_ff & last_beat)) | !miss_pending
io.dec_mem_ctrl.ifu_miss_state_idle := miss_state === idle_C io.dec_mem_ctrl.ifu_miss_state_idle := miss_state === idle_C
val write_ic_16_bytes = WireInit(Bool(), 0.B) val write_ic_16_bytes = WireInit(Bool(), false.B)
val reset_tag_valid_for_miss = WireInit(Bool(), 0.B) val reset_tag_valid_for_miss = WireInit(Bool(), false.B)
val sel_mb_addr = (miss_pending & write_ic_16_bytes & !uncacheable_miss_ff) | reset_tag_valid_for_miss val sel_mb_addr = (miss_pending & write_ic_16_bytes & !uncacheable_miss_ff) | reset_tag_valid_for_miss
io.ic.rw_addr := Mux1H(Seq(sel_mb_addr -> Cat(imb_ff(30,ICACHE_BEAT_ADDR_HI) , ic_wr_addr_bits_hi_3 , imb_ff(1,0)), val ifu_ic_rw_int_addr = Mux1H(Seq(sel_mb_addr -> Cat(imb_ff(30,ICACHE_BEAT_ADDR_HI) , ic_wr_addr_bits_hi_3 , imb_ff(1,0)),
!sel_mb_addr -> io.ifc_fetch_addr_bf)) !sel_mb_addr -> io.ifc_fetch_addr_bf))
val bus_ifu_wr_en_ff_q = WireInit(Bool(), 0.B) val bus_ifu_wr_en_ff_q = WireInit(Bool(), false.B)
val sel_mb_status_addr = (miss_pending & write_ic_16_bytes & !uncacheable_miss_ff & last_beat & bus_ifu_wr_en_ff_q) | reset_tag_valid_for_miss val sel_mb_status_addr = (miss_pending & write_ic_16_bytes & !uncacheable_miss_ff & last_beat & bus_ifu_wr_en_ff_q) | reset_tag_valid_for_miss
val ifu_status_wr_addr = Mux(sel_mb_status_addr, Cat(imb_ff(30, ICACHE_BEAT_ADDR_HI),ic_wr_addr_bits_hi_3, imb_ff(1,0)), ifu_fetch_addr_int_f) val ifu_status_wr_addr = Mux(sel_mb_status_addr, Cat(imb_ff(30, ICACHE_BEAT_ADDR_HI),ic_wr_addr_bits_hi_3, imb_ff(1,0)), ifu_fetch_addr_int_f)
sel_mb_addr_ff := rvdffie(sel_mb_addr,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.active_clk){RegNext(sel_mb_addr, 0.U)} io.ic.rw_addr := ifu_ic_rw_int_addr
val ifu_bus_rdata_ff = rvdffe(io.ifu_axi.r.bits.data,io.ifu_bus_clk_en & io.ifu_axi.r.valid,clock,io.scan_mode) sel_mb_addr_ff := withClock(io.free_clk){RegNext(sel_mb_addr, 0.U)}
val ifu_bus_rdata_ff = WireInit(UInt(64.W), 0.U)
val ic_miss_buff_half = WireInit(UInt(64.W), 0.U) val ic_miss_buff_half = WireInit(UInt(64.W), 0.U)
// Ecc of the read data from the AXI // Ecc of the read data from the AXI
@ -256,8 +260,7 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
val ifu_ic_debug_rd_data_in = Mux(ic_debug_ict_array_sel_ff.asBool, if(ICACHE_ECC) Cat(0.U(2.W),io.ic.tag_debug_rd_data(25,21),0.U(32.W),io.ic.tag_debug_rd_data(20,0), 0.U((7-ICACHE_STATUS_BITS).W), way_status, 0.U(3.W),ic_debug_tag_val_rd_out) val ifu_ic_debug_rd_data_in = Mux(ic_debug_ict_array_sel_ff.asBool, if(ICACHE_ECC) Cat(0.U(2.W),io.ic.tag_debug_rd_data(25,21),0.U(32.W),io.ic.tag_debug_rd_data(20,0), 0.U((7-ICACHE_STATUS_BITS).W), way_status, 0.U(3.W),ic_debug_tag_val_rd_out)
else Cat(0.U(6.W),io.ic.tag_debug_rd_data(21),0.U(32.W),io.ic.tag_debug_rd_data(20,0),0.U(7-ICACHE_STATUS_BITS),way_status ,0.U(3.W) ,ic_debug_tag_val_rd_out) , else Cat(0.U(6.W),io.ic.tag_debug_rd_data(21),0.U(32.W),io.ic.tag_debug_rd_data(20,0),0.U(7-ICACHE_STATUS_BITS),way_status ,0.U(3.W) ,ic_debug_tag_val_rd_out) ,
io.ic.debug_rd_data) io.ic.debug_rd_data)
io.dec_mem_ctrl.ifu_ic_debug_rd_data := withClock(debug_data_clk){RegNext(ifu_ic_debug_rd_data_in, 0.U)}
io.dec_mem_ctrl.ifu_ic_debug_rd_data := rvdffe(ifu_ic_debug_rd_data_in,ic_debug_rd_en_ff,clock,io.scan_mode)//withClock(debug_data_clk){RegNext(ifu_ic_debug_rd_data_in, 0.U)}
val ic_wr_parity = (0 until 4).map(i=>rveven_paritygen(ifu_bus_rdata_ff((16*i)+15,16*i))).reverse.reduce(Cat(_,_)) val ic_wr_parity = (0 until 4).map(i=>rveven_paritygen(ifu_bus_rdata_ff((16*i)+15,16*i))).reverse.reduce(Cat(_,_))
val ic_miss_buff_parity = (0 until 4).map(i=>rveven_paritygen(ic_miss_buff_half((16*i)+15,16*i))).reverse.reduce(Cat(_,_)) val ic_miss_buff_parity = (0 until 4).map(i=>rveven_paritygen(ic_miss_buff_half((16*i)+15,16*i))).reverse.reduce(Cat(_,_))
@ -267,52 +270,59 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
val bus_ifu_wr_data_error_ff = WireInit(Bool(), 0.U) val bus_ifu_wr_data_error_ff = WireInit(Bool(), 0.U)
val ifu_wr_data_comb_err_ff = WireInit(Bool(), 0.U) val ifu_wr_data_comb_err_ff = WireInit(Bool(), 0.U)
val reset_beat_cnt = WireInit(Bool(), 0.U) val reset_beat_cnt = WireInit(Bool(), 0.U)
val ifu_wr_cumulative_err = (bus_ifu_wr_data_error_ff | ifu_wr_data_comb_err_ff) & !reset_beat_cnt val ifu_wr_data_comb_err = bus_ifu_wr_data_error_ff
ifu_wr_cumulative_err_data := bus_ifu_wr_data_error_ff | ifu_wr_data_comb_err_ff val ifu_wr_cumulative_err = (ifu_wr_data_comb_err | ifu_wr_data_comb_err_ff) & !reset_beat_cnt
ifu_wr_data_comb_err_ff := rvdffie(ifu_wr_cumulative_err,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.free_clk) {RegNext(ifu_wr_cumulative_err, 0.U)} ifu_wr_cumulative_err_data := ifu_wr_data_comb_err | ifu_wr_data_comb_err_ff
ifu_wr_data_comb_err_ff := withClock(io.free_clk) {RegNext(ifu_wr_cumulative_err, 0.U)}
val ic_crit_wd_rdy = WireInit(Bool(), 0.U) val ic_crit_wd_rdy = WireInit(Bool(), 0.U)
val ifu_byp_data_err_f = WireInit(UInt(2.W), 0.U) val ifu_byp_data_err_new = WireInit(Bool(), 0.U)
val sel_byp_data = (ic_crit_wd_rdy | (miss_state===stream_C) | (miss_state===crit_byp_ok_C)) val sel_byp_data = (ic_crit_wd_rdy | (miss_state===stream_C) | (miss_state===crit_byp_ok_C)) & !ifu_byp_data_err_new
val sel_ic_data = !(ic_crit_wd_rdy | (miss_state===stream_C) | (miss_state===crit_byp_ok_C) | (miss_state === miss_wait_C)) & !fetch_req_iccm_f & !ifc_region_acc_fault_final_f val sel_ic_data = !(ic_crit_wd_rdy | (miss_state===stream_C) | (miss_state===crit_byp_ok_C)) & !fetch_req_iccm_f
val sel_iccm_data = fetch_req_iccm_f
val ic_byp_data_only_new = WireInit(UInt(80.W), 0.U) val ic_byp_data_only_new = WireInit(UInt(80.W), 0.U)
val final_data_sel1 = VecInit(sel_byp_data | sel_iccm_data | sel_ic_data, sel_byp_data, sel_byp_data | sel_ic_data, sel_byp_data)
val ic_final_data = if(ICCM_ICACHE) Fill(64, sel_byp_data | fetch_req_iccm_f | sel_ic_data) & io.ic.rd_data else val final_data_sel2 = VecInit(true.B, sel_iccm_data, true.B, true.B)
if (ICCM_ONLY) (Fill(64, sel_byp_data) & ic_byp_data_only_new) | (Fill(64, fetch_req_iccm_f) & io.iccm.rd_data) else val final_data_out1 = VecInit(io.ic.rd_data, ic_byp_data_only_new, io.ic.rd_data, ic_byp_data_only_new)
val final_data_out2 = VecInit(1.U, io.iccm.rd_data, 1.U, 1.U)
val ic_final_data = if(ICCM_ICACHE) Fill(64, sel_byp_data | sel_iccm_data | sel_ic_data) & io.ic.rd_data else
if (ICCM_ONLY) (Fill(64, sel_byp_data) & ic_byp_data_only_new) | (Fill(64, sel_iccm_data) & io.iccm.rd_data) else
if (ICACHE_ONLY) Fill(64, sel_byp_data | sel_ic_data) & io.ic.rd_data else if (ICACHE_ONLY) Fill(64, sel_byp_data | sel_ic_data) & io.ic.rd_data else
if (NO_ICCM_NO_ICACHE) Fill(64, sel_byp_data) & ic_byp_data_only_new else 0.U if (NO_ICCM_NO_ICACHE) Fill(64, sel_byp_data) & ic_byp_data_only_new else 0.U
val ic_premux_data_temp = if(ICCM_ICACHE) (Fill(64,fetch_req_iccm_f) & io.iccm.rd_data) | (Fill(64, sel_byp_data) & ic_byp_data_only_new) val ic_premux_data_temp = if(ICCM_ICACHE) (Fill(64,sel_iccm_data) & io.iccm.rd_data) | (Fill(64, sel_byp_data) & ic_byp_data_only_new)
else if(ICACHE_ONLY) Fill(64, sel_byp_data) & ic_byp_data_only_new else 0.U else if(ICACHE_ONLY) Fill(64, sel_byp_data) & ic_byp_data_only_new else 0.U
val ic_sel_premux_data_temp = if(ICCM_ICACHE) fetch_req_iccm_f | sel_byp_data else if(ICACHE_ONLY) sel_byp_data else 0.U val ic_sel_premux_data_temp = if(ICCM_ICACHE) sel_iccm_data | sel_byp_data else if(ICACHE_ONLY) sel_byp_data else 0.U
io.ic.premux_data := ic_premux_data_temp io.ic.premux_data := ic_premux_data_temp
io.ic.sel_premux_data := ic_sel_premux_data_temp io.ic.sel_premux_data := ic_sel_premux_data_temp
val ifc_bus_acc_fault_f = Fill(2,ic_byp_hit_f) & ifu_byp_data_err_f val ifc_bus_acc_fault_f = ic_byp_hit_f & ifu_byp_data_err_new
io.ic_data_f := ic_final_data io.ic_data_f := ic_final_data
val fetch_req_f_qual = io.ic_hit_f & !io.exu_flush_final val fetch_req_f_qual = io.ic_hit_f & !io.exu_flush_final
val ifc_region_acc_fault_memory_f = WireInit(Bool(), 0.U) val ifc_region_acc_fault_memory_f = WireInit(Bool(), 0.U)
io.ic_access_fault_f := (Fill(2,ifc_region_acc_fault_final_f) | ifc_bus_acc_fault_f) & Fill(2,!io.exu_flush_final) io.ic_access_fault_f := (ifc_region_acc_fault_final_f | ifc_bus_acc_fault_f) & !io.exu_flush_final
io.ic_access_fault_type_f := Mux(io.iccm_rd_ecc_double_err.orR, 1.U, Mux(ifc_region_acc_fault_f, 2.U, Mux(ifc_region_acc_fault_memory_f, 3.U, 0.U))) io.ic_access_fault_type_f := Mux(io.iccm_rd_ecc_double_err.asBool, 1.U,
Mux(ifc_region_acc_fault_f.asBool, 2.U,
Mux(ifc_region_acc_fault_memory_f.asBool(), 3.U, 0.U)))
io.ic_fetch_val_f := Cat(fetch_req_f_qual & io.ifu_bp_inst_mask_f & !(vaddr_f===Fill(ICACHE_BEAT_ADDR_HI,1.U)) & (err_stop_state=/=err_fetch2_C), fetch_req_f_qual) io.ic_fetch_val_f := Cat(fetch_req_f_qual & io.ifu_bp_inst_mask_f & !(vaddr_f===Fill(ICACHE_BEAT_ADDR_HI,1.U)) & (err_stop_state=/=err_fetch2_C), fetch_req_f_qual)
val two_byte_instr = io.ic_data_f(1,0) =/= 3.U val two_byte_instr = io.ic_data_f(1,0) =/= 3.U
//// Creating full buffer //// Creating full buffer
val ic_miss_buff_data_in = io.ifu_axi.r.bits.data val ifu_bus_rsp_rdata = WireInit(UInt(64.W), 0.U)
val bus_ifu_wr_en = WireInit(Bool(), 0.B) val ic_miss_buff_data_in = ifu_bus_rsp_rdata
val write_fill_data = (0 until ICACHE_NUM_BEATS).map(i=>bus_ifu_wr_en & (io.ifu_axi.r.bits.id===i.U)) val ifu_bus_rsp_tag = WireInit(UInt(IFU_BUS_TAG.W), 0.U)
val bus_ifu_wr_en = WireInit(Bool(), false.B)
val write_fill_data = (0 until ICACHE_NUM_BEATS).map(i=>bus_ifu_wr_en & (ifu_bus_rsp_tag===i.U))
val ic_miss_buff_data = Wire(Vec(2*ICACHE_NUM_BEATS, UInt(32.W))) val ic_miss_buff_data = Wire(Vec(2*ICACHE_NUM_BEATS, UInt(32.W)))
for(i<- 0 until ICACHE_NUM_BEATS){ for(i<- 0 until ICACHE_NUM_BEATS){
//val wr_data_c1_clk = write_fill_data.map(rvclkhdr(clock, _ , io.scan_mode)) val wr_data_c1_clk = write_fill_data.map(rvclkhdr(clock, _ , io.scan_mode))
ic_miss_buff_data(2 * i) := rvdffe(ic_miss_buff_data_in(31, 0), write_fill_data(i), clock, io.scan_mode) //withClock(wr_data_c1_clk(i)){RegNext(ic_miss_buff_data_in(31,0), 0.U)} ic_miss_buff_data(2*i) := withClock(wr_data_c1_clk(i)){RegNext(ic_miss_buff_data_in(31,0), 0.U)}
ic_miss_buff_data(2 * i + 1) := rvdffe(ic_miss_buff_data_in(63, 32), write_fill_data(i), clock, io.scan_mode) //withClock(wr_data_c1_clk(i)){RegNext(ic_miss_buff_data_in(63,32), 0.U)}} ic_miss_buff_data(2*i+1) := withClock(wr_data_c1_clk(i)){RegNext(ic_miss_buff_data_in(63,32), 0.U)}}
}
val ic_miss_buff_data_valid = WireInit(UInt(ICACHE_NUM_BEATS.W), 0.U) val ic_miss_buff_data_valid = WireInit(UInt(ICACHE_NUM_BEATS.W), 0.U)
val ic_miss_buff_data_valid_in = (0 until ICACHE_NUM_BEATS).map(i=>write_fill_data(i)|(ic_miss_buff_data_valid(i)&(!ic_act_miss_f))) val ic_miss_buff_data_valid_in = (0 until ICACHE_NUM_BEATS).map(i=>write_fill_data(i)|(ic_miss_buff_data_valid(i)&(!ic_act_miss_f)))
ic_miss_buff_data_valid := withClock(io.active_clk){RegNext(ic_miss_buff_data_valid_in.map(i=>i.asUInt()).reverse.reduce(Cat(_,_)), 0.U)} ic_miss_buff_data_valid := withClock(io.free_clk){RegNext(ic_miss_buff_data_valid_in.map(i=>i.asUInt()).reverse.reduce(Cat(_,_)), 0.U)}
val bus_ifu_wr_data_error = WireInit(Bool(), 0.U) val bus_ifu_wr_data_error = WireInit(Bool(), 0.U)
val ic_miss_buff_data_error = WireInit(UInt(ICACHE_NUM_BEATS.W), 0.U) val ic_miss_buff_data_error = WireInit(UInt(ICACHE_NUM_BEATS.W), 0.U)
val ic_miss_buff_data_error_in =(0 until ICACHE_NUM_BEATS).map(i=>Mux(write_fill_data(i).asBool,bus_ifu_wr_data_error, val ic_miss_buff_data_error_in =(0 until ICACHE_NUM_BEATS).map(i=>Mux(write_fill_data(i).asBool,bus_ifu_wr_data_error,
ic_miss_buff_data_error(i) & !ic_act_miss_f)) ic_miss_buff_data_error(i) & !ic_act_miss_f))
ic_miss_buff_data_error := withClock(io.active_clk){RegNext(ic_miss_buff_data_error_in.reverse.reduce(Cat(_,_)), 0.U)} ic_miss_buff_data_error := withClock(io.free_clk){RegNext(ic_miss_buff_data_error_in.reverse.reduce(Cat(_,_)), 0.U)}
// New Bypass ready // New Bypass ready
val bypass_index = imb_ff(ICACHE_BEAT_ADDR_HI-1, 0) val bypass_index = imb_ff(ICACHE_BEAT_ADDR_HI-1, 0)
@ -329,7 +339,7 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
val ic_crit_wd_rdy_new_in = (bypass_data_ready_in & crit_wd_byp_ok_ff & uncacheable_miss_ff & !io.exu_flush_final & !ifu_bp_hit_taken_q_f) | val ic_crit_wd_rdy_new_in = (bypass_data_ready_in & crit_wd_byp_ok_ff & uncacheable_miss_ff & !io.exu_flush_final & !ifu_bp_hit_taken_q_f) |
( crit_wd_byp_ok_ff & !uncacheable_miss_ff & !io.exu_flush_final & !ifu_bp_hit_taken_q_f) | ( crit_wd_byp_ok_ff & !uncacheable_miss_ff & !io.exu_flush_final & !ifu_bp_hit_taken_q_f) |
(ic_crit_wd_rdy_new_ff & crit_wd_byp_ok_ff & !fetch_req_icache_f & !io.exu_flush_final) (ic_crit_wd_rdy_new_ff & crit_wd_byp_ok_ff & !fetch_req_icache_f & !io.exu_flush_final)
ic_crit_wd_rdy_new_ff := rvdffie(ic_crit_wd_rdy_new_in,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.free_clk){RegNext(ic_crit_wd_rdy_new_in, 0.U)} ic_crit_wd_rdy_new_ff := withClock(io.free_clk){RegNext(ic_crit_wd_rdy_new_in, 0.U)}
val byp_fetch_index = ifu_fetch_addr_int_f(ICACHE_BEAT_ADDR_HI-1,0) val byp_fetch_index = ifu_fetch_addr_int_f(ICACHE_BEAT_ADDR_HI-1,0)
val byp_fetch_index_0 = Cat(ifu_fetch_addr_int_f(ICACHE_BEAT_ADDR_HI-1,2), 0.U) val byp_fetch_index_0 = Cat(ifu_fetch_addr_int_f(ICACHE_BEAT_ADDR_HI-1,2), 0.U)
val byp_fetch_index_1 = Cat(ifu_fetch_addr_int_f(ICACHE_BEAT_ADDR_HI-1,2), 1.U) val byp_fetch_index_1 = Cat(ifu_fetch_addr_int_f(ICACHE_BEAT_ADDR_HI-1,2), 1.U)
@ -338,18 +348,19 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
val byp_fetch_index_inc_1 = Cat(byp_fetch_index_inc, 1.U) val byp_fetch_index_inc_1 = Cat(byp_fetch_index_inc, 1.U)
val ic_miss_buff_data_error_bypass = Mux1H((0 until ICACHE_NUM_BEATS).map(i=>(bypass_index(ICACHE_BEAT_ADDR_HI-1,2)===i.U).asBool->ic_miss_buff_data_error(i))) val ic_miss_buff_data_error_bypass = Mux1H((0 until ICACHE_NUM_BEATS).map(i=>(bypass_index(ICACHE_BEAT_ADDR_HI-1,2)===i.U).asBool->ic_miss_buff_data_error(i)))
val ic_miss_buff_data_error_bypass_inc = Mux1H((0 until ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_inc===i.U).asBool->ic_miss_buff_data_error(i))) val ic_miss_buff_data_error_bypass_inc = Mux1H((0 until ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_inc===i.U).asBool->ic_miss_buff_data_error(i)))
val miss_wrap_f = WireInit(Bool(),0.B) ifu_byp_data_err_new := (!ifu_fetch_addr_int_f(1) & !ifu_fetch_addr_int_f(0) & ic_miss_buff_data_error(byp_fetch_index(ICACHE_BEAT_ADDR_HI-1,2))) |
ifu_byp_data_err_f := Mux(ic_miss_buff_data_error(byp_fetch_index(ICACHE_BEAT_ADDR_HI-1,2) ) , 3.U, (!ifu_fetch_addr_int_f(1) & ifu_fetch_addr_int_f(0) & ic_miss_buff_data_error(byp_fetch_index(ICACHE_BEAT_ADDR_HI-1,2))) |
Mux((ifu_fetch_addr_int_f(1) & ifu_fetch_addr_int_f(0) & ~(ic_miss_buff_data_error(byp_fetch_index(ICACHE_BEAT_ADDR_HI-1,2))) & (!ifu_fetch_addr_int_f(1) & ifu_fetch_addr_int_f(0) & ic_miss_buff_data_error(byp_fetch_index(ICACHE_BEAT_ADDR_HI-1,2))) |
(~miss_wrap_f & ic_miss_buff_data_error(byp_fetch_index_inc))), 2.U, 0.U)) ( ifu_fetch_addr_int_f(1) & !ifu_fetch_addr_int_f(0) & ic_miss_buff_data_error(byp_fetch_index(ICACHE_BEAT_ADDR_HI-1,2))) |
(ifu_fetch_addr_int_f(1) & ifu_fetch_addr_int_f(0) & (ic_miss_buff_data_error(byp_fetch_index(ICACHE_BEAT_ADDR_HI-1,2)) |
ic_miss_buff_data_error(byp_fetch_index_inc(ICACHE_BEAT_ADDR_HI-3,0))))
val ic_byp_data_only_pre_new = Mux(!ifu_fetch_addr_int_f(1).asBool, val ic_byp_data_only_pre_new = Mux(!ifu_fetch_addr_int_f(1).asBool,
Cat(Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_inc_0===i.U).asBool->ic_miss_buff_data(i)(15,0))), Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_1===i.U).asBool->ic_miss_buff_data(i)(31,0))), Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_0===i.U).asBool->ic_miss_buff_data(i)(31,0)))), Cat(Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_inc_0===i.U).asBool->ic_miss_buff_data(i)(15,0))), Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_1===i.U).asBool->ic_miss_buff_data(i)(31,0))), Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_0===i.U).asBool->ic_miss_buff_data(i)(31,0)))),
Cat(Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_inc_1===i.U).asBool->ic_miss_buff_data(i)(15,0))), Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_inc_0===i.U).asBool->ic_miss_buff_data(i)(31,0))), Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_1===i.U).asBool->ic_miss_buff_data(i)(31,0))))) Cat(Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_inc_1===i.U).asBool->ic_miss_buff_data(i)(15,0))), Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_inc_0===i.U).asBool->ic_miss_buff_data(i)(31,0))), Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_1===i.U).asBool->ic_miss_buff_data(i)(31,0)))))
ic_byp_data_only_new := Mux(!ifu_fetch_addr_int_f(0).asBool(),ic_byp_data_only_pre_new,Cat(0.U(16.W),ic_byp_data_only_pre_new(79,16))) ic_byp_data_only_new := Mux(!ifu_fetch_addr_int_f(0).asBool(),ic_byp_data_only_pre_new,Cat(0.U(16.W),ic_byp_data_only_pre_new(79,16)))
miss_wrap_f := imb_ff(ICACHE_TAG_INDEX_LO-1) =/= ifu_fetch_addr_int_f(ICACHE_TAG_INDEX_LO-1) val miss_wrap_f = imb_ff(ICACHE_TAG_INDEX_LO-1) =/= ifu_fetch_addr_int_f(ICACHE_TAG_INDEX_LO-1)
val ic_miss_buff_data_valid_bypass_index = Mux1H((0 until ICACHE_NUM_BEATS).map(i=>(byp_fetch_index(ICACHE_BEAT_ADDR_HI-1,2)===i.U).asBool->ic_miss_buff_data_valid(i))) val ic_miss_buff_data_valid_bypass_index = Mux1H((0 until ICACHE_NUM_BEATS).map(i=>(byp_fetch_index(ICACHE_BEAT_ADDR_HI-1,2)===i.U).asBool->ic_miss_buff_data_valid(i)))
val ic_miss_buff_data_valid_inc_bypass_index = Mux1H((0 until ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_inc===i.U).asBool->ic_miss_buff_data_valid(i))) val ic_miss_buff_data_valid_inc_bypass_index = Mux1H((0 until ICACHE_NUM_BEATS).map(i=>(byp_fetch_index_inc===i.U).asBool->ic_miss_buff_data_valid(i)))
val miss_buff_hit_unq_f = (ic_miss_buff_data_valid_bypass_index & !byp_fetch_index(1) & !byp_fetch_index(0)) | val miss_buff_hit_unq_f = (ic_miss_buff_data_valid_bypass_index & !byp_fetch_index(1) & !byp_fetch_index(0)) |
@ -371,23 +382,23 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(Cat(other_tag,0.U)===i.U).asBool->ic_miss_buff_data(i)))) Mux1H((0 until 2*ICACHE_NUM_BEATS).map(i=>(Cat(other_tag,0.U)===i.U).asBool->ic_miss_buff_data(i))))
// Parity check for the I$ logic // Parity check for the I$ logic
ic_rd_parity_final_err := io.ic.tag_perr & !io.exu_flush_final & sel_ic_data & !(ifc_region_acc_fault_final_f | (ifc_bus_acc_fault_f.orR)) & ic_rd_parity_final_err := io.ic.tag_perr & sel_ic_data & !(ifc_region_acc_fault_final_f | ifc_bus_acc_fault_f)
(fetch_req_icache_f & !reset_all_tags & (!miss_pending | (miss_state===hit_u_miss_C)) & !sel_mb_addr_ff);
val ifu_ic_rw_int_addr_ff = WireInit(UInt((ICACHE_INDEX_HI-ICACHE_TAG_INDEX_LO+1).W), 0.U) val ifu_ic_rw_int_addr_ff = WireInit(UInt((ICACHE_INDEX_HI-ICACHE_TAG_INDEX_LO+1).W), 0.U)
val perr_sb_write_status = WireInit(Bool(), 0.B) val perr_sb_write_status = WireInit(Bool(), false.B)
val perr_ic_index_ff = rvdffe(ifu_ic_rw_int_addr_ff,perr_sb_write_status,clock,io.scan_mode)//withClock(io.active_clk){RegEnable(ifu_ic_rw_int_addr_ff, 0.U, perr_sb_write_status)} val perr_ic_index_ff = withClock(io.active_clk){RegEnable(ifu_ic_rw_int_addr_ff, 0.U, perr_sb_write_status)}
val perr_sel_invalidate = WireInit(Bool(), 0.B) val perr_sel_invalidate = WireInit(Bool(), false.B)
val perr_err_inv_way = Fill(ICACHE_NUM_WAYS, perr_sel_invalidate) val perr_err_inv_way = Fill(ICACHE_NUM_WAYS, perr_sel_invalidate)
iccm_correct_ecc := perr_state === ecc_cor_C iccm_correct_ecc := perr_state === ecc_cor_C
val dma_sb_err_state_ff = rvdffie(perr_state === dma_sb_err_C,io.free_l2clk,reset.asAsyncReset(),io.scan_mode) val dma_sb_err_state = perr_state === dma_sb_err_C
val dma_sb_err_state_ff = Wire(Bool())
io.iccm.buf_correct_ecc := iccm_correct_ecc & !dma_sb_err_state_ff io.iccm.buf_correct_ecc := iccm_correct_ecc & !dma_sb_err_state_ff
dma_sb_err_state_ff := withClock(io.active_clk){RegNext(dma_sb_err_state, false.B)}
///////////////////////////////// PARITY ERROR FSM ///////////////////////////////// ///////////////////////////////// PARITY ERROR FSM /////////////////////////////////
val perr_nxtstate = WireInit(UInt(3.W), 0.U) val perr_nxtstate = WireInit(UInt(3.W), 0.U)
val perr_state_en = WireInit(Bool(), 0.B) val perr_state_en = WireInit(Bool(), false.B)
val iccm_error_start = if(ICCM_ENABLE) io.dec_mem_ctrl.ifu_iccm_rd_ecc_single_err else 0.U val iccm_error_start = WireInit(Bool(), false.B)
switch(perr_state){ switch(perr_state){
is(err_idle_C){ is(err_idle_C){
perr_nxtstate := Mux(io.iccm_dma_sb_error, dma_sb_err_C, Mux((io.dec_mem_ctrl.ifu_ic_error_start & !io.exu_flush_final).asBool, ic_wff_C, ecc_wff_C)) perr_nxtstate := Mux(io.iccm_dma_sb_error, dma_sb_err_C, Mux((io.dec_mem_ctrl.ifu_ic_error_start & !io.exu_flush_final).asBool, ic_wff_C, ecc_wff_C))
@ -405,18 +416,18 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
} }
is(dma_sb_err_C){ is(dma_sb_err_C){
perr_nxtstate := Mux(io.dec_mem_ctrl.dec_tlu_force_halt, err_idle_C, ecc_cor_C) perr_nxtstate := Mux(io.dec_mem_ctrl.dec_tlu_force_halt, err_idle_C, ecc_cor_C)
perr_state_en := 1.B perr_state_en := true.B
} }
is(ecc_cor_C){ is(ecc_cor_C){
perr_nxtstate := err_idle_C perr_nxtstate := err_idle_C
perr_state_en := 1.B perr_state_en := true.B
} }
} }
perr_state := withClock(io.active_clk){RegEnable(perr_nxtstate, 0.U, perr_state_en)} perr_state := withClock(io.free_clk){RegEnable(perr_nxtstate, 0.U, perr_state_en)}
///////////////////////////////// STOP FETCH FSM ///////////////////////////////// ///////////////////////////////// STOP FETCH FSM /////////////////////////////////
val err_stop_nxtstate = WireInit(UInt(2.W), 0.U) val err_stop_nxtstate = WireInit(UInt(2.W), 0.U)
val err_stop_state_en = WireInit(Bool(), 0.B) val err_stop_state_en = WireInit(Bool(), false.B)
io.iccm.correction_state := 0.B io.iccm.correction_state := false.B
switch(err_stop_state){ switch(err_stop_state){
is(err_stop_idle_C){ is(err_stop_idle_C){
err_stop_nxtstate := err_fetch1_C err_stop_nxtstate := err_fetch1_C
@ -428,167 +439,190 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
Mux(io.ifu_fetch_val(0).asBool(), err_fetch2_C, err_fetch1_C))) Mux(io.ifu_fetch_val(0).asBool(), err_fetch2_C, err_fetch1_C)))
err_stop_state_en := io.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.ifu_fetch_val(0) | ifu_bp_hit_taken_q_f | io.dec_mem_ctrl.dec_tlu_force_halt err_stop_state_en := io.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.ifu_fetch_val(0) | ifu_bp_hit_taken_q_f | io.dec_mem_ctrl.dec_tlu_force_halt
err_stop_fetch := ((io.ifu_fetch_val(1,0)===3.U) | (io.ifu_fetch_val(0) & two_byte_instr)) & !(io.exu_flush_final | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt) err_stop_fetch := ((io.ifu_fetch_val(1,0)===3.U) | (io.ifu_fetch_val(0) & two_byte_instr)) & !(io.exu_flush_final | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt)
io.iccm.correction_state := 1.B io.iccm.correction_state := true.B
} }
is(err_fetch2_C){ is(err_fetch2_C){
err_stop_nxtstate := Mux((io.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.dec_mem_ctrl.dec_tlu_force_halt).asBool, err_stop_nxtstate := Mux((io.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.dec_mem_ctrl.dec_tlu_force_halt).asBool,
err_stop_idle_C, Mux(io.ifu_fetch_val(0).asBool, err_stop_fetch_C, err_fetch2_C)) err_stop_idle_C, Mux(io.ifu_fetch_val(0).asBool, err_stop_fetch_C, err_fetch2_C))
err_stop_state_en := io.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.ifu_fetch_val(0) | io.dec_mem_ctrl.dec_tlu_force_halt err_stop_state_en := io.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.ifu_fetch_val(0) | io.dec_mem_ctrl.dec_tlu_force_halt
err_stop_fetch := io.ifu_fetch_val(0) & !io.exu_flush_final & !io.dec_mem_ctrl.dec_tlu_i0_commit_cmt err_stop_fetch := io.ifu_fetch_val(0) & !io.exu_flush_final & !io.dec_mem_ctrl.dec_tlu_i0_commit_cmt
io.iccm.correction_state := 1.B io.iccm.correction_state := true.B
} }
is(err_stop_fetch_C){ is(err_stop_fetch_C){
err_stop_nxtstate := Mux(((io.dec_tlu_flush_lower_wb & !io.dec_mem_ctrl.dec_tlu_flush_err_wb) | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.dec_mem_ctrl.dec_tlu_force_halt).asBool, err_stop_nxtstate := Mux(((io.dec_tlu_flush_lower_wb & !io.dec_mem_ctrl.dec_tlu_flush_err_wb) | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.dec_mem_ctrl.dec_tlu_force_halt).asBool,
err_stop_idle_C, Mux(io.dec_mem_ctrl.dec_tlu_flush_err_wb.asBool(), err_fetch1_C, err_stop_fetch_C)) err_stop_idle_C, Mux(io.dec_mem_ctrl.dec_tlu_flush_err_wb.asBool(), err_fetch1_C, err_stop_fetch_C))
err_stop_state_en := io.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.dec_mem_ctrl.dec_tlu_force_halt err_stop_state_en := io.dec_tlu_flush_lower_wb | io.dec_mem_ctrl.dec_tlu_i0_commit_cmt | io.dec_mem_ctrl.dec_tlu_force_halt
err_stop_fetch := 1.B err_stop_fetch := true.B
io.iccm.correction_state := 1.B io.iccm.correction_state := true.B
} }
} }
err_stop_state := withClock(io.active_clk){RegEnable(err_stop_nxtstate, 0.U, err_stop_state_en)} err_stop_state := withClock(io.free_clk){RegEnable(err_stop_nxtstate, 0.U, err_stop_state_en)}
bus_ifu_bus_clk_en := io.ifu_bus_clk_en bus_ifu_bus_clk_en := io.ifu_bus_clk_en
val busclk = rvclkhdr(clock, bus_ifu_bus_clk_en, io.scan_mode)
val busclk = if(RV_FPGA_OPTIMIZE) 0.B.asClock() else rvclkhdr(clock, bus_ifu_bus_clk_en, io.scan_mode) val busclk_force = rvclkhdr(clock, bus_ifu_bus_clk_en | io.dec_mem_ctrl.dec_tlu_force_halt , io.scan_mode)
val busclk_force = if(RV_FPGA_OPTIMIZE) 0.B.asClock() else rvclkhdr(clock, bus_ifu_bus_clk_en | io.dec_mem_ctrl.dec_tlu_force_halt , io.scan_mode) val bus_ifu_bus_clk_en_ff = withClock(io.free_clk){RegNext(bus_ifu_bus_clk_en, 0.U)}
scnd_miss_req_q := withClock(io.free_clk){RegNext(scnd_miss_req_in, 0.U)}
val scnd_miss_req_ff2 = withClock(io.free_clk){RegNext(scnd_miss_req, 0.U)}
val bus_ifu_bus_clk_en_ff = rvdffie(bus_ifu_bus_clk_en,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.free_clk){RegNext(bus_ifu_bus_clk_en, 0.U)}
scnd_miss_req_q := rvdffie(scnd_miss_req_in,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.free_clk){RegNext(scnd_miss_req_in, 0.U)}
scnd_miss_req := scnd_miss_req_q & (!io.exu_flush_final) scnd_miss_req := scnd_miss_req_q & (!io.exu_flush_final)
val bus_cmd_req_hold = WireInit(Bool(), 0.B) val bus_cmd_req_hold = WireInit(Bool(), false.B)
val ifu_bus_cmd_valid = WireInit(Bool(), 0.B) val ifu_bus_cmd_valid = WireInit(Bool(), false.B)
val bus_cmd_beat_count = WireInit(UInt(ICACHE_BEAT_BITS.W), 0.U) val bus_cmd_beat_count = WireInit(UInt(ICACHE_BEAT_BITS.W), 0.U)
val ifc_bus_ic_req_ff_in = (ic_act_miss_f | bus_cmd_req_hold | ifu_bus_cmd_valid) & !io.dec_mem_ctrl.dec_tlu_force_halt & !((bus_cmd_beat_count===Fill(ICACHE_BEAT_BITS,1.U)) & ifu_bus_cmd_valid & io.ifu_axi.ar.ready & miss_pending) val ifu_bus_cmd_ready = WireInit(Bool(), false.B)
ifu_bus_cmd_valid := rvdff_fpga(ifc_bus_ic_req_ff_in,busclk_force,bus_ifu_bus_clk_en | io.dec_mem_ctrl.dec_tlu_force_halt,clock)//withClock(busclk_force){RegNext(ifc_bus_ic_req_ff_in, 0.U)} val ifc_bus_ic_req_ff_in = (ic_act_miss_f | bus_cmd_req_hold | ifu_bus_cmd_valid) & !io.dec_mem_ctrl.dec_tlu_force_halt & !((bus_cmd_beat_count===Fill(ICACHE_BEAT_BITS,1.U)) & ifu_bus_cmd_valid & ifu_bus_cmd_ready & miss_pending)
val bus_cmd_sent = WireInit(Bool(), 0.B) ifu_bus_cmd_valid := withClock(busclk_force){RegNext(ifc_bus_ic_req_ff_in, 0.U)}
val bus_cmd_sent = WireInit(Bool(), false.B)
val bus_cmd_req_in = (ic_act_miss_f | bus_cmd_req_hold) & !bus_cmd_sent & !io.dec_mem_ctrl.dec_tlu_force_halt val bus_cmd_req_in = (ic_act_miss_f | bus_cmd_req_hold) & !bus_cmd_sent & !io.dec_mem_ctrl.dec_tlu_force_halt
bus_cmd_req_hold := rvdffie(bus_cmd_req_in,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.free_clk){RegNext(bus_cmd_req_in, false.B)} bus_cmd_req_hold := withClock(io.free_clk){RegNext(bus_cmd_req_in, false.B)}
// AXI Read-Channel // AXI Read-Channel
io.ifu_axi <> 0.U.asTypeOf(io.ifu_axi) io.ifu_axi.w.valid := 0.U
io.ifu_axi.ar.bits.prot := 5.U io.ifu_axi.w.bits.data := 0.U
io.ifu_axi.aw.bits.qos := 0.U
io.ifu_axi.aw.bits.addr := 0.U
io.ifu_axi.aw.bits.prot := 0.U
io.ifu_axi.aw.bits.len := 0.U
io.ifu_axi.ar.bits.lock := 0.U
io.ifu_axi.aw.bits.region := 0.U
io.ifu_axi.aw.bits.id := 0.U
io.ifu_axi.aw.valid := 0.U
io.ifu_axi.w.bits.strb := 0.U
io.ifu_axi.aw.bits.cache := 0.U
io.ifu_axi.ar.bits.qos := 0.U
io.ifu_axi.aw.bits.lock := 0.U
io.ifu_axi.b.ready := 0.U
io.ifu_axi.ar.bits.len := 0.U
io.ifu_axi.aw.bits.size := 0.U
io.ifu_axi.ar.bits.prot := 0.U
io.ifu_axi.aw.bits.burst := 0.U
io.ifu_axi.w.bits.last := 0.U
io.ifu_axi.ar.valid := ifu_bus_cmd_valid io.ifu_axi.ar.valid := ifu_bus_cmd_valid
io.ifu_axi.ar.bits.id := bus_rd_addr_count & Fill(IFU_BUS_TAG, ifu_bus_cmd_valid) io.ifu_axi.ar.bits.id := bus_rd_addr_count & Fill(IFU_BUS_TAG, ifu_bus_cmd_valid)
io.ifu_axi.ar.bits.addr := Cat(ifu_ic_req_addr_f, 0.U(3.W)) & Fill(32, ifu_bus_cmd_valid) io.ifu_axi.ar.bits.addr := Cat(ifu_ic_req_addr_f, 0.U(3.W)) & Fill(32, ifu_bus_cmd_valid)
io.ifu_axi.ar.bits.size := 3.U io.ifu_axi.ar.bits.size := 3.U(3.W)
io.ifu_axi.ar.bits.cache := 15.U io.ifu_axi.ar.bits.cache := 15.U
io.ifu_axi.ar.bits.region := ifu_ic_req_addr_f(28,25) io.ifu_axi.ar.bits.region := ifu_ic_req_addr_f(28,25)
io.ifu_axi.ar.bits.burst := 1.U io.ifu_axi.ar.bits.burst := 1.U
io.ifu_axi.r.ready := 1.B io.ifu_axi.r.ready := true.B
val ifu_bus_arready_unq_ff = rvdff_fpga(io.ifu_axi.ar.ready,busclk,bus_ifu_bus_clk_en,clock)//withClock(busclk){RegNext(io.ifu_axi.ar.ready, false.B)} val ifu_bus_arready_unq = io.ifu_axi.ar.ready
val ifu_bus_rvalid_unq_ff = rvdff_fpga(io.ifu_axi.r.valid,busclk,bus_ifu_bus_clk_en,clock)//withClock(busclk){RegNext(io.ifu_axi.r.valid, false.B)} val ifu_bus_rvalid_unq = io.ifu_axi.r.valid
val ifu_bus_arvalid_ff = rvdff_fpga(io.ifu_axi.ar.valid,busclk,bus_ifu_bus_clk_en,clock)//withClock(busclk){RegNext(io.ifu_axi.ar.valid, false.B)} val ifu_bus_arvalid = io.ifu_axi.ar.valid
val ifu_bus_rresp_ff = rvdff_fpga(io.ifu_axi.r.bits.resp,busclk,bus_ifu_bus_clk_en,clock)//withClock(busclk){RegNext(io.ifu_axi.r.bits.resp, 0.U)} val ifu_bus_arready_unq_ff = withClock(busclk){RegNext(ifu_bus_arready_unq, false.B)}
//withClock(busclk){RegNext(io.ifu_axi.r.bits.data, 0.U)} val ifu_bus_rvalid_unq_ff = withClock(busclk){RegNext(ifu_bus_rvalid_unq, false.B)}
ifu_bus_rid_ff := rvdff_fpga(io.ifu_axi.r.bits.id,busclk,bus_ifu_bus_clk_en,clock)//withClock(busclk){RegNext(io.ifu_axi.r.bits.id, 0.U)} val ifu_bus_arvalid_ff = withClock(busclk){RegNext(ifu_bus_arvalid, false.B)}
val ifu_bus_rvalid = io.ifu_axi.r.valid & bus_ifu_bus_clk_en val ifu_bus_rresp_ff = withClock(busclk){RegNext(io.ifu_axi.r.bits.resp, 0.U)}
val ifu_bus_arready = io.ifu_axi.ar.ready & bus_ifu_bus_clk_en ifu_bus_rdata_ff := withClock(busclk){RegNext(io.ifu_axi.r.bits.data, 0.U)}
ifu_bus_rid_ff := withClock(busclk){RegNext(io.ifu_axi.r.bits.id, 0.U)}
ifu_bus_cmd_ready := io.ifu_axi.ar.ready
ifu_bus_rsp_valid := io.ifu_axi.r.valid
ifu_bus_rsp_ready := io.ifu_axi.r.ready
ifu_bus_rsp_tag := io.ifu_axi.r.bits.id
ifu_bus_rsp_rdata := io.ifu_axi.r.bits.data
val ifu_bus_rsp_opc = io.ifu_axi.r.bits.resp
val ifu_bus_rvalid = ifu_bus_rsp_valid & bus_ifu_bus_clk_en
val ifu_bus_arready = ifu_bus_arready_unq & bus_ifu_bus_clk_en
val ifu_bus_arready_ff = ifu_bus_arready_unq_ff & bus_ifu_bus_clk_en_ff val ifu_bus_arready_ff = ifu_bus_arready_unq_ff & bus_ifu_bus_clk_en_ff
val ifu_bus_rvalid_ff = ifu_bus_rvalid_unq_ff & bus_ifu_bus_clk_en_ff val ifu_bus_rvalid_ff = ifu_bus_rvalid_unq_ff & bus_ifu_bus_clk_en_ff
// Write signals to write to the bus // Write signals to write to the bus
bus_cmd_sent := io.ifu_axi.ar.valid & ifu_bus_arready & miss_pending & !io.dec_mem_ctrl.dec_tlu_force_halt bus_cmd_sent := ifu_bus_arvalid & ifu_bus_arready & miss_pending & !io.dec_mem_ctrl.dec_tlu_force_halt
val bus_last_data_beat = WireInit(Bool(), 0.B) val bus_last_data_beat = WireInit(Bool(), false.B)
val bus_inc_data_beat_cnt = bus_ifu_wr_en_ff & !bus_last_data_beat & !io.dec_mem_ctrl.dec_tlu_force_halt val bus_inc_data_beat_cnt = bus_ifu_wr_en_ff & !bus_last_data_beat & !io.dec_mem_ctrl.dec_tlu_force_halt
val bus_reset_data_beat_cnt = ic_act_miss_f | (bus_ifu_wr_en_ff & bus_last_data_beat) | io.dec_mem_ctrl.dec_tlu_force_halt val bus_reset_data_beat_cnt = ic_act_miss_f | (bus_ifu_wr_en_ff & bus_last_data_beat) | io.dec_mem_ctrl.dec_tlu_force_halt
val bus_hold_data_beat_cnt = !bus_inc_data_beat_cnt & !bus_reset_data_beat_cnt val bus_hold_data_beat_cnt = !bus_inc_data_beat_cnt & !bus_reset_data_beat_cnt
val bus_data_beat_count = WireInit(UInt(ICACHE_BEAT_BITS.W), 0.U) val bus_data_beat_count = WireInit(UInt(ICACHE_BEAT_BITS.W), 0.U)
bus_new_data_beat_count := Mux1H(Seq(bus_reset_data_beat_cnt->0.U, bus_inc_data_beat_cnt-> (bus_data_beat_count + 1.U), bus_hold_data_beat_cnt->bus_data_beat_count)) bus_new_data_beat_count := Mux1H(Seq(bus_reset_data_beat_cnt->0.U, bus_inc_data_beat_cnt-> (bus_data_beat_count + 1.U), bus_hold_data_beat_cnt->bus_data_beat_count))
bus_data_beat_count := rvdffie(bus_new_data_beat_count,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.free_clk){RegNext(bus_new_data_beat_count, 0.U)} bus_data_beat_count := withClock(io.free_clk){RegNext(bus_new_data_beat_count, 0.U)}
val last_data_recieved_in = (bus_ifu_wr_en_ff & bus_last_data_beat & !scnd_miss_req) | (last_data_recieved_ff & !ic_act_miss_f) val last_data_recieved_in = (bus_ifu_wr_en_ff & bus_last_data_beat & !scnd_miss_req) | (last_data_recieved_ff & !ic_act_miss_f)
last_data_recieved_ff := rvdffie(last_data_recieved_in,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.free_clk){RegNext(last_data_recieved_in, 0.U)} last_data_recieved_ff := withClock(io.free_clk){RegNext(last_data_recieved_in, 0.U)}
// Request Address Count // Request Address Count
val bus_new_rd_addr_count = Mux(!miss_pending, imb_ff(ICACHE_BEAT_ADDR_HI-1, 2), val bus_new_rd_addr_count = Mux(!miss_pending, imb_ff(ICACHE_BEAT_ADDR_HI-1, 2),
Mux(scnd_miss_req_q, imb_scnd_ff(ICACHE_BEAT_ADDR_HI-1, 2), Mux(scnd_miss_req_q, imb_scnd_ff(ICACHE_BEAT_ADDR_HI-1, 2),
Mux(bus_cmd_sent, bus_rd_addr_count + 1.U, bus_rd_addr_count))) Mux(bus_cmd_sent, bus_rd_addr_count + 1.U, bus_rd_addr_count)))
bus_rd_addr_count := rvdff_fpga(bus_new_rd_addr_count,busclk_reset,bus_ifu_bus_clk_en | ic_act_miss_f | io.dec_mem_ctrl.dec_tlu_force_halt,clock)//withClock(busclk_reset){RegNext(bus_new_rd_addr_count, 0.U)} bus_rd_addr_count := withClock(busclk_reset){RegNext(bus_new_rd_addr_count, 0.U)}
// Command beat Count // Command beat Count
val bus_inc_cmd_beat_cnt = ifu_bus_cmd_valid & io.ifu_axi.ar.ready & miss_pending & !io.dec_mem_ctrl.dec_tlu_force_halt val bus_inc_cmd_beat_cnt = ifu_bus_cmd_valid & ifu_bus_cmd_ready & miss_pending & !io.dec_mem_ctrl.dec_tlu_force_halt
val bus_reset_cmd_beat_cnt_0 = (ic_act_miss_f & !uncacheable_miss_in) | io.dec_mem_ctrl.dec_tlu_force_halt val bus_reset_cmd_beat_cnt_0 = (ic_act_miss_f & !uncacheable_miss_in) | io.dec_mem_ctrl.dec_tlu_force_halt
val bus_reset_cmd_beat_cnt_secondlast = ic_act_miss_f & uncacheable_miss_in val bus_reset_cmd_beat_cnt_secondlast = ic_act_miss_f & uncacheable_miss_in
val bus_hold_cmd_beat_cnt = !bus_inc_cmd_beat_cnt & !(ic_act_miss_f | scnd_miss_req | io.dec_mem_ctrl.dec_tlu_force_halt) val bus_hold_cmd_beat_cnt = !bus_inc_cmd_beat_cnt & !(ic_act_miss_f | scnd_miss_req | io.dec_mem_ctrl.dec_tlu_force_halt)
val bus_cmd_beat_en = bus_inc_cmd_beat_cnt | ic_act_miss_f | io.dec_mem_ctrl.dec_tlu_force_halt val bus_cmd_beat_en = bus_inc_cmd_beat_cnt | ic_act_miss_f | io.dec_mem_ctrl.dec_tlu_force_halt
val bus_new_cmd_beat_count = Mux1H(Seq(bus_reset_cmd_beat_cnt_0->0.U, bus_reset_cmd_beat_cnt_secondlast.asBool->ICACHE_SCND_LAST.U, val bus_new_cmd_beat_count = Mux1H(Seq(bus_reset_cmd_beat_cnt_0->0.U, bus_reset_cmd_beat_cnt_secondlast.asBool->ICACHE_SCND_LAST.U,
bus_inc_cmd_beat_cnt->(bus_cmd_beat_count+1.U), bus_hold_cmd_beat_cnt->bus_cmd_beat_count)) bus_inc_cmd_beat_cnt->(bus_cmd_beat_count+1.U), bus_hold_cmd_beat_cnt->bus_cmd_beat_count))
bus_cmd_beat_count := rvdffs_fpga(bus_new_cmd_beat_count,bus_cmd_beat_en,busclk_reset,bus_ifu_bus_clk_en | ic_act_miss_f | io.dec_mem_ctrl.dec_tlu_force_halt,clock)//withClock(busclk_reset){RegEnable(bus_new_cmd_beat_count, 0.U, bus_cmd_beat_en)} bus_cmd_beat_count := withClock(busclk_reset){RegEnable(bus_new_cmd_beat_count, 0.U, bus_cmd_beat_en)}
bus_last_data_beat := Mux(uncacheable_miss_ff, bus_data_beat_count===1.U, bus_data_beat_count.andR()) bus_last_data_beat := Mux(uncacheable_miss_ff, bus_data_beat_count===1.U, bus_data_beat_count.andR())
bus_ifu_wr_en := ifu_bus_rvalid & miss_pending bus_ifu_wr_en := ifu_bus_rvalid & miss_pending
bus_ifu_wr_en_ff := ifu_bus_rvalid_ff & miss_pending bus_ifu_wr_en_ff := ifu_bus_rvalid_ff & miss_pending
bus_ifu_wr_en_ff_q := ifu_bus_rvalid_ff & miss_pending & !uncacheable_miss_ff & !(ifu_bus_rresp_ff.orR) & write_ic_16_bytes bus_ifu_wr_en_ff_q := ifu_bus_rvalid_ff & miss_pending & !uncacheable_miss_ff & !(ifu_bus_rresp_ff.orR) & write_ic_16_bytes
val bus_ifu_wr_en_ff_wo_err = ifu_bus_rvalid_ff & miss_pending & !uncacheable_miss_ff val bus_ifu_wr_en_ff_wo_err = ifu_bus_rvalid_ff & miss_pending & !uncacheable_miss_ff
val ic_act_miss_f_delayed = rvdffie(ic_act_miss_f,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.free_clk){RegNext(ic_act_miss_f, false.B)} val ic_act_miss_f_delayed = withClock(io.free_clk){RegNext(ic_act_miss_f, false.B)}
reset_tag_valid_for_miss := ic_act_miss_f_delayed & (miss_state===crit_byp_ok_C) & !uncacheable_miss_ff reset_tag_valid_for_miss := ic_act_miss_f_delayed & (miss_state===crit_byp_ok_C) & !uncacheable_miss_ff
bus_ifu_wr_data_error := io.ifu_axi.r.bits.resp.orR() & ifu_bus_rvalid & miss_pending bus_ifu_wr_data_error := ifu_bus_rsp_opc.orR() & ifu_bus_rvalid & miss_pending
bus_ifu_wr_data_error_ff := ifu_bus_rresp_ff.orR & ifu_bus_rvalid_ff & miss_pending bus_ifu_wr_data_error_ff := ifu_bus_rresp_ff.orR & ifu_bus_rvalid_ff & miss_pending
val ifc_dma_access_ok_d = io.ifc_dma_access_ok & !iccm_correct_ecc & !io.iccm_dma_sb_error val ifc_dma_access_ok_d = WireInit(Bool(), false.B)
val ifc_dma_access_ok_prev = rvdffie(ifc_dma_access_ok_d,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.free_clk){RegNext(ifc_dma_access_ok_d, false.B)} val ifc_dma_access_ok_prev = withClock(io.free_clk){RegNext(ifc_dma_access_ok_d, false.B)}
ic_crit_wd_rdy := ic_crit_wd_rdy_new_in | ic_crit_wd_rdy_new_ff ic_crit_wd_rdy := ic_crit_wd_rdy_new_in | ic_crit_wd_rdy_new_ff
last_beat := bus_last_data_beat & bus_ifu_wr_en_ff last_beat := bus_last_data_beat & bus_ifu_wr_en_ff
reset_beat_cnt := bus_reset_data_beat_cnt reset_beat_cnt := bus_reset_data_beat_cnt
// DMA // DMA
ifc_dma_access_ok_d := io.ifc_dma_access_ok & !iccm_correct_ecc & !io.iccm_dma_sb_error
io.iccm_ready := io.ifc_dma_access_ok & !iccm_correct_ecc & ifc_dma_access_ok_prev & (perr_state===err_idle_C) & !io.iccm_dma_sb_error val ifc_dma_access_q_ok = io.ifc_dma_access_ok & !iccm_correct_ecc & ifc_dma_access_ok_prev & (perr_state===err_idle_C) & !io.iccm_dma_sb_error
dma_iccm_req_f := rvdffie(io.dma_mem_ctl.dma_iccm_req,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.free_clk){RegNext(io.dma_mem_ctl.dma_iccm_req, false.B)} io.iccm_ready := ifc_dma_access_q_ok
io.iccm.wren := (io.iccm_ready & io.dma_mem_ctl.dma_iccm_req & io.dma_mem_ctl.dma_mem_write) | iccm_correct_ecc dma_iccm_req_f := withClock(io.free_clk){RegNext(io.dma_mem_ctl.dma_iccm_req, false.B)}
io.iccm.rden := (io.iccm_ready & io.dma_mem_ctl.dma_iccm_req & !io.dma_mem_ctl.dma_mem_write) | (io.ifc_iccm_access_bf & io.ifc_fetch_req_bf) io.iccm.wren := (ifc_dma_access_q_ok & io.dma_mem_ctl.dma_iccm_req & io.dma_mem_ctl.dma_mem_write) | iccm_correct_ecc
val iccm_dma_rden = io.iccm_ready & io.dma_mem_ctl.dma_iccm_req & !io.dma_mem_ctl.dma_mem_write io.iccm.rden := (ifc_dma_access_q_ok & io.dma_mem_ctl.dma_iccm_req & !io.dma_mem_ctl.dma_mem_write) | (io.ifc_iccm_access_bf & io.ifc_fetch_req_bf)
val iccm_dma_rden = ifc_dma_access_q_ok & io.dma_mem_ctl.dma_iccm_req & !io.dma_mem_ctl.dma_mem_write
io.iccm.wr_size := Fill(3, io.dma_mem_ctl.dma_iccm_req) & io.dma_mem_ctl.dma_mem_sz io.iccm.wr_size := Fill(3, io.dma_mem_ctl.dma_iccm_req) & io.dma_mem_ctl.dma_mem_sz
val dma_mem_ecc = Cat(rvecc_encode(io.dma_mem_ctl.dma_mem_wdata(63,32)), rvecc_encode(io.dma_mem_ctl.dma_mem_wdata(31,0))) val dma_mem_ecc = Cat(rvecc_encode(io.dma_mem_ctl.dma_mem_wdata(63,32)), rvecc_encode(io.dma_mem_ctl.dma_mem_wdata(31,0)))
val iccm_ecc_corr_data_ff = WireInit(UInt(39.W), 0.U) val iccm_ecc_corr_data_ff = WireInit(UInt(39.W), 0.U)
io.iccm.wr_data := Mux(iccm_correct_ecc & !(io.iccm_ready & io.dma_mem_ctl.dma_iccm_req), Fill(2,iccm_ecc_corr_data_ff), io.iccm.wr_data := Mux(iccm_correct_ecc & !(ifc_dma_access_q_ok & io.dma_mem_ctl.dma_iccm_req), Fill(2,iccm_ecc_corr_data_ff),
Cat(dma_mem_ecc(13,7),io.dma_mem_ctl.dma_mem_wdata(63,32), dma_mem_ecc(6,0), io.dma_mem_ctl.dma_mem_wdata(31,0))) Cat(dma_mem_ecc(13,7),io.dma_mem_ctl.dma_mem_wdata(63,32), dma_mem_ecc(6,0), io.dma_mem_ctl.dma_mem_wdata(31,0)))
val iccm_corrected_data = Wire(Vec(2, UInt(32.W))) val iccm_corrected_data = Wire(Vec(2, UInt(32.W)))
iccm_corrected_data(0) := 0.U
iccm_corrected_data(1) := 0.U
val dma_mem_addr_ff = WireInit(UInt(2.W), 0.U) val dma_mem_addr_ff = WireInit(UInt(2.W), 0.U)
val iccm_dma_rdata_1_muxed = Mux(dma_mem_addr_ff(0).asBool, iccm_corrected_data(0), iccm_corrected_data(1)) val iccm_dma_rdata_1_muxed = Mux(dma_mem_addr_ff(0).asBool, iccm_corrected_data(0), iccm_corrected_data(1))
val iccm_double_ecc_error = WireInit(UInt(2.W), 0.U) val iccm_double_ecc_error = WireInit(UInt(2.W), 0.U)
val iccm_dma_rdata_in = Mux(iccm_double_ecc_error.orR, Fill(2, io.dma_mem_ctl.dma_mem_addr), Cat(iccm_dma_rdata_1_muxed, iccm_corrected_data(0))) val iccm_dma_ecc_error_in = iccm_double_ecc_error.orR
val dma_mem_tag_ff = rvdffie(io.dma_mem_ctl.dma_mem_tag,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.free_clk){RegNext(io.dma_mem_ctl.dma_mem_tag, 0.U)} val iccm_dma_rdata_in = Mux(iccm_dma_ecc_error_in, Fill(2, io.dma_mem_ctl.dma_mem_addr), Cat(iccm_dma_rdata_1_muxed, iccm_corrected_data(0)))
val iccm_dma_rtag_temp = if(ICCM_ENABLE) rvdffie(dma_mem_tag_ff,io.free_l2clk,reset.asAsyncReset(),io.scan_mode) else 0.U val dma_mem_tag_ff = withClock(io.free_clk){RegNext(io.dma_mem_ctl.dma_mem_tag, 0.U)}
val iccm_dma_rtag_temp = if(ICCM_ENABLE) withClock(io.free_clk){RegNext(dma_mem_tag_ff, 0.U)} else 0.U
io.iccm_dma_rtag := iccm_dma_rtag_temp io.iccm_dma_rtag := iccm_dma_rtag_temp
dma_mem_addr_ff := rvdffie(io.dma_mem_ctl.dma_mem_addr(3,2),io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.free_clk) {RegNext(io.dma_mem_ctl.dma_mem_addr(3,2), 0.U)}
val iccm_dma_rvalid_in = rvdffie(iccm_dma_rden,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.free_clk) {RegNext(iccm_dma_rden, false.B)} dma_mem_addr_ff := withClock(io.free_clk) {RegNext(io.dma_mem_ctl.dma_mem_addr(3,2), 0.U)}
val iccm_dma_rvalid_temp = if(ICCM_ENABLE) rvdffie(iccm_dma_rvalid_in,io.free_l2clk,reset.asAsyncReset(),io.scan_mode) else 0.U val iccm_dma_rvalid_in = withClock(io.free_clk) {RegNext(iccm_dma_rden, false.B)}
val iccm_dma_rvalid_temp = if(ICCM_ENABLE) withClock(io.free_clk){RegNext(iccm_dma_rvalid_in, false.B)} else 0.U
io.iccm_dma_rvalid := iccm_dma_rvalid_temp io.iccm_dma_rvalid := iccm_dma_rvalid_temp
val iccm_dma_ecc_error = if(ICCM_ENABLE) rvdffie(iccm_double_ecc_error.orR,io.free_l2clk,reset.asAsyncReset(),io.scan_mode) else 0.U val iccm_dma_ecc_error = if(ICCM_ENABLE) withClock(io.free_clk){RegNext(iccm_dma_ecc_error_in, false.B)} else 0.U
io.iccm_dma_ecc_error := iccm_dma_ecc_error io.iccm_dma_ecc_error := iccm_dma_ecc_error
val iccm_dma_rdata_temp = if(ICCM_ENABLE) rvdffe(iccm_dma_rdata_in,iccm_dma_rvalid_in,clock,io.scan_mode) else 0.U val iccm_dma_rdata_temp = if(ICCM_ENABLE) withClock(io.free_clk){RegNext(iccm_dma_rdata_in, 0.U)} else 0.U
io.iccm_dma_rdata := iccm_dma_rdata_temp io.iccm_dma_rdata := iccm_dma_rdata_temp
val iccm_ecc_corr_index_ff = WireInit(UInt((ICCM_BITS-2).W), 0.U) val iccm_ecc_corr_index_ff = WireInit(UInt((ICCM_BITS-2).W), 0.U)
io.iccm.rw_addr := Mux(io.iccm_ready & io.dma_mem_ctl.dma_iccm_req & !iccm_correct_ecc, io.dma_mem_ctl.dma_mem_addr(ICCM_BITS-1,1), io.iccm.rw_addr := Mux(ifc_dma_access_q_ok & io.dma_mem_ctl.dma_iccm_req & !iccm_correct_ecc, io.dma_mem_ctl.dma_mem_addr(ICCM_BITS-1,1),
Mux(!(io.iccm_ready & io.dma_mem_ctl.dma_iccm_req) & iccm_correct_ecc, Cat(iccm_ecc_corr_index_ff, 0.U), io.ifc_fetch_addr_bf(ICCM_BITS-2,0))) Mux(!(ifc_dma_access_q_ok & io.dma_mem_ctl.dma_iccm_req) & iccm_correct_ecc, Cat(iccm_ecc_corr_index_ff, 0.U), io.ifc_fetch_addr_bf(ICCM_BITS-2,0)))
val ic_fetch_val_int_f = Cat(0.U(2.W), io.ic_fetch_val_f) val ic_fetch_val_int_f = Cat(0.U(2.W), io.ic_fetch_val_f)
val ic_fetch_val_shift_right = ic_fetch_val_int_f << ifu_fetch_addr_int_f(0) val ic_fetch_val_shift_right = ic_fetch_val_int_f << ifu_fetch_addr_int_f(0)
val iccm_rdmux_data = io.iccm.rd_data_ecc
// ICCM ECC Check logic // ICCM ECC Check logic
val iccm_ecc_word_enable = (0 until 2).map(i=>((ic_fetch_val_shift_right((2*i+1),(2*i)).orR & !io.exu_flush_final & fetch_req_iccm_f) | iccm_dma_rvalid_in) & !io.dec_mem_ctrl.dec_tlu_core_ecc_disable).reverse.reduce(Cat(_,_)) val iccm_ecc_word_enable = (0 until 2).map(i=>((ic_fetch_val_shift_right((2*i+1),(2*i)).orR & !io.exu_flush_final & sel_iccm_data) | iccm_dma_rvalid_in) & !io.dec_mem_ctrl.dec_tlu_core_ecc_disable).reverse.reduce(Cat(_,_))
val ecc_decoded = (0 until 2).map(i=>rvecc_decode(iccm_ecc_word_enable(i), io.iccm.rd_data_ecc((39*i+31),(39*i)), io.iccm.rd_data_ecc((39*i+38),(39*i+32)), 0.U)) val ecc_decoded = (0 until 2).map(i=>rvecc_decode(iccm_ecc_word_enable(i), iccm_rdmux_data((39*i+31),(39*i)), iccm_rdmux_data((39*i+38),(39*i+32)), 0.U))
val iccm_corrected_ecc = Wire(Vec(2, UInt(7.W))) val iccm_corrected_ecc = Wire(Vec(2, UInt(7.W)))
iccm_corrected_ecc := VecInit(ecc_decoded(0)._1,ecc_decoded(1)._1) iccm_corrected_ecc := VecInit(ecc_decoded(0)._1,ecc_decoded(1)._1)
iccm_corrected_data := VecInit(ecc_decoded(0)._2,ecc_decoded(1)._2) iccm_corrected_data := VecInit(ecc_decoded(0)._2,ecc_decoded(1)._2)
iccm_single_ecc_error := Cat(ecc_decoded(1)._3,ecc_decoded(0)._3) iccm_single_ecc_error := Cat(ecc_decoded(1)._3,ecc_decoded(0)._3)
iccm_double_ecc_error := Cat(ecc_decoded(1)._4,ecc_decoded(0)._4) iccm_double_ecc_error := Cat(ecc_decoded(1)._4,ecc_decoded(0)._4)
if(ICCM_ENABLE){
io.dec_mem_ctrl.ifu_iccm_rd_ecc_single_err := iccm_single_ecc_error.orR & ifc_iccm_access_f & ifc_fetch_req_f io.dec_mem_ctrl.ifu_iccm_rd_ecc_single_err := iccm_single_ecc_error.orR & ifc_iccm_access_f & ifc_fetch_req_f
io.iccm_rd_ecc_double_err := Mux(!ifu_fetch_addr_int_f(0), (Cat(iccm_double_ecc_error(0), iccm_double_ecc_error(0)) ) & Fill(2,ifc_iccm_access_f), io.iccm_rd_ecc_double_err := iccm_double_ecc_error.orR & ifc_iccm_access_f
(Cat(iccm_double_ecc_error(1), iccm_double_ecc_error(0)) ) & Fill(2,ifc_iccm_access_f))
}
else {
io.iccm_rd_ecc_double_err := 0.U
io.dec_mem_ctrl.ifu_iccm_rd_ecc_single_err := 0.U
}
val iccm_corrected_data_f_mux = Mux(iccm_single_ecc_error(0).asBool, iccm_corrected_data(0), iccm_corrected_data(1)) val iccm_corrected_data_f_mux = Mux(iccm_single_ecc_error(0).asBool, iccm_corrected_data(0), iccm_corrected_data(1))
val iccm_corrected_ecc_f_mux = Mux(iccm_single_ecc_error(0).asBool, iccm_corrected_ecc(0), iccm_corrected_ecc(1)) val iccm_corrected_ecc_f_mux = Mux(iccm_single_ecc_error(0).asBool, iccm_corrected_ecc(0), iccm_corrected_ecc(1))
val iccm_rd_ecc_single_err_hold_in = WireInit(Bool(),0.B) val iccm_rd_ecc_single_err_ff = WireInit(Bool(), false.B)
val iccm_rd_ecc_single_err_ff = if(ICCM_ENABLE) rvdffie(iccm_rd_ecc_single_err_hold_in,io.free_l2clk,reset.asAsyncReset(),io.scan_mode) else 0.U
val iccm_ecc_write_status = if(ICCM_ENABLE)((io.dec_mem_ctrl.ifu_iccm_rd_ecc_single_err & !iccm_rd_ecc_single_err_ff) & !io.exu_flush_final) | io.iccm_dma_sb_error else 0.U val iccm_ecc_write_status = if(ICCM_ENABLE)((io.dec_mem_ctrl.ifu_iccm_rd_ecc_single_err & !iccm_rd_ecc_single_err_ff) & !io.exu_flush_final) | io.iccm_dma_sb_error else 0.U
iccm_rd_ecc_single_err_hold_in := (io.dec_mem_ctrl.ifu_iccm_rd_ecc_single_err | iccm_rd_ecc_single_err_ff) & !io.exu_flush_final val iccm_rd_ecc_single_err_hold_in = (io.dec_mem_ctrl.ifu_iccm_rd_ecc_single_err | iccm_rd_ecc_single_err_ff) & !io.exu_flush_final
iccm_error_start := io.dec_mem_ctrl.ifu_iccm_rd_ecc_single_err
val iccm_rw_addr_f = WireInit(UInt((ICCM_BITS-2).W), 0.U) val iccm_rw_addr_f = WireInit(UInt((ICCM_BITS-2).W), 0.U)
val iccm_ecc_corr_index_in = Mux(iccm_single_ecc_error(0).asBool(), iccm_rw_addr_f, iccm_rw_addr_f + 1.U) val iccm_ecc_corr_index_in = Mux(iccm_single_ecc_error(0).asBool(), iccm_rw_addr_f, iccm_rw_addr_f + 1.U)
iccm_rw_addr_f := rvdffie(io.iccm.rw_addr(ICCM_BITS-2,1),io.free_l2clk,reset.asAsyncReset(),io.scan_mode) iccm_rw_addr_f := withClock(io.free_clk){RegNext(io.iccm.rw_addr(ICCM_BITS-2,1), 0.U)}
iccm_ecc_corr_data_ff := rvdffe(Cat(iccm_corrected_ecc_f_mux, iccm_corrected_data_f_mux),iccm_ecc_write_status,clock,io.scan_mode)//withClock(io.free_clk){RegEnable(Cat(iccm_corrected_ecc_f_mux, iccm_corrected_data_f_mux), 0.U, iccm_ecc_write_status.asBool())} iccm_rd_ecc_single_err_ff := withClock(io.free_clk){RegNext(iccm_rd_ecc_single_err_hold_in, false.B)}
if(ICCM_ENABLE) iccm_ecc_corr_index_ff := rvdffe(iccm_ecc_corr_index_in,iccm_ecc_write_status,clock,io.scan_mode) else iccm_ecc_corr_index_ff := 0.U//withClock(io.free_clk){RegEnable(iccm_ecc_corr_index_in, 0.U, iccm_ecc_write_status.asBool())} iccm_ecc_corr_data_ff := withClock(io.free_clk){RegEnable(Cat(iccm_corrected_ecc_f_mux, iccm_corrected_data_f_mux), 0.U, iccm_ecc_write_status.asBool())}
iccm_ecc_corr_index_ff := withClock(io.free_clk){RegEnable(iccm_ecc_corr_index_in, 0.U, iccm_ecc_write_status.asBool())}
io.ic.rd_en := (io.ifc_fetch_req_bf & !io.ifc_fetch_uncacheable_bf & !io.ifc_iccm_access_bf & io.ic.rd_en := (io.ifc_fetch_req_bf & !io.ifc_fetch_uncacheable_bf & !io.ifc_iccm_access_bf &
!(((miss_state===stream_C) & !miss_state_en) | !(((miss_state===stream_C) & !miss_state_en) |
((miss_state===crit_byp_ok_C) & !miss_state_en) | ((miss_state===crit_byp_ok_C) & !miss_state_en) |
@ -600,60 +634,66 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
val bus_ic_wr_en = WireInit(UInt(ICACHE_NUM_WAYS.W), 0.U) val bus_ic_wr_en = WireInit(UInt(ICACHE_NUM_WAYS.W), 0.U)
io.ic.wr_en := bus_ic_wr_en & Fill(ICACHE_NUM_WAYS, write_ic_16_bytes) io.ic.wr_en := bus_ic_wr_en & Fill(ICACHE_NUM_WAYS, write_ic_16_bytes)
io.ic_write_stall := write_ic_16_bytes & !((((miss_state===crit_byp_ok_C) | ((miss_state===stream_C) & !(io.exu_flush_final | ifu_bp_hit_taken_q_f | stream_eol_f ))) & !(bus_ifu_wr_en_ff & last_beat & !uncacheable_miss_ff))) io.ic_write_stall := write_ic_16_bytes & !((((miss_state===crit_byp_ok_C) | ((miss_state===stream_C) & !(io.exu_flush_final | ifu_bp_hit_taken_q_f | stream_eol_f ))) & !(bus_ifu_wr_en_ff & last_beat & !uncacheable_miss_ff)))
reset_all_tags := rvdffie(io.dec_mem_ctrl.dec_tlu_fence_i_wb,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.active_clk){RegNext(io.dec_mem_ctrl.dec_tlu_fence_i_wb, false.B)} reset_all_tags := withClock(io.active_clk){RegNext(io.dec_mem_ctrl.dec_tlu_fence_i_wb, false.B)}
// I$ status and P-LRU // I$ status and P-LRU
val ic_valid = !ifu_wr_cumulative_err_data & !(reset_ic_in | reset_ic_ff) & !reset_tag_valid_for_miss val ic_valid = !ifu_wr_cumulative_err_data & !(reset_ic_in | reset_ic_ff) & !reset_tag_valid_for_miss
val ifu_status_wr_addr_w_debug = Mux((io.ic.debug_rd_en | io.ic.debug_wr_en) & io.ic.debug_tag_array, io.ic.debug_addr(ICACHE_INDEX_HI - 3, ICACHE_TAG_INDEX_LO - 3), val ifu_status_wr_addr_w_debug = Mux((io.ic.debug_rd_en | io.ic.debug_wr_en) & io.ic.debug_tag_array, io.ic.debug_addr(ICACHE_INDEX_HI - 3, ICACHE_TAG_INDEX_LO - 3),
ifu_status_wr_addr(ICACHE_INDEX_HI - 1, ICACHE_TAG_INDEX_LO - 1)) ifu_status_wr_addr(ICACHE_INDEX_HI - 1, ICACHE_TAG_INDEX_LO - 1))
val ifu_status_wr_addr_ff = rvdffie(ifu_status_wr_addr_w_debug,io.free_l2clk,reset.asAsyncReset(),io.scan_mode) val ifu_status_wr_addr_ff = withClock(io.free_clk) {
RegNext(ifu_status_wr_addr_w_debug, 0.U)
val way_status_wr_en = WireInit(Bool(), 0.B) }
val way_status_wr_en = WireInit(Bool(), false.B)
val way_status_wr_en_w_debug = way_status_wr_en | (io.ic.debug_wr_en & io.ic.debug_tag_array) val way_status_wr_en_w_debug = way_status_wr_en | (io.ic.debug_wr_en & io.ic.debug_tag_array)
val way_status_wr_en_ff = rvdffie(way_status_wr_en_w_debug,io.free_l2clk,reset.asAsyncReset(),io.scan_mode) val way_status_wr_en_ff = withClock(io.free_clk) {
RegNext(way_status_wr_en_w_debug, false.B)
}
val way_status_new = WireInit(UInt(ICACHE_STATUS_BITS.W), 0.U) val way_status_new = WireInit(UInt(ICACHE_STATUS_BITS.W), 0.U)
val way_status_new_w_debug = Mux(io.ic.debug_wr_en & io.ic.debug_tag_array, val way_status_new_w_debug = Mux(io.ic.debug_wr_en & io.ic.debug_tag_array,
if (ICACHE_STATUS_BITS == 1) io.ic.debug_wr_data(4) else io.ic.debug_wr_data(6, 4), way_status_new) if (ICACHE_STATUS_BITS == 1) io.ic.debug_wr_data(4) else io.ic.debug_wr_data(6, 4), way_status_new)
val way_status_new_ff = rvdffie(way_status_new_w_debug,io.free_l2clk,reset.asAsyncReset(),io.scan_mode) val way_status_new_ff = withClock(io.free_clk) {
RegNext(way_status_new_w_debug, 0.U)
}
val way_status_clken = (0 until ICACHE_TAG_DEPTH / 8).map(i => ifu_status_wr_addr_ff(ICACHE_INDEX_HI - ICACHE_TAG_INDEX_LO, 3) === i.U) val way_status_clken = (0 until ICACHE_TAG_DEPTH / 8).map(i => ifu_status_wr_addr_ff(ICACHE_INDEX_HI - ICACHE_TAG_INDEX_LO, 3) === i.U)
val way_status_clk = if(RV_FPGA_OPTIMIZE) way_status_clken.map(rvclkhdr(clock, _, io.scan_mode)) else (0 until ICACHE_TAG_DEPTH/8).map(i=>0.B.asClock()) val way_status_clk = way_status_clken.map(rvclkhdr(clock, _, io.scan_mode))
val way_status_out = Wire(Vec(ICACHE_TAG_DEPTH, UInt(ICACHE_STATUS_BITS.W))) val way_status_out = Wire(Vec(ICACHE_TAG_DEPTH, UInt(ICACHE_STATUS_BITS.W)))
for (i <- 0 until ICACHE_TAG_DEPTH / 8; j <- 0 until 8) for (i <- 0 until ICACHE_TAG_DEPTH / 8; j <- 0 until 8)
way_status_out((8 * i) + j) := rvdffs_fpga(way_status_new_ff,(ifu_status_wr_addr_ff(2,0)===j.U) & way_status_wr_en_ff,way_status_clk(i),way_status_clken(i),clock)//withClock(way_status_clk(i)){RegEnable(way_status_new_ff, 0.U, (ifu_status_wr_addr_ff(2,0)===j.U) & way_status_wr_en_ff)} way_status_out((8 * i) + j) := withClock(way_status_clk(i)){RegEnable(way_status_new_ff, 0.U, (ifu_status_wr_addr_ff(2,0)===j.U) & way_status_wr_en_ff)}
val test_way_status_out = (0 until ICACHE_TAG_DEPTH).map(i=>way_status_out(i).asUInt).reverse.reduce(Cat(_,_)) val test_way_status_out = (0 until ICACHE_TAG_DEPTH).map(i=>way_status_out(i).asUInt).reverse.reduce(Cat(_,_))
// io.test_way_status_out := test_way_status_out // io.test_way_status_out := test_way_status_out
val test_way_status_clken = (0 until ICACHE_TAG_DEPTH/8).map(i=>way_status_clken(i).asUInt()).reverse.reduce(Cat(_,_)) val test_way_status_clken = (0 until ICACHE_TAG_DEPTH/8).map(i=>way_status_clken(i).asUInt()).reverse.reduce(Cat(_,_))
//io.test_way_status_clken := test_way_status_clken //io.test_way_status_clken := test_way_status_clken
way_status := Mux1H((0 until ICACHE_TAG_DEPTH).map(i=>(ifu_ic_rw_int_addr_ff === i.U) -> way_status_out(i))) way_status := Mux1H((0 until ICACHE_TAG_DEPTH).map(i=>(ifu_ic_rw_int_addr_ff === i.U) -> way_status_out(i)))
val ifu_ic_rw_int_addr_w_debug = Mux((io.ic.debug_rd_en | io.ic.debug_wr_en) & io.ic.debug_tag_array, val ifu_ic_rw_int_addr_w_debug = Mux((io.ic.debug_rd_en | io.ic.debug_wr_en) & io.ic.debug_tag_array,
io.ic.debug_addr(ICACHE_INDEX_HI - 3, ICACHE_TAG_INDEX_LO - 3), io.ic.rw_addr(ICACHE_INDEX_HI - 1, ICACHE_TAG_INDEX_LO - 1)) io.ic.debug_addr(ICACHE_INDEX_HI - 3, ICACHE_TAG_INDEX_LO - 3), ifu_ic_rw_int_addr(ICACHE_INDEX_HI - 1, ICACHE_TAG_INDEX_LO - 1))
ifu_ic_rw_int_addr_ff := rvdffie(ifu_ic_rw_int_addr_w_debug,io.free_l2clk,reset.asAsyncReset(),io.scan_mode) ifu_ic_rw_int_addr_ff := withClock(io.free_clk) {
// withClock(io.free_clk) { RegNext(ifu_ic_rw_int_addr_w_debug, 0.U)
// RegNext(ifu_ic_rw_int_addr_w_debug, 0.U) }
// }
val ifu_tag_wren = WireInit(UInt(ICACHE_NUM_WAYS.W), 0.U) val ifu_tag_wren = WireInit(UInt(ICACHE_NUM_WAYS.W), 0.U)
val ic_debug_tag_wr_en = WireInit(UInt(ICACHE_NUM_WAYS.W), 0.U) val ic_debug_tag_wr_en = WireInit(UInt(ICACHE_NUM_WAYS.W), 0.U)
val ifu_tag_wren_w_debug = ifu_tag_wren | ic_debug_tag_wr_en val ifu_tag_wren_w_debug = ifu_tag_wren | ic_debug_tag_wr_en
val ifu_tag_wren_ff = rvdffie(ifu_tag_wren_w_debug,io.free_l2clk,reset.asAsyncReset(),io.scan_mode) val ifu_tag_wren_ff = withClock(io.free_clk) {
RegNext(ifu_tag_wren_w_debug, 0.U)
}
val ic_valid_w_debug = Mux(io.ic.debug_wr_en & io.ic.debug_tag_array, io.ic.debug_wr_data(0), ic_valid) val ic_valid_w_debug = Mux(io.ic.debug_wr_en & io.ic.debug_tag_array, io.ic.debug_wr_data(0), ic_valid)
val ic_valid_ff =rvdffie(ic_valid_w_debug,io.free_l2clk,reset.asAsyncReset(),io.scan_mode) val ic_valid_ff = withClock(io.free_clk) {
RegNext(ic_valid_w_debug, false.B)
}
val tag_valid_clken = (0 until (ICACHE_TAG_DEPTH / 32)).map(i => (0 until ICACHE_NUM_WAYS).map(j => val tag_valid_clken = (0 until (ICACHE_TAG_DEPTH / 32)).map(i => (0 until ICACHE_NUM_WAYS).map(j =>
if (ICACHE_TAG_DEPTH == 32) ifu_tag_wren_ff(j) | perr_err_inv_way(j) | reset_all_tags if (ICACHE_TAG_DEPTH == 32) ifu_tag_wren_ff(j) | perr_err_inv_way(j) | reset_all_tags
else ((ifu_ic_rw_int_addr_ff(ICACHE_INDEX_HI - ICACHE_TAG_INDEX_LO, 5) === i.U) & ifu_tag_wren_ff(j)) | else ((ifu_ic_rw_int_addr_ff(ICACHE_INDEX_HI - ICACHE_TAG_INDEX_LO, 5) === i.U) & ifu_tag_wren_ff(j)) |
((perr_ic_index_ff(ICACHE_INDEX_HI - ICACHE_TAG_INDEX_LO, 5) === i.U) & perr_err_inv_way(j)) | ((perr_ic_index_ff(ICACHE_INDEX_HI - ICACHE_TAG_INDEX_LO, 5) === i.U) & perr_err_inv_way(j)) |
reset_all_tags).reverse.reduce(Cat(_, _))) reset_all_tags).reverse.reduce(Cat(_, _)))
val tag_valid_clk = if(RV_FPGA_OPTIMIZE) (0 until ICACHE_TAG_DEPTH / 32).map(i => (0 until ICACHE_NUM_WAYS).map(j => rvclkhdr(clock, tag_valid_clken(i)(j), io.scan_mode))) else (0 until ICACHE_TAG_DEPTH / 32).map(i => (0 until ICACHE_NUM_WAYS).map(j => 0.B.asClock())) val tag_valid_clk = (0 until ICACHE_TAG_DEPTH / 32).map(i => (0 until ICACHE_NUM_WAYS).map(j => rvclkhdr(clock, tag_valid_clken(i)(j), io.scan_mode)))
val ic_tag_valid_out = Wire(Vec(ICACHE_NUM_WAYS, Vec(ICACHE_TAG_DEPTH, Bool()))) val ic_tag_valid_out = Wire(Vec(ICACHE_NUM_WAYS, Vec(ICACHE_TAG_DEPTH, Bool())))
// io.valids := Cat((0 until ICACHE_TAG_DEPTH).map(i=>ic_tag_valid_out(1)(i).asUInt()).reverse.reduce(Cat(_,_)), // io.valids := Cat((0 until ICACHE_TAG_DEPTH).map(i=>ic_tag_valid_out(1)(i).asUInt()).reverse.reduce(Cat(_,_)),
// (0 until ICACHE_TAG_DEPTH).map(i=>ic_tag_valid_out(0)(i).asUInt()).reverse.reduce(Cat(_,_))) // (0 until ICACHE_TAG_DEPTH).map(i=>ic_tag_valid_out(0)(i).asUInt()).reverse.reduce(Cat(_,_)))
for (i <- 0 until (ICACHE_TAG_DEPTH / 32); j <- 0 until ICACHE_NUM_WAYS; k <- 0 until 32) for (i <- 0 until (ICACHE_TAG_DEPTH / 32); j <- 0 until ICACHE_NUM_WAYS; k <- 0 until 32)
ic_tag_valid_out(j)((32 * i) + k) := rvdffs_fpga(ic_valid_ff & !reset_all_tags.asBool & !perr_sel_invalidate,(((ifu_ic_rw_int_addr_ff === (k + (32 * i)).U) & ifu_tag_wren_ff(j)) | ((perr_ic_index_ff === (k + (32 * i)).U) & perr_err_inv_way(j)) | reset_all_tags),tag_valid_clk(i)(j),tag_valid_clken(i)(j),clock) ic_tag_valid_out(j)((32 * i) + k) := withClock(tag_valid_clk(i)(j)){RegEnable(ic_valid_ff & !reset_all_tags.asBool & !perr_sel_invalidate, false.B,
((((ifu_ic_rw_int_addr_ff === (k + (32 * i)).U) & ifu_tag_wren_ff(j)) | ((perr_ic_index_ff === (k + (32 * i)).U) & perr_err_inv_way(j)) | reset_all_tags)).asBool)}
val ic_tag_valid_unq = if(ICACHE_ENABLE)(0 until ICACHE_NUM_WAYS).map(k => (0 until ICACHE_TAG_DEPTH).map(j => val ic_tag_valid_unq = if(ICACHE_ENABLE)(0 until ICACHE_NUM_WAYS).map(k => (0 until ICACHE_TAG_DEPTH).map(j =>
Mux(ifu_ic_rw_int_addr_ff === j.U, ic_tag_valid_out(k)(j), 0.B).asUInt).reduce(_|_)).reverse.reduce(Cat(_,_)) Mux(ifu_ic_rw_int_addr_ff === j.U, ic_tag_valid_out(k)(j), false.B).asUInt).reduce(_|_)).reverse.reduce(Cat(_,_))
else 0.U(ICACHE_NUM_WAYS.W) else 0.U(ICACHE_NUM_WAYS.W)
// Making sudo LRU // Making sudo LRU
val way_status_hit_new = WireInit(UInt(ICACHE_STATUS_BITS.W), 0.U) val way_status_hit_new = WireInit(UInt(ICACHE_STATUS_BITS.W), 0.U)
@ -666,10 +706,10 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
(!tagv_mb_ff(1) & tagv_mb_ff(0)) (!tagv_mb_ff(1) & tagv_mb_ff(0))
replace_way_mb_any(0) := (!way_status_mb_ff(1) & !way_status_mb_ff(0) & tagv_mb_ff(3, 0).andR) | !tagv_mb_ff(0) replace_way_mb_any(0) := (!way_status_mb_ff(1) & !way_status_mb_ff(0) & tagv_mb_ff(3, 0).andR) | !tagv_mb_ff(0)
way_status_hit_new := Mux1H(Seq((!io.exu_flush_final & io.ic.rd_hit(0)) -> Cat(way_status(2), 3.U), way_status_hit_new := Mux1H(Seq(io.ic.rd_hit(0) -> Cat(way_status(2), 3.U),
(!io.exu_flush_final & io.ic.rd_hit(1)) -> Cat(way_status(2), 1.U(2.W)), io.ic.rd_hit(1) -> Cat(way_status(2), 1.U(2.W)),
(!io.exu_flush_final & io.ic.rd_hit(2)) -> Cat(1.U, way_status(1), 0.U), io.ic.rd_hit(2) -> Cat(1.U, way_status(1), 0.U),
(!io.exu_flush_final & io.ic.rd_hit(3)) -> Cat(0.U, way_status(1), 0.U))) io.ic.rd_hit(3) -> Cat(0.U, way_status(1), 0.U)))
way_status_rep_new := Mux1H(Seq(replace_way_mb_any(0).asBool -> Cat(way_status_mb_ff(2), 3.U), way_status_rep_new := Mux1H(Seq(replace_way_mb_any(0).asBool -> Cat(way_status_mb_ff(2), 3.U),
replace_way_mb_any(1).asBool -> Cat(way_status_mb_ff(2), 1.U(2.W)), replace_way_mb_any(1).asBool -> Cat(way_status_mb_ff(2), 1.U(2.W)),
@ -699,16 +739,16 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
way_status_new := 0.U way_status_new := 0.U
way_status_wr_en := 0.U way_status_wr_en := 0.U
} }
io.ic.tag_valid := ic_tag_valid_unq & Fill(ICACHE_NUM_WAYS, !fetch_uncacheable_ff & ifc_fetch_req_f_raw) io.ic.tag_valid := ic_tag_valid_unq & Fill(ICACHE_NUM_WAYS, !fetch_uncacheable_ff & ifc_fetch_req_f)
val ic_debug_way_ff = WireInit(UInt(ICACHE_NUM_WAYS.W), 0.U) val ic_debug_way_ff = WireInit(UInt(ICACHE_NUM_WAYS.W), 0.U)
ic_debug_tag_val_rd_out := (ic_tag_valid_unq & (ic_debug_way_ff & Fill(ICACHE_NUM_WAYS, ic_debug_rd_en_ff))).orR() ic_debug_tag_val_rd_out := (ic_tag_valid_unq & (ic_debug_way_ff & Fill(ICACHE_NUM_WAYS, ic_debug_rd_en_ff))).orR()
io.dec_mem_ctrl.ifu_pmu_ic_miss := rvdffie(ic_act_miss_f,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.active_clk){RegNext(ic_act_miss_f, false.B)} io.dec_mem_ctrl.ifu_pmu_ic_miss := withClock(io.active_clk){RegNext(ic_act_miss_f, false.B)}
io.dec_mem_ctrl.ifu_pmu_ic_hit := rvdffie(ic_act_hit_f,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.active_clk){RegNext(ic_act_hit_f, false.B)} io.dec_mem_ctrl.ifu_pmu_ic_hit := withClock(io.active_clk){RegNext(ic_act_hit_f, false.B)}
io.dec_mem_ctrl.ifu_pmu_bus_error := rvdffie(ifc_bus_acc_fault_f.orR,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.active_clk){RegNext(ifc_bus_acc_fault_f.orR, false.B)} io.dec_mem_ctrl.ifu_pmu_bus_error := withClock(io.active_clk){RegNext(ifc_bus_acc_fault_f, false.B)}
io.dec_mem_ctrl.ifu_pmu_bus_busy := rvdffie(ifu_bus_arvalid_ff & !ifu_bus_arready_ff & miss_pending,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.active_clk){RegNext(ifu_bus_arvalid_ff & !ifu_bus_arready_ff & miss_pending, false.B)} io.dec_mem_ctrl.ifu_pmu_bus_busy := withClock(io.active_clk){RegNext(ifu_bus_arvalid_ff & !ifu_bus_arready_ff & miss_pending, false.B)}
io.dec_mem_ctrl.ifu_pmu_bus_trxn := rvdffie(bus_cmd_sent,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.active_clk){RegNext(bus_cmd_sent, false.B)} io.dec_mem_ctrl.ifu_pmu_bus_trxn := withClock(io.active_clk){RegNext(bus_cmd_sent, false.B)}
io.ic.debug_addr := io.dec_mem_ctrl.dec_tlu_ic_diag_pkt.icache_dicawics io.ic.debug_addr := io.dec_mem_ctrl.dec_tlu_ic_diag_pkt.icache_dicawics
@ -719,10 +759,10 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
io.dec_mem_ctrl.dec_tlu_ic_diag_pkt.icache_dicawics(15,14)===1.U, io.dec_mem_ctrl.dec_tlu_ic_diag_pkt.icache_dicawics(15,14)===0.U) io.dec_mem_ctrl.dec_tlu_ic_diag_pkt.icache_dicawics(15,14)===1.U, io.dec_mem_ctrl.dec_tlu_ic_diag_pkt.icache_dicawics(15,14)===0.U)
ic_debug_tag_wr_en := Fill(ICACHE_NUM_WAYS, io.ic.debug_wr_en & io.ic.debug_tag_array) & io.ic.debug_way ic_debug_tag_wr_en := Fill(ICACHE_NUM_WAYS, io.ic.debug_wr_en & io.ic.debug_tag_array) & io.ic.debug_way
val ic_debug_ict_array_sel_in = io.ic.debug_rd_en & io.ic.debug_tag_array val ic_debug_ict_array_sel_in = io.ic.debug_rd_en & io.ic.debug_tag_array
ic_debug_way_ff := rvdff_fpga(io.ic.debug_way,debug_c1_clk,debug_c1_clken,clock)//withClock(debug_c1_clk){RegNext(io.ic.debug_way, 0.U)} ic_debug_way_ff := withClock(debug_c1_clk){RegNext(io.ic.debug_way, 0.U)}
ic_debug_ict_array_sel_ff := rvdff_fpga(ic_debug_ict_array_sel_in,debug_c1_clk,debug_c1_clken,clock)//withClock(debug_c1_clk){RegNext(ic_debug_ict_array_sel_in, 0.U)} ic_debug_ict_array_sel_ff := withClock(debug_c1_clk){RegNext(ic_debug_ict_array_sel_in, 0.U)}
ic_debug_rd_en_ff := rvdffie(io.ic.debug_rd_en,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.free_clk){RegNext(io.ic.debug_rd_en, false.B)} ic_debug_rd_en_ff := withClock(io.free_clk){RegNext(io.ic.debug_rd_en, false.B)}
io.dec_mem_ctrl.ifu_ic_debug_rd_data_valid := rvdffie(ic_debug_rd_en_ff,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.active_clk){RegNext(ic_debug_rd_en_ff, 0.U)} io.dec_mem_ctrl.ifu_ic_debug_rd_data_valid := withClock(io.free_clk){RegNext(ic_debug_rd_en_ff, 0.U)}
// Memory protection each access enable with its Mask // Memory protection each access enable with its Mask
val ifc_region_acc_okay = !(Cat(INST_ACCESS_ENABLE0.U,INST_ACCESS_ENABLE1.U,INST_ACCESS_ENABLE2.U,INST_ACCESS_ENABLE3.U,INST_ACCESS_ENABLE4.U,INST_ACCESS_ENABLE5.U,INST_ACCESS_ENABLE6.U,INST_ACCESS_ENABLE7.U).orR()) | val ifc_region_acc_okay = !(Cat(INST_ACCESS_ENABLE0.U,INST_ACCESS_ENABLE1.U,INST_ACCESS_ENABLE2.U,INST_ACCESS_ENABLE3.U,INST_ACCESS_ENABLE4.U,INST_ACCESS_ENABLE5.U,INST_ACCESS_ENABLE6.U,INST_ACCESS_ENABLE7.U).orR()) |
(INST_ACCESS_ENABLE0.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK0).U) === (aslong(INST_ACCESS_ADDR0).U | aslong(INST_ACCESS_MASK0).U))) | (INST_ACCESS_ENABLE0.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK0).U) === (aslong(INST_ACCESS_ADDR0).U | aslong(INST_ACCESS_MASK0).U))) |
@ -733,13 +773,9 @@ class ifu_mem_ctl extends Module with lib with RequireAsyncReset {
(INST_ACCESS_ENABLE5.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK5).U) === (aslong(INST_ACCESS_ADDR5).U | aslong(INST_ACCESS_MASK5).U))) | (INST_ACCESS_ENABLE5.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK5).U) === (aslong(INST_ACCESS_ADDR5).U | aslong(INST_ACCESS_MASK5).U))) |
(INST_ACCESS_ENABLE6.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK6).U) === (aslong(INST_ACCESS_ADDR6).U | aslong(INST_ACCESS_MASK6).U))) | (INST_ACCESS_ENABLE6.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK6).U) === (aslong(INST_ACCESS_ADDR6).U | aslong(INST_ACCESS_MASK6).U))) |
(INST_ACCESS_ENABLE7.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK7).U) === (aslong(INST_ACCESS_ADDR7).U | aslong(INST_ACCESS_MASK7).U))) (INST_ACCESS_ENABLE7.U & ((Cat(io.ifc_fetch_addr_bf, 0.U) | aslong(INST_ACCESS_MASK7).U) === (aslong(INST_ACCESS_ADDR7).U | aslong(INST_ACCESS_MASK7).U)))
dontTouch(ifc_region_acc_okay)
val ifc_region_acc_fault_memory_bf = !io.ifc_iccm_access_bf & !ifc_region_acc_okay & io.ifc_fetch_req_bf val ifc_region_acc_fault_memory_bf = !io.ifc_iccm_access_bf & !ifc_region_acc_okay & io.ifc_fetch_req_bf
ifc_region_acc_fault_final_bf := io.ifc_region_acc_fault_bf | ifc_region_acc_fault_memory_bf ifc_region_acc_fault_final_bf := io.ifc_region_acc_fault_bf | ifc_region_acc_fault_memory_bf
ifc_region_acc_fault_memory_f := rvdffie(ifc_region_acc_fault_memory_bf,io.free_l2clk,reset.asAsyncReset(),io.scan_mode)//withClock(io.active_clk){RegNext(ifc_region_acc_fault_memory_bf, false.B)} ifc_region_acc_fault_memory_f := withClock(io.free_clk){RegNext(ifc_region_acc_fault_memory_bf, false.B)}
} }
//object ifumem_ctl extends App {
// println((new chisel3.stage.ChiselStage).emitVerilog(new ifu_mem_ctl()))
//}

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