Compare commits
3 Commits
master
...
quasar-1.0
Author | SHA1 | Date |
---|---|---|
Laraib Khan | 4b949f86f7 | |
komaljaved-lm | b40e643c68 | |
komaljaved-lm | 31c8526ffe |
79
README.md
79
README.md
|
@ -1,6 +1,6 @@
|
|||
# Quasar RISC-V Core 2.0 from Lampro Mellon
|
||||
# Quasar RISC-V Core 1.0 from Lampro Mellon
|
||||
|
||||
This repository contains the Quasar Core design in CHISEL.
|
||||
This repository contains the SweRV-EL2 Core written in CHISEL named "Quasar".
|
||||
|
||||
## License
|
||||
|
||||
|
@ -40,22 +40,18 @@ Quasar is a Chiselified version of EL2 SweRV RISC-V Core.
|
|||
├── generated_rtl # Quasar wrapper
|
||||
├── testbench
|
||||
│ ├── asm # Example assembly files
|
||||
│ ├── hex # Canned demo hex files
|
||||
│ └── tests # Example tests
|
||||
│ └── hex # Canned demo hex files
|
||||
├── tools # Scripts/Makefiles
|
||||
├── tracer_logs # generated log files
|
||||
└── verif
|
||||
├── LEC
|
||||
├── formality_work
|
||||
└── formality_log # LEC log files
|
||||
└── setup_files # user_match files
|
||||
├── LEC
|
||||
└── sim # Simulation log/dump files
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Verilator **(4.102 or later)** must be installed on the system if running with verilator.
|
||||
- Verilator **(4.030 or later)** must be installed on the system if running with verilator.
|
||||
- Vcs must be installed on the system if running with vcs.
|
||||
- RISCV tool chain (based on gcc version 8.3 or higher) must be
|
||||
- RISCV tool chain (based on gcc version 7.3 or higher) must be
|
||||
installed so that it can be used to prepare RISCV binaries to run.
|
||||
- Sbt **(1.3.13 or later)** must be installed on the system.
|
||||
|
||||
|
@ -67,7 +63,7 @@ installed so that it can be used to prepare RISCV binaries to run.
|
|||
4. Run make with $RV_ROOT/tools/Makefile
|
||||
|
||||
## Release Notes for this version
|
||||
Please see [release-notes](release-notes.md) for changes and bug fixes in this version of Quasar.
|
||||
Please see [release notes](release-notes.md) for changes and bug fixes in this version of Quasar.
|
||||
|
||||
### Configurations
|
||||
|
||||
|
@ -99,8 +95,7 @@ $RV_ROOT/design/snapshots/default
|
|||
├── pd_defines.vh # `defines for physical design
|
||||
├── perl_configs.pl # Perl %configs hash for scripting
|
||||
├── pic_map_auto.h # PIC memory map based on configure size
|
||||
├── whisper.json # JSON file for swerv-iss
|
||||
└── link.ld # default linker control file
|
||||
└── whisper.json # JSON file for swerv-iss
|
||||
```
|
||||
#### 1. Generate scala parameter
|
||||
```
|
||||
|
@ -141,9 +136,9 @@ Snapshots are placed in `$BUILD_PATH` directory.
|
|||
|
||||
#### 3. Run sbt
|
||||
```
|
||||
make -f $RV_ROOT/tools/Makefile sbt_
|
||||
make -f $RV_ROOT/tools/Makefile sbt
|
||||
```
|
||||
This command will generate the Quasar wrapper in system verilog of Quasar chisel, in the `generated_rtl` directory and runs the `reset_script.py`
|
||||
This command will generate the Quasar wrapper in system verilog in the `generated_rtl` directory and runs the `reset_script.py`
|
||||
* In the reset_script we do a post verilog-generation changes, these changes are as follows:
|
||||
|
||||
* Replace `posedge reset` with `negedge reset`
|
||||
|
@ -162,7 +157,7 @@ The simulation produces output on the screen like:
|
|||
VerilatorTB: Start of sim
|
||||
|
||||
----------------------------------
|
||||
Hello World from QUASAR @LMDC !!
|
||||
Hello World from Quasar @LM !!
|
||||
----------------------------------
|
||||
TEST_PASSED
|
||||
|
||||
|
@ -185,7 +180,21 @@ You can re-execute simulation using:
|
|||
```
|
||||
make -f $RV_ROOT/tools/Makefile verilator
|
||||
```
|
||||
#### 5. Default for VCS/Verilotor
|
||||
The simulation run/build command has following generic form:
|
||||
```
|
||||
make -f $RV_ROOT/tools/Makefile [<simulator>] [debug=1] [snapshot=mybuild] [target=<target>] [TEST=<test>] [TEST_DIR=<path_to_test_dir>]
|
||||
```
|
||||
where:
|
||||
```
|
||||
<simulator> - can be 'verilator' (by default) , 'vcs' - Synopsys VCS. if not provided, 'make' cleans work directory, builds verilator executable and runs a test.
|
||||
debug=1 - allows VCD generation for verilator and VCS and SHM waves for irun option.
|
||||
<target> - predefined CPU configurations 'default' ( by default), 'default_ahb', 'typical_pd', 'high_perf'.
|
||||
TEST - allows to run a C (<test>.c) or assembly (<test>.s) test, hello_world is run by default.
|
||||
TEST_DIR - alternative to test source directory testbench/asm or testbench/tests.
|
||||
<snapshot> - run and build executable model of custom CPU configuration, remember to provide 'snapshot' argument for runs on custom configurations.
|
||||
CONF_PARAMS - allows to provide -set options to quasar.conf script to alter predefined targets parameters.
|
||||
```
|
||||
#### Default for VCS/Verilotor
|
||||
If you want to run default configuration on verilator use the following command
|
||||
```
|
||||
make -f $RV_ROOT/tools/Makefile
|
||||
|
@ -194,21 +203,6 @@ For VCS use
|
|||
```
|
||||
make -f $RV_ROOT/tools/Makefile vcs_all
|
||||
```
|
||||
|
||||
The simulation run/build command has following generic form:
|
||||
```
|
||||
make -f $RV_ROOT/tools/Makefile [<simulator>] [debug=1] [snapshot=mybuild] [target=<target>] [TEST=<test>] [TEST_DIR=<path_to_test_dir>]
|
||||
```
|
||||
where:
|
||||
```
|
||||
<simulator> - can be 'verilator' (by default) , 'vcs' - Synopsys VCS, 'riviera'- Aldec Riviera-PRO. If not provided, 'make' cleans work directory, builds verilator executable and runs a test.
|
||||
debug=1 - allows VCD generation for verilator and VCS and SHM waves for irun option.
|
||||
<target> - predefined CPU configurations 'default' ( by default), 'default_ahb', 'typical_pd', 'high_perf'.
|
||||
TEST - allows to run a C (<test>.c) or assembly (<test>.s) test, hello_world is run by default.
|
||||
TEST_DIR - alternative to test source directory testbench/asm or testbench/tests.
|
||||
<snapshot> - run and build executable model of custom CPU configuration, remember to provide 'snapshot' argument for runs on custom configurations.
|
||||
CONF_PARAMS - allows to provide -set options to quasar.conf script to alter predefined targets parameters.
|
||||
```
|
||||
Example:
|
||||
```
|
||||
make -f $RV_ROOT/tools/Makefile verilator TEST=cmark
|
||||
|
@ -220,6 +214,7 @@ If you want to compile a test only, you can run:
|
|||
```
|
||||
make -f $RV_ROOT/tools/Makefile program.hex TEST=<test> [TEST_DIR=/path/to/dir]
|
||||
```
|
||||
|
||||
The Makefile uses `snapshot/<target>/link.ld` file, generated by quasar.conf script by default to build test executable. User can provide test specific linker file in form `<test_name>.ld` to build the test executable, in the same directory with the test source.
|
||||
|
||||
User also can create a test specific makefile in form `<test_name>.makefile`, containing building instructions how to create `program.hex` file used by simulation. The private makefile should be in the same directory as the test source. See examples in `testbench/asm` directory.
|
||||
|
@ -234,27 +229,15 @@ Note: You may need to delete `program.hex` file from work directory, when run a
|
|||
|
||||
The `$RV_ROOT/testbench/asm` directory contains following tests ready to simulate:
|
||||
```
|
||||
hello_world - default test program to run, prints Hello World message to screen and console.log
|
||||
hello_world - default tes to run, prints Hello World message to screen and console.log
|
||||
hello_world_dccm - the same as above, but takes the string from preloaded DCCM.
|
||||
hello_world_iccm - the same as hello_world, but loads the test code to ICCM via LSU to DMA bridge and then executes it from there. Runs on QUASAR with AXI4 buses only.
|
||||
hello_world_iccm - the same as hello_world, but loads the test code to ICCM via LSU to DMA bridge and then executes
|
||||
it from there. Runs on QUASAR with AXI4 buses only.
|
||||
cmark - coremark benchmark running with code and data in external memories
|
||||
cmark_dccm - the same as above, running data and stack from DCCM (faster)
|
||||
cmark_iccm - the same as above with preloaded code to ICCM.
|
||||
|
||||
dhry - Run dhrystone. (Scale by 1757 to get DMIPS/MHZ)
|
||||
cmark_iccm - the same as above with preloaded code to ICCM.
|
||||
```
|
||||
|
||||
The `$RV_ROOT/testbench/hex` directory contains precompiled hex files of the tests, ready for simulation in case RISCV SW tools are not installed.
|
||||
|
||||
#### 6. Logical Equivalence Checking of Quasar
|
||||
If you want to perform LEC on quasar, use the following command
|
||||
```
|
||||
make -f $RV_ROOT/tools/Makefile lec
|
||||
```
|
||||
This command will call the LEC Makefile to clone Quasar along with the SweRV-EL2 and run `sbt` for chisel-generated RTL. Then, this will take file for user-match the ports, blockbox pins, latches, flops and perform the LEC of Quasar.
|
||||
Following log files are created in `$RV_ROOT/verif/LEC/formality_work/formality_log` :
|
||||
`fm_shell_command.log` gives the detail of instructions
|
||||
`formality.log` gives the detail of undriven nets
|
||||
|
||||
**Note**: The testbench has a simple synthesizable bridge that allows you to load the ICCM via load/store instructions. This is only supported for AXI4 builds.
|
||||
|
||||
|
|
|
@ -41,4 +41,3 @@ high_perf | Large BTB/BHT, AXI4 interface
|
|||
`quasar.config` may be edited to add additional target configurations, or new configurations may be created via the command line `-set` or `-unset` options.
|
||||
|
||||
**Run `$RV_ROOT/configs/quasar.config -h` for options and settable parameters.**
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -30,9 +30,6 @@ version := "3.3.0"
|
|||
|
||||
scalaVersion := "2.12.10"
|
||||
|
||||
// Making the main-class
|
||||
mainClass in (Compile, run) := Some("wrapper")
|
||||
|
||||
crossScalaVersions := Seq("2.12.10", "2.11.12")
|
||||
|
||||
resolvers ++= Seq(
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
sbt.internal.DslEntry
|
Binary file not shown.
|
@ -1,3 +1,3 @@
|
|||
[0m[[0m[0mdebug[0m] [0m[0m"not up to date. inChanged = true, force = false[0m
|
||||
[0m[[0m[0mdebug[0m] [0m[0mUpdating ProjectRef(uri("file:/home/users/scratch/komal.javed.data/Quasar/quasar2/design/project/"), "design-build")...[0m
|
||||
[0m[[0m[0mdebug[0m] [0m[0mDone updating ProjectRef(uri("file:/home/users/scratch/komal.javed.data/Quasar/quasar2/design/project/"), "design-build")[0m
|
||||
[0m[[0m[0mdebug[0m] [0m[0mUpdating ProjectRef(uri("file:/home/users/scratch/komal.javed.data/Quasar/quasar1_final/design/project/"), "design-build")...[0m
|
||||
[0m[[0m[0mdebug[0m] [0m[0mDone updating ProjectRef(uri("file:/home/users/scratch/komal.javed.data/Quasar/quasar1_final/design/project/"), "design-build")[0m
|
||||
|
|
|
@ -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"]]
|
|
@ -1 +1 @@
|
|||
[debug] Full compilation, no sources in previous analysis.
|
||||
[0m[[0m[0mdebug[0m] [0m[0mFull compilation, no sources in previous analysis.[0m
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[debug] Copy resource mappings:
|
||||
[debug]
|
||||
[0m[[0m[0mdebug[0m] [0m[0mCopy resource mappings: [0m
|
||||
[0m[[0m[0mdebug[0m] [0m[0m [0m
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -6,16 +6,15 @@ infile = root+"/design/quasar_wrapper.v"
|
|||
outfile = root+"/design/quasar_wrapper.sv"
|
||||
|
||||
delete_list1 = ["if (dbg_dm_rst_l)"]
|
||||
delete_list2 = ["if (_T_597)"]
|
||||
delete_list2 = ["if (rst_temp)"]
|
||||
delete_list3 = ["if (io_dbg_rst_l)"]
|
||||
delete_list4 = ["if (reset)"]
|
||||
delete_list5 = ["posedge reset"]
|
||||
delete_list6 = ["posedge dbg_dm_rst_l"]
|
||||
delete_list7 = ["posedge _T_597"]
|
||||
delete_list7 = ["posedge rst_temp"]
|
||||
delete_list8 = ["posedge io_dbg_rst_l"]
|
||||
delete_list9 = ["if (rst_not)"]
|
||||
delete_list10 = ["posedge rst_not"]
|
||||
delete_list11 = ["rvclkhdr"]
|
||||
|
||||
fin = open(infile)
|
||||
fout = open(outfile, "w+")
|
||||
|
@ -24,7 +23,7 @@ for line in fin:
|
|||
line = line.replace(word, "if (~dbg_dm_rst_l)")
|
||||
|
||||
for word in delete_list2:
|
||||
line = line.replace(word, "if (~_T_597)")
|
||||
line = line.replace(word, "if (~rst_temp)")
|
||||
|
||||
for word in delete_list3:
|
||||
line = line.replace(word, "if (~io_dbg_rst_l)")
|
||||
|
@ -39,7 +38,7 @@ for line in fin:
|
|||
line = line.replace(word, "negedge dbg_dm_rst_l")
|
||||
|
||||
for word in delete_list7:
|
||||
line = line.replace(word, "negedge _T_597")
|
||||
line = line.replace(word, "negedge rst_temp")
|
||||
|
||||
for word in delete_list8:
|
||||
line = line.replace(word, "negedge io_dbg_rst_l")
|
||||
|
@ -49,10 +48,6 @@ for line in fin:
|
|||
|
||||
for word in delete_list10:
|
||||
line = line.replace(word, "negedge rst_not")
|
||||
|
||||
for word in delete_list11:
|
||||
line = line.replace(word, "rvclkhdr_ch")
|
||||
|
||||
fout.write(line)
|
||||
fin.close()
|
||||
fout.close()
|
||||
|
|
|
@ -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
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 Western Digital Corporation or its affiliates.
|
||||
// Copyright 2020 Western Digital Corporation or it's affiliates.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -14,8 +14,6 @@
|
|||
// limitations under the License.
|
||||
|
||||
// all flops call the rvdff flop
|
||||
`define RV_FPGA_OPTIMIZE 1
|
||||
`define RV_PHYSICAL 1
|
||||
|
||||
|
||||
module rvdff #( parameter WIDTH=1, SHORT=0 )
|
||||
|
@ -31,7 +29,7 @@ if (SHORT == 1) begin
|
|||
assign dout = din;
|
||||
end
|
||||
else begin
|
||||
`ifdef RV_CLOCKGATE
|
||||
`ifdef CLOCKGATE
|
||||
always @(posedge tb_top.clk) begin
|
||||
#0 $strobe("CG: %0t %m din %x dout %x clk %b width %d",$time,din,dout,clk,WIDTH);
|
||||
end
|
||||
|
@ -87,85 +85,7 @@ else begin
|
|||
end
|
||||
endmodule
|
||||
|
||||
// _fpga versions
|
||||
module rvdff_fpga #( parameter WIDTH=1, SHORT=0 )
|
||||
(
|
||||
input logic [WIDTH-1:0] din,
|
||||
input logic clk,
|
||||
input logic clken,
|
||||
input logic rawclk,
|
||||
input logic rst_l,
|
||||
|
||||
output logic [WIDTH-1:0] dout
|
||||
);
|
||||
|
||||
if (SHORT == 1) begin
|
||||
assign dout = din;
|
||||
end
|
||||
else begin
|
||||
`ifdef RV_FPGA_OPTIMIZE
|
||||
rvdffs #(WIDTH) dffs (.clk(rawclk), .en(clken), .*);
|
||||
`else
|
||||
rvdff #(WIDTH) dff (.*);
|
||||
`endif
|
||||
end
|
||||
endmodule
|
||||
|
||||
// rvdff with 2:1 input mux to flop din iff sel==1
|
||||
module rvdffs_fpga #( parameter WIDTH=1, SHORT=0 )
|
||||
(
|
||||
input logic [WIDTH-1:0] din,
|
||||
input logic en,
|
||||
input logic clk,
|
||||
input logic clken,
|
||||
input logic rawclk,
|
||||
input logic rst_l,
|
||||
|
||||
output logic [WIDTH-1:0] dout
|
||||
);
|
||||
|
||||
if (SHORT == 1) begin : genblock
|
||||
assign dout = din;
|
||||
end
|
||||
else begin : genblock
|
||||
`ifdef RV_FPGA_OPTIMIZE
|
||||
rvdffs #(WIDTH) dffs (.clk(rawclk), .en(clken & en), .*);
|
||||
`else
|
||||
rvdffs #(WIDTH) dffs (.*);
|
||||
`endif
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
// rvdff with en and clear
|
||||
module rvdffsc_fpga #( parameter WIDTH=1, SHORT=0 )
|
||||
(
|
||||
input logic [WIDTH-1:0] din,
|
||||
input logic en,
|
||||
input logic clear,
|
||||
input logic clk,
|
||||
input logic clken,
|
||||
input logic rawclk,
|
||||
input logic rst_l,
|
||||
|
||||
output logic [WIDTH-1:0] dout
|
||||
);
|
||||
|
||||
logic [WIDTH-1:0] din_new;
|
||||
if (SHORT == 1) begin
|
||||
assign dout = din;
|
||||
end
|
||||
else begin
|
||||
`ifdef RV_FPGA_OPTIMIZE
|
||||
rvdffs #(WIDTH) dffs (.clk(rawclk), .din(din[WIDTH-1:0] & {WIDTH{~clear}}),.en((en | clear) & clken), .*);
|
||||
`else
|
||||
rvdffsc #(WIDTH) dffsc (.*);
|
||||
`endif
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
||||
module rvdffe #( parameter WIDTH=1, SHORT=0, OVERRIDE=0 )
|
||||
module rvdffe #( parameter WIDTH=1, SHORT=0 )
|
||||
(
|
||||
input logic [WIDTH-1:0] din,
|
||||
input logic en,
|
||||
|
@ -184,8 +104,8 @@ if (SHORT == 1) begin : genblock
|
|||
end
|
||||
else begin : genblock
|
||||
|
||||
`ifndef RV_PHYSICAL
|
||||
if (WIDTH >= 8 || OVERRIDE==1) begin: genblock
|
||||
`ifndef PHYSICAL
|
||||
if (WIDTH >= 8) begin: genblock
|
||||
`endif
|
||||
|
||||
`ifdef RV_FPGA_OPTIMIZE
|
||||
|
@ -195,226 +115,15 @@ else begin : genblock
|
|||
rvdff #(WIDTH) dff (.*, .clk(l1clk));
|
||||
`endif
|
||||
|
||||
`ifndef RV_PHYSICAL
|
||||
`ifndef PHYSICAL
|
||||
end
|
||||
else
|
||||
$error("%m: rvdffe must be WIDTH >= 8");
|
||||
$error(" rvdffe width must be >= 8");
|
||||
`endif
|
||||
end // else: !if(SHORT == 1)
|
||||
|
||||
endmodule // rvdffe
|
||||
|
||||
|
||||
module rvdffpcie #( parameter WIDTH=31 )
|
||||
(
|
||||
input logic [WIDTH-1:0] din,
|
||||
input logic clk,
|
||||
input logic rst_l,
|
||||
input logic en,
|
||||
input logic scan_mode,
|
||||
output logic [WIDTH-1:0] dout
|
||||
);
|
||||
|
||||
|
||||
|
||||
`ifndef RV_PHYSICAL
|
||||
if (WIDTH == 31) begin: genblock
|
||||
`endif
|
||||
|
||||
`ifdef RV_FPGA_OPTIMIZE
|
||||
rvdffs #(WIDTH) dff ( .* );
|
||||
`else
|
||||
|
||||
rvdfflie #(.WIDTH(WIDTH), .LEFT(19)) dff (.*);
|
||||
|
||||
`endif
|
||||
|
||||
`ifndef RV_PHYSICAL
|
||||
end
|
||||
else
|
||||
$error("%m: rvdffpcie width must be 31");
|
||||
`endif
|
||||
endmodule
|
||||
|
||||
// format: { LEFT, EXTRA }
|
||||
// LEFT # of bits will be done with rvdffie, all else EXTRA with rvdffe
|
||||
module rvdfflie #( parameter WIDTH=16, LEFT=8 )
|
||||
(
|
||||
input logic [WIDTH-1:0] din,
|
||||
input logic clk,
|
||||
input logic rst_l,
|
||||
input logic en,
|
||||
input logic scan_mode,
|
||||
output logic [WIDTH-1:0] dout
|
||||
);
|
||||
|
||||
localparam EXTRA = WIDTH-LEFT;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
localparam LMSB = WIDTH-1;
|
||||
localparam LLSB = LMSB-LEFT+1;
|
||||
localparam XMSB = LLSB-1;
|
||||
localparam XLSB = LLSB-EXTRA;
|
||||
|
||||
|
||||
`ifndef RV_PHYSICAL
|
||||
if (WIDTH >= 16 && LEFT >= 8 && EXTRA >= 8) begin: genblock
|
||||
`endif
|
||||
|
||||
`ifdef RV_FPGA_OPTIMIZE
|
||||
rvdffs #(WIDTH) dff ( .* );
|
||||
`else
|
||||
|
||||
rvdffiee #(LEFT) dff_left (.*, .din(din[LMSB:LLSB]), .dout(dout[LMSB:LLSB]));
|
||||
|
||||
|
||||
rvdffe #(EXTRA) dff_extra (.*, .din(din[XMSB:XLSB]), .dout(dout[XMSB:XLSB]));
|
||||
|
||||
|
||||
|
||||
|
||||
`endif
|
||||
|
||||
`ifndef RV_PHYSICAL
|
||||
end
|
||||
else
|
||||
$error("%m: rvdfflie musb be WIDTH >= 16 && LEFT >= 8 && EXTRA >= 8");
|
||||
`endif
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
|
||||
// special power flop for predict packet
|
||||
// format: { LEFT, RIGHT==31 }
|
||||
// LEFT # of bits will be done with rvdffe; RIGHT is enabled by LEFT[LSB] & en
|
||||
module rvdffppe #( parameter WIDTH=32 )
|
||||
(
|
||||
input logic [WIDTH-1:0] din,
|
||||
input logic clk,
|
||||
input logic rst_l,
|
||||
input logic en,
|
||||
input logic scan_mode,
|
||||
output logic [WIDTH-1:0] dout
|
||||
);
|
||||
|
||||
localparam RIGHT = 31;
|
||||
localparam LEFT = WIDTH - RIGHT;
|
||||
|
||||
localparam LMSB = WIDTH-1;
|
||||
localparam LLSB = LMSB-LEFT+1;
|
||||
localparam RMSB = LLSB-1;
|
||||
localparam RLSB = LLSB-RIGHT;
|
||||
|
||||
|
||||
`ifndef RV_PHYSICAL
|
||||
if (WIDTH>=32 && LEFT>=8 && RIGHT>=8) begin: genblock
|
||||
`endif
|
||||
|
||||
`ifdef RV_FPGA_OPTIMIZE
|
||||
rvdffs #(WIDTH) dff ( .* );
|
||||
`else
|
||||
rvdffe #(LEFT) dff_left (.*, .din(din[LMSB:LLSB]), .dout(dout[LMSB:LLSB]));
|
||||
|
||||
rvdffe #(RIGHT) dff_right (.*, .din(din[RMSB:RLSB]), .dout(dout[RMSB:RLSB]), .en(en & din[LLSB])); // qualify with pret
|
||||
|
||||
|
||||
`endif
|
||||
|
||||
`ifndef RV_PHYSICAL
|
||||
end
|
||||
else
|
||||
$error("%m: must be WIDTH>=32 && LEFT>=8 && RIGHT>=8");
|
||||
`endif
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
|
||||
module rvdffie #( parameter WIDTH=1, OVERRIDE=0 )
|
||||
(
|
||||
input logic [WIDTH-1:0] din,
|
||||
|
||||
input logic clk,
|
||||
input logic rst_l,
|
||||
input logic scan_mode,
|
||||
output logic [WIDTH-1:0] dout
|
||||
);
|
||||
|
||||
logic l1clk;
|
||||
logic en;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
`ifndef RV_PHYSICAL
|
||||
if (WIDTH >= 8 || OVERRIDE==1) begin: genblock
|
||||
`endif
|
||||
|
||||
assign en = |(din ^ dout);
|
||||
|
||||
`ifdef RV_FPGA_OPTIMIZE
|
||||
rvdffs #(WIDTH) dff ( .* );
|
||||
`else
|
||||
rvclkhdr clkhdr ( .* );
|
||||
rvdff #(WIDTH) dff (.*, .clk(l1clk));
|
||||
`endif
|
||||
|
||||
`ifndef RV_PHYSICAL
|
||||
end
|
||||
else
|
||||
$error("%m: rvdffie must be WIDTH >= 8");
|
||||
`endif
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ie flop but it has an .en input
|
||||
module rvdffiee #( parameter WIDTH=1, OVERRIDE=0 )
|
||||
(
|
||||
input logic [WIDTH-1:0] din,
|
||||
|
||||
input logic clk,
|
||||
input logic rst_l,
|
||||
input logic scan_mode,
|
||||
input logic en,
|
||||
output logic [WIDTH-1:0] dout
|
||||
);
|
||||
|
||||
logic l1clk;
|
||||
logic final_en;
|
||||
|
||||
`ifndef RV_PHYSICAL
|
||||
if (WIDTH >= 8 || OVERRIDE==1) begin: genblock
|
||||
`endif
|
||||
|
||||
assign final_en = (|(din ^ dout)) & en;
|
||||
|
||||
`ifdef RV_FPGA_OPTIMIZE
|
||||
rvdffs #(WIDTH) dff ( .*, .en(final_en) );
|
||||
`else
|
||||
rvdffe #(WIDTH) dff (.*, .en(final_en));
|
||||
`endif
|
||||
|
||||
`ifndef RV_PHYSICAL
|
||||
end
|
||||
else
|
||||
$error("%m: rvdffie width must be >= 8");
|
||||
`endif
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
module rvsyncss #(parameter WIDTH = 251)
|
||||
(
|
||||
input logic clk,
|
||||
|
@ -430,23 +139,6 @@ module rvsyncss #(parameter WIDTH = 251)
|
|||
|
||||
endmodule // rvsyncss
|
||||
|
||||
module rvsyncss_fpga #(parameter WIDTH = 251)
|
||||
(
|
||||
input logic gw_clk,
|
||||
input logic rawclk,
|
||||
input logic clken,
|
||||
input logic rst_l,
|
||||
input logic [WIDTH-1:0] din,
|
||||
output logic [WIDTH-1:0] dout
|
||||
);
|
||||
|
||||
logic [WIDTH-1:0] din_ff1;
|
||||
|
||||
rvdff_fpga #(WIDTH) sync_ff1 (.*, .clk(gw_clk), .rawclk(rawclk), .clken(clken), .din (din[WIDTH-1:0]), .dout(din_ff1[WIDTH-1:0]));
|
||||
rvdff_fpga #(WIDTH) sync_ff2 (.*, .clk(gw_clk), .rawclk(rawclk), .clken(clken), .din (din_ff1[WIDTH-1:0]), .dout(dout[WIDTH-1:0]));
|
||||
|
||||
endmodule // rvsyncss
|
||||
|
||||
module rvlsadder
|
||||
(
|
||||
input logic [31:0] rs1,
|
||||
|
@ -751,7 +443,7 @@ module rvecc_decode_64 (
|
|||
endmodule // rvecc_decode_64
|
||||
|
||||
|
||||
module TEC_RV_ICG
|
||||
module gated_flop
|
||||
(
|
||||
input logic SE, EN, CK,
|
||||
output Q
|
||||
|
@ -776,24 +468,5 @@ module TEC_RV_ICG
|
|||
|
||||
endmodule
|
||||
|
||||
module rvoclkhdr
|
||||
(
|
||||
input logic en,
|
||||
input logic clk,
|
||||
input logic scan_mode,
|
||||
output logic l1clk
|
||||
);
|
||||
|
||||
logic SE;
|
||||
assign SE = 0;
|
||||
|
||||
`ifdef RV_FPGA_OPTIMIZE
|
||||
assign l1clk = clk;
|
||||
`else
|
||||
TEC_RV_ICG clkhdr ( .*, .EN(en), .CK(clk), .Q(l1clk));
|
||||
`endif
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
@ -1,6 +1,6 @@
|
|||
//********************************************************************************
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 Western Digital Corporation or its affiliates.
|
||||
// Copyright 2020 Western Digital Corporation or it's affiliates.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -20,38 +20,29 @@
|
|||
//********************************************************************************
|
||||
|
||||
module ifu_iccm_mem
|
||||
//`include "parameter.sv"
|
||||
#(
|
||||
parameter ICCM_BITS,
|
||||
parameter ICCM_BANK_INDEX_LO,
|
||||
parameter ICCM_INDEX_BITS,
|
||||
parameter ICCM_BANK_HI,
|
||||
parameter ICCM_NUM_BANKS,
|
||||
// parameter ICCM_ENABLE= 'b1,
|
||||
parameter ICCM_BANK_BITS
|
||||
|
||||
)
|
||||
parameter ICCM_BANK_BITS )(
|
||||
input logic clk,
|
||||
input logic rst_l,
|
||||
input logic clk_override,
|
||||
|
||||
(
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
|
||||
input logic rst_l, // reset, active low
|
||||
input logic clk_override, // Override non-functional clock gating
|
||||
|
||||
input logic iccm_wren, // ICCM write enable
|
||||
input logic iccm_rden, // ICCM read enable
|
||||
input logic [ICCM_BITS-1:1] iccm_rw_addr, // ICCM read/write address
|
||||
input logic iccm_wren,
|
||||
input logic iccm_rden,
|
||||
input logic [ICCM_BITS-1:1] iccm_rw_addr,
|
||||
input logic iccm_buf_correct_ecc, // ICCM is doing a single bit error correct cycle
|
||||
input logic iccm_correction_state, // ICCM under a correction - This is needed to guard replacements when hit
|
||||
input logic [2:0] iccm_wr_size, // ICCM write size
|
||||
input logic [77:0] iccm_wr_data, // ICCM write data
|
||||
input logic iccm_correction_state, // We are under a correction - This is needed to guard replacements when hit
|
||||
input logic [2:0] iccm_wr_size,
|
||||
input logic [77:0] iccm_wr_data,
|
||||
|
||||
input iccm_ext_in_pkt_t [ICCM_NUM_BANKS-1:0] iccm_ext_in_pkt, // External packet
|
||||
|
||||
|
||||
output logic [63:0] iccm_rd_data, // ICCM read data
|
||||
output logic [77:0] iccm_rd_data_ecc, // ICCM read ecc
|
||||
input logic scan_mode // Scan mode control
|
||||
output logic [63:0] iccm_rd_data,
|
||||
output logic [77:0] iccm_rd_data_ecc,
|
||||
input logic scan_mode
|
||||
|
||||
);
|
||||
|
||||
|
@ -84,32 +75,15 @@ module ifu_iccm_mem
|
|||
logic redundant_data1_en;
|
||||
logic r0_addr_en, r1_addr_en;
|
||||
|
||||
// Testing persistent flip
|
||||
// logic [3:0] not_iccm_bank_dout;
|
||||
// logic [15:3] ecc_insert_flip_in, ecc_insert_flip;
|
||||
// logic flip_en, flip_match, flip_match_q;
|
||||
//
|
||||
// assign flip_in = (iccm_rw_addr[3:2] != 2'b00); // dont flip when bank0 - this is to make some progress in DMA streaming cases
|
||||
// assign flip_en = iccm_rden;
|
||||
//
|
||||
// rvdffs #(1) flipmatch (.*,
|
||||
// .clk(clk),
|
||||
// .din(flip_in),
|
||||
// .en(flip_en),
|
||||
// .dout(flip_match_q));
|
||||
//
|
||||
// end of testing flip
|
||||
|
||||
|
||||
assign addr_incr[1:0] = (iccm_wr_size[1:0] == 2'b11) ? 2'b10: 2'b01;
|
||||
assign addr_bank_inc[ICCM_BITS-1 : 1] = iccm_rw_addr[ICCM_BITS-1 : 1] + addr_incr[1:0];
|
||||
|
||||
for (genvar i=0; i<ICCM_NUM_BANKS/2; i++) begin: mem_bank_data
|
||||
for (genvar i=0; i<32'(ICCM_NUM_BANKS)/2; i++) begin: mem_bank_data
|
||||
assign iccm_bank_wr_data_vec[(2*i)] = iccm_wr_data[38:0];
|
||||
assign iccm_bank_wr_data_vec[(2*i)+1] = iccm_wr_data[77:39];
|
||||
end
|
||||
|
||||
for (genvar i=0; i<ICCM_NUM_BANKS; i++) begin: mem_bank
|
||||
for (genvar i=0; i<32'(ICCM_NUM_BANKS); i++) begin: mem_bank
|
||||
assign wren_bank[i] = iccm_wren & ((iccm_rw_addr[ICCM_BANK_HI:2] == i) | (addr_bank_inc[ICCM_BANK_HI:2] == i));
|
||||
assign iccm_bank_wr_data[i] = iccm_bank_wr_data_vec[i];
|
||||
assign rden_bank[i] = iccm_rden & ( (iccm_rw_addr[ICCM_BANK_HI:2] == i) | (addr_bank_inc[ICCM_BANK_HI:2] == i));
|
||||
|
@ -127,18 +101,7 @@ module ifu_iccm_mem
|
|||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
.Q(iccm_bank_dout[i][38:0])
|
||||
|
||||
);
|
||||
`else
|
||||
|
@ -151,18 +114,7 @@ module ifu_iccm_mem
|
|||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
.Q(iccm_bank_dout[i][38:0])
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
|
@ -175,18 +127,7 @@ module ifu_iccm_mem
|
|||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
.Q(iccm_bank_dout[i][38:0])
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
|
@ -199,18 +140,7 @@ module ifu_iccm_mem
|
|||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
.Q(iccm_bank_dout[i][38:0])
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
|
@ -222,18 +152,7 @@ module ifu_iccm_mem
|
|||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
.Q(iccm_bank_dout[i][38:0])
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
|
@ -245,18 +164,7 @@ module ifu_iccm_mem
|
|||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
.Q(iccm_bank_dout[i][38:0])
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
|
@ -268,18 +176,7 @@ module ifu_iccm_mem
|
|||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
.Q(iccm_bank_dout[i][38:0])
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
|
@ -291,18 +188,7 @@ module ifu_iccm_mem
|
|||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
.Q(iccm_bank_dout[i][38:0])
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
|
@ -314,18 +200,7 @@ module ifu_iccm_mem
|
|||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
.Q(iccm_bank_dout[i][38:0])
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
|
@ -337,18 +212,7 @@ module ifu_iccm_mem
|
|||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
.Q(iccm_bank_dout[i][38:0])
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
|
@ -360,18 +224,7 @@ module ifu_iccm_mem
|
|||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(iccm_bank_wr_data[i][38:0]),
|
||||
.Q(iccm_bank_dout[i][38:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
.TEST1(iccm_ext_in_pkt[i].TEST1),
|
||||
.RME(iccm_ext_in_pkt[i].RME),
|
||||
.RM(iccm_ext_in_pkt[i].RM),
|
||||
.LS(iccm_ext_in_pkt[i].LS),
|
||||
.DS(iccm_ext_in_pkt[i].DS),
|
||||
.SD(iccm_ext_in_pkt[i].SD) ,
|
||||
.TEST_RNM(iccm_ext_in_pkt[i].TEST_RNM),
|
||||
.BC1(iccm_ext_in_pkt[i].BC1),
|
||||
.BC2(iccm_ext_in_pkt[i].BC2)
|
||||
.Q(iccm_bank_dout[i][38:0])
|
||||
|
||||
);
|
||||
end // block: iccm
|
||||
|
@ -385,20 +238,21 @@ module ifu_iccm_mem
|
|||
((addr_bank_inc[ICCM_BITS-1:2]== redundant_address[0][ICCM_BITS-1:2]) & (addr_bank_inc[3:2] == i))));
|
||||
|
||||
rvdff #(1) selred0 (.*,
|
||||
.clk(active_clk),
|
||||
.clk(clk),
|
||||
.din(sel_red0[i]),
|
||||
.dout(sel_red0_q[i]));
|
||||
|
||||
rvdff #(1) selred1 (.*,
|
||||
.clk(active_clk),
|
||||
.clk(clk),
|
||||
.din(sel_red1[i]),
|
||||
.dout(sel_red1_q[i]));
|
||||
|
||||
|
||||
// muxing out the memory data with the redundant data if the address matches
|
||||
assign iccm_bank_dout_fn[i][38:0] = ({39{sel_red1_q[i]}} & redundant_data[1][38:0]) |
|
||||
({39{sel_red0_q[i]}} & redundant_data[0][38:0]) |
|
||||
({39{~sel_red0_q[i] & ~sel_red1_q[i]}} & iccm_bank_dout[i][38:0]);
|
||||
assign iccm_bank_dout_fn[i][38:0] = ({39{sel_red1_q[i]}} & redundant_data[1][38:0]) |
|
||||
({39{sel_red0_q[i]}} & redundant_data[0][38:0]) |
|
||||
({39{~sel_red0_q[i] & ~sel_red1_q[i]}} & iccm_bank_dout[i][38:0]);
|
||||
|
||||
|
||||
end : mem_bank
|
||||
// This section does the redundancy for tolerating single bit errors
|
||||
|
@ -410,31 +264,31 @@ module ifu_iccm_mem
|
|||
assign redundant_lru_in = iccm_buf_correct_ecc ? ~redundant_lru : (|sel_red0[ICCM_NUM_BANKS-1:0]) ? 1'b1 : 1'b0;
|
||||
|
||||
rvdffs #() red_lru (.*, // LRU flop for the redundant replacements
|
||||
.clk(active_clk),
|
||||
.clk(clk),
|
||||
.en(redundant_lru_en),
|
||||
.din(redundant_lru_in),
|
||||
.dout(redundant_lru));
|
||||
|
||||
rvdffs #(ICCM_BITS-2) r0_address (.*, // Redundant Row 0 address
|
||||
.clk(active_clk),
|
||||
.clk(clk),
|
||||
.en(r0_addr_en),
|
||||
.din(iccm_rw_addr[ICCM_BITS-1:2]),
|
||||
.dout(redundant_address[0][ICCM_BITS-1:2]));
|
||||
|
||||
rvdffs #(ICCM_BITS-2) r1_address (.*, // Redundant Row 0 address
|
||||
.clk(active_clk),
|
||||
.clk(clk),
|
||||
.en(r1_addr_en),
|
||||
.din(iccm_rw_addr[ICCM_BITS-1:2]),
|
||||
.dout(redundant_address[1][ICCM_BITS-1:2]));
|
||||
|
||||
rvdffs #(1) r0_valid (.*,
|
||||
.clk(active_clk), // Redundant Row 0 Valid
|
||||
.clk(clk), // Redundant Row 0 Valid
|
||||
.en(r0_addr_en),
|
||||
.din(1'b1),
|
||||
.dout(redundant_valid[0]));
|
||||
|
||||
rvdffs #(1) r1_valid (.*, // Redundant Row 1 Valid
|
||||
.clk(active_clk),
|
||||
.clk(clk),
|
||||
.en(r1_addr_en),
|
||||
.din(1'b1),
|
||||
.dout(redundant_valid[1]));
|
||||
|
@ -451,7 +305,7 @@ module ifu_iccm_mem
|
|||
assign redundant_data0_in[38:0] = (((iccm_rw_addr[2] == redundant_address[0][2]) & iccm_rw_addr[2]) | (redundant_address[0][2] & (iccm_wr_size[1:0] == 2'b11))) ? iccm_wr_data[77:39] : iccm_wr_data[38:0];
|
||||
|
||||
rvdffs #(39) r0_data (.*, // Redundant Row 1 data
|
||||
.clk(active_clk),
|
||||
.clk(clk),
|
||||
.en(redundant_data0_en),
|
||||
.din(redundant_data0_in[38:0]),
|
||||
.dout(redundant_data[0][38:0]));
|
||||
|
@ -462,18 +316,18 @@ module ifu_iccm_mem
|
|||
assign redundant_data1_in[38:0] = (((iccm_rw_addr[2] == redundant_address[1][2]) & iccm_rw_addr[2]) | (redundant_address[1][2] & (iccm_wr_size[1:0] == 2'b11))) ? iccm_wr_data[77:39] : iccm_wr_data[38:0];
|
||||
|
||||
rvdffs #(39) r1_data (.*, // Redundant Row 1 data
|
||||
.clk(active_clk),
|
||||
.clk(clk),
|
||||
.en(redundant_data1_en),
|
||||
.din(redundant_data1_in[38:0]),
|
||||
.dout(redundant_data[1][38:0]));
|
||||
|
||||
|
||||
rvdffs #(ICCM_BANK_HI) rd_addr_lo_ff (.*, .clk(active_clk), .din(iccm_rw_addr [ICCM_BANK_HI:1]), .dout(iccm_rd_addr_lo_q[ICCM_BANK_HI:1]), .en(1'b1)); // bit 0 of address is always 0
|
||||
rvdffs #(ICCM_BANK_BITS) rd_addr_hi_ff (.*, .clk(active_clk), .din(addr_bank_inc[ICCM_BANK_HI:2]), .dout(iccm_rd_addr_hi_q[ICCM_BANK_HI:2]), .en(1'b1));
|
||||
rvdffs #(ICCM_BANK_HI) rd_addr_lo_ff (.*, .din(iccm_rw_addr [ICCM_BANK_HI:1]), .dout(iccm_rd_addr_lo_q[ICCM_BANK_HI:1]), .en(1'b1)); // bit 0 of address is always 0
|
||||
rvdffs #(ICCM_BANK_BITS) rd_addr_hi_ff (.*, .din(addr_bank_inc[ICCM_BANK_HI:2]), .dout(iccm_rd_addr_hi_q[ICCM_BANK_HI:2]), .en(1'b1));
|
||||
|
||||
assign iccm_rd_data_pre[63:0] = {iccm_bank_dout_fn[iccm_rd_addr_hi_q][31:0], iccm_bank_dout_fn[iccm_rd_addr_lo_q[ICCM_BANK_HI:2]][31:0]};
|
||||
assign iccm_data[63:0] = 64'({16'b0, (iccm_rd_data_pre[63:0] >> (16*iccm_rd_addr_lo_q[1]))});
|
||||
assign iccm_rd_data[63:0] = {iccm_data[63:0]};
|
||||
assign iccm_rd_data_ecc[77:0] = {iccm_bank_dout_fn[iccm_rd_addr_hi_q][38:0], iccm_bank_dout_fn[iccm_rd_addr_lo_q[ICCM_BANK_HI:2]][38:0]};
|
||||
|
||||
endmodule // ifu_iccm_mem
|
||||
endmodule // el2_ifu_iccm_mem
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 Western Digital Corporation or its affiliates.
|
||||
// Copyright 2020 Western Digital Corporation or it's affiliates.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -27,37 +27,17 @@
|
|||
// //********************************************************************************
|
||||
|
||||
|
||||
|
||||
`define LOCAL_DCCM_RAM_TEST_PORTS .TEST1(dccm_ext_in_pkt[i].TEST1), \
|
||||
.RME(dccm_ext_in_pkt[i].RME), \
|
||||
.RM(dccm_ext_in_pkt[i].RM), \
|
||||
.LS(dccm_ext_in_pkt[i].LS), \
|
||||
.DS(dccm_ext_in_pkt[i].DS), \
|
||||
.SD(dccm_ext_in_pkt[i].SD), \
|
||||
.TEST_RNM(dccm_ext_in_pkt[i].TEST_RNM), \
|
||||
.BC1(dccm_ext_in_pkt[i].BC1), \
|
||||
.BC2(dccm_ext_in_pkt[i].BC2), \
|
||||
|
||||
|
||||
|
||||
module lsu_dccm_mem
|
||||
//`include "parameter.sv"
|
||||
#(
|
||||
|
||||
parameter DCCM_BYTE_WIDTH,
|
||||
parameter DCCM_BITS,
|
||||
parameter DCCM_NUM_BANKS,
|
||||
parameter DCCM_ENABLE= 'b1,
|
||||
parameter DCCM_BANK_BITS,
|
||||
parameter DCCM_SIZE,
|
||||
parameter DCCM_FDATA_WIDTH,
|
||||
parameter DCCM_WIDTH_BITS
|
||||
)
|
||||
(
|
||||
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
|
||||
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
|
||||
input logic rst_l, // reset, active low
|
||||
input logic clk_override, // Override non-functional clock gating
|
||||
parameter DCCM_FDATA_WIDTH )(
|
||||
input logic clk, // clock
|
||||
input logic rst_l,
|
||||
input logic clk_override, // clock override
|
||||
|
||||
input logic dccm_wren, // write enable
|
||||
input logic dccm_rden, // read enable
|
||||
|
@ -67,8 +47,7 @@ module lsu_dccm_mem
|
|||
input logic [DCCM_BITS-1:0] dccm_rd_addr_hi, // read address for the upper bank in case of a misaligned access
|
||||
input logic [DCCM_FDATA_WIDTH-1:0] dccm_wr_data_lo, // write data
|
||||
input logic [DCCM_FDATA_WIDTH-1:0] dccm_wr_data_hi, // write data
|
||||
input dccm_ext_in_pkt_t [DCCM_NUM_BANKS-1:0] dccm_ext_in_pkt, // the dccm packet from the soc
|
||||
|
||||
|
||||
output logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_lo, // read data from the lo bank
|
||||
output logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi, // read data from the hi bank
|
||||
|
||||
|
@ -76,7 +55,7 @@ module lsu_dccm_mem
|
|||
);
|
||||
|
||||
|
||||
//localparam DCCM_WIDTH_BITS = $clog2(DCCM_BYTE_WIDTH);
|
||||
localparam DCCM_WIDTH_BITS = $clog2(DCCM_BYTE_WIDTH);
|
||||
localparam DCCM_INDEX_BITS = (DCCM_BITS - DCCM_BANK_BITS - DCCM_WIDTH_BITS);
|
||||
localparam DCCM_INDEX_DEPTH = ((DCCM_SIZE)*1024)/((DCCM_BYTE_WIDTH)*(DCCM_NUM_BANKS)); // Depth of memory bank
|
||||
|
||||
|
@ -102,9 +81,10 @@ module lsu_dccm_mem
|
|||
assign dccm_rd_data_lo[DCCM_FDATA_WIDTH-1:0] = dccm_bank_dout[dccm_rd_addr_lo_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]][DCCM_FDATA_WIDTH-1:0];
|
||||
assign dccm_rd_data_hi[DCCM_FDATA_WIDTH-1:0] = dccm_bank_dout[dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]][DCCM_FDATA_WIDTH-1:0];
|
||||
|
||||
// Generate even/odd address
|
||||
|
||||
// 8 Banks, 16KB each (2048 x 72)
|
||||
for (genvar i=0; i<DCCM_NUM_BANKS; i++) begin: mem_bank
|
||||
for (genvar i=0; i<32'(DCCM_NUM_BANKS); i++) begin: mem_bank
|
||||
assign wren_bank[i] = dccm_wren & ((dccm_wr_addr_hi[2+:DCCM_BANK_BITS] == i) | (dccm_wr_addr_lo[2+:DCCM_BANK_BITS] == i));
|
||||
assign rden_bank[i] = dccm_rden & ((dccm_rd_addr_hi[2+:DCCM_BANK_BITS] == i) | (dccm_rd_addr_lo[2+:DCCM_BANK_BITS] == i));
|
||||
assign addr_bank[i][(DCCM_BANK_BITS+DCCM_WIDTH_BITS)+:DCCM_INDEX_BITS] = wren_bank[i] ? (((dccm_wr_addr_hi[2+:DCCM_BANK_BITS] == i) & wr_unaligned) ?
|
||||
|
@ -121,8 +101,7 @@ module lsu_dccm_mem
|
|||
// end clock gating section
|
||||
|
||||
`ifdef VERILATOR
|
||||
|
||||
el2_ram #(DCCM_INDEX_DEPTH,39) ram (
|
||||
el2_ram #(DCCM_INDEX_DEPTH,39) ram (
|
||||
// Primary ports
|
||||
.ME(dccm_clken[i]),
|
||||
.CLK(clk),
|
||||
|
@ -130,13 +109,10 @@ module lsu_dccm_mem
|
|||
.ADR(addr_bank[i]),
|
||||
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
`LOCAL_DCCM_RAM_TEST_PORTS
|
||||
.*
|
||||
);
|
||||
`else
|
||||
|
||||
`else
|
||||
if (DCCM_INDEX_DEPTH == 32768) begin : dccm
|
||||
ram_32768x39 dccm_bank (
|
||||
// Primary ports
|
||||
|
@ -146,10 +122,7 @@ module lsu_dccm_mem
|
|||
.ADR(addr_bank[i]),
|
||||
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
`LOCAL_DCCM_RAM_TEST_PORTS
|
||||
.*
|
||||
.*
|
||||
);
|
||||
end
|
||||
else if (DCCM_INDEX_DEPTH == 16384) begin : dccm
|
||||
|
@ -161,9 +134,6 @@ module lsu_dccm_mem
|
|||
.ADR(addr_bank[i]),
|
||||
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
`LOCAL_DCCM_RAM_TEST_PORTS
|
||||
.*
|
||||
);
|
||||
end
|
||||
|
@ -176,9 +146,6 @@ module lsu_dccm_mem
|
|||
.ADR(addr_bank[i]),
|
||||
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
`LOCAL_DCCM_RAM_TEST_PORTS
|
||||
.*
|
||||
);
|
||||
end
|
||||
|
@ -191,9 +158,6 @@ module lsu_dccm_mem
|
|||
.ADR(addr_bank[i]),
|
||||
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
`LOCAL_DCCM_RAM_TEST_PORTS
|
||||
.*
|
||||
);
|
||||
end
|
||||
|
@ -206,9 +170,6 @@ module lsu_dccm_mem
|
|||
.ADR(addr_bank[i]),
|
||||
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
`LOCAL_DCCM_RAM_TEST_PORTS
|
||||
.*
|
||||
);
|
||||
end
|
||||
|
@ -221,9 +182,6 @@ module lsu_dccm_mem
|
|||
.ADR(addr_bank[i]),
|
||||
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
`LOCAL_DCCM_RAM_TEST_PORTS
|
||||
.*
|
||||
);
|
||||
end
|
||||
|
@ -236,9 +194,6 @@ module lsu_dccm_mem
|
|||
.ADR(addr_bank[i]),
|
||||
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
`LOCAL_DCCM_RAM_TEST_PORTS
|
||||
.*
|
||||
);
|
||||
end
|
||||
|
@ -251,9 +206,6 @@ module lsu_dccm_mem
|
|||
.ADR(addr_bank[i]),
|
||||
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
`LOCAL_DCCM_RAM_TEST_PORTS
|
||||
.*
|
||||
);
|
||||
end
|
||||
|
@ -266,37 +218,18 @@ module lsu_dccm_mem
|
|||
.ADR(addr_bank[i]),
|
||||
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
`LOCAL_DCCM_RAM_TEST_PORTS
|
||||
.*
|
||||
);
|
||||
end
|
||||
else if (DCCM_INDEX_DEPTH == 128) begin : dccm
|
||||
ram_128x39 dccm_bank (
|
||||
// Primary ports
|
||||
.ME(dccm_clken[i]),
|
||||
.CLK(clk),
|
||||
.WE(wren_bank[i]),
|
||||
.ADR(addr_bank[i]),
|
||||
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
|
||||
.ROP ( ),
|
||||
// These are used by SoC
|
||||
`LOCAL_DCCM_RAM_TEST_PORTS
|
||||
.*
|
||||
);
|
||||
end
|
||||
`endif
|
||||
|
||||
`endif // VERILATOR
|
||||
end : mem_bank
|
||||
|
||||
// Flops
|
||||
rvdff #(DCCM_BANK_BITS) rd_addr_lo_ff (.*, .din(dccm_rd_addr_lo[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_lo_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .clk(active_clk));
|
||||
rvdff #(DCCM_BANK_BITS) rd_addr_hi_ff (.*, .din(dccm_rd_addr_hi[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .clk(active_clk));
|
||||
rvdffs #(DCCM_BANK_BITS) rd_addr_lo_ff (.*, .din(dccm_rd_addr_lo[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_lo_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .en(1'b1));
|
||||
rvdffs #(DCCM_BANK_BITS) rd_addr_hi_ff (.*, .din(dccm_rd_addr_hi[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .en(1'b1));
|
||||
|
||||
`undef LOCAL_DCCM_RAM_TEST_PORTS
|
||||
`undef EL2_LOCAL_DCCM_RAM_TEST_PORTS
|
||||
|
||||
endmodule // lsu_dccm_mem
|
||||
endmodule // el2_lsu_dccm_mem
|
||||
|
||||
|
||||
|
|
|
@ -1,71 +1,5 @@
|
|||
//********************************************************************************
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 Western Digital Corporation or its affiliates.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//********************************************************************************
|
||||
|
||||
typedef struct packed {
|
||||
logic TEST1;
|
||||
logic RME;
|
||||
logic [3:0] RM;
|
||||
|
||||
logic LS;
|
||||
logic DS;
|
||||
logic SD;
|
||||
logic TEST_RNM;
|
||||
logic BC1;
|
||||
logic BC2;
|
||||
} iccm_ext_in_pkt_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic TEST1;
|
||||
logic RME;
|
||||
logic [3:0] RM;
|
||||
logic LS;
|
||||
logic DS;
|
||||
logic SD;
|
||||
logic TEST_RNM;
|
||||
logic BC1;
|
||||
logic BC2;
|
||||
} dccm_ext_in_pkt_t;
|
||||
|
||||
|
||||
typedef struct packed {
|
||||
logic TEST1;
|
||||
logic RME;
|
||||
logic [3:0] RM;
|
||||
logic LS;
|
||||
logic DS;
|
||||
logic SD;
|
||||
logic TEST_RNM;
|
||||
logic BC1;
|
||||
logic BC2;
|
||||
} ic_data_ext_in_pkt_t;
|
||||
|
||||
|
||||
typedef struct packed {
|
||||
logic TEST1;
|
||||
logic RME;
|
||||
logic [3:0] RM;
|
||||
logic LS;
|
||||
logic DS;
|
||||
logic SD;
|
||||
logic TEST_RNM;
|
||||
logic BC1;
|
||||
logic BC2;
|
||||
} ic_tag_ext_in_pkt_t;
|
||||
module mem#(
|
||||
module mem #(
|
||||
parameter ICACHE_BEAT_BITS,
|
||||
parameter ICCM_BITS,
|
||||
parameter ICACHE_NUM_WAYS,
|
||||
|
@ -95,17 +29,7 @@ module mem#(
|
|||
parameter DCCM_SIZE,
|
||||
parameter DCCM_FDATA_WIDTH,
|
||||
parameter ICACHE_TAG_INDEX_LO,
|
||||
parameter ICACHE_DATA_DEPTH,
|
||||
parameter DCCM_WIDTH_BITS,
|
||||
parameter ICACHE_NUM_BYPASS,
|
||||
parameter ICACHE_TAG_NUM_BYPASS,
|
||||
parameter ICACHE_TAG_NUM_BYPASS_WIDTH,
|
||||
parameter ICACHE_TAG_BYPASS_ENABLE,
|
||||
parameter ICACHE_NUM_BYPASS_WIDTH,
|
||||
parameter ICACHE_BYPASS_ENABLE,
|
||||
parameter ICACHE_LN_SZ
|
||||
)
|
||||
|
||||
parameter ICACHE_DATA_DEPTH)
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst_l,
|
||||
|
@ -128,89 +52,10 @@ module mem#(
|
|||
output logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi,
|
||||
|
||||
//`ifdef DCCM_ENABLE
|
||||
//input dccm_ext_in_pkt_t [DCCM_NUM_BANKS-1:0] dccm_ext_in_pkt,
|
||||
input logic dccm_ext_in_pkt_TEST1_0,
|
||||
input logic dccm_ext_in_pkt_RME_0,
|
||||
input logic [3:0] dccm_ext_in_pkt_RM_0,
|
||||
input logic dccm_ext_in_pkt_LS_0,
|
||||
input logic dccm_ext_in_pkt_DS_0,
|
||||
input logic dccm_ext_in_pkt_SD_0,
|
||||
input logic dccm_ext_in_pkt_TEST_RNM_0,
|
||||
input logic dccm_ext_in_pkt_BC1_0,
|
||||
input logic dccm_ext_in_pkt_BC2_0,
|
||||
|
||||
input logic dccm_ext_in_pkt_TEST1_1,
|
||||
input logic dccm_ext_in_pkt_RME_1,
|
||||
input logic [3:0] dccm_ext_in_pkt_RM_1,
|
||||
input logic dccm_ext_in_pkt_LS_1,
|
||||
input logic dccm_ext_in_pkt_DS_1,
|
||||
input logic dccm_ext_in_pkt_SD_1,
|
||||
input logic dccm_ext_in_pkt_TEST_RNM_1,
|
||||
input logic dccm_ext_in_pkt_BC1_1,
|
||||
input logic dccm_ext_in_pkt_BC2_1,
|
||||
|
||||
input logic dccm_ext_in_pkt_TEST1_2,
|
||||
input logic dccm_ext_in_pkt_RME_2,
|
||||
input logic [3:0] dccm_ext_in_pkt_RM_2,
|
||||
input logic dccm_ext_in_pkt_LS_2,
|
||||
input logic dccm_ext_in_pkt_DS_2,
|
||||
input logic dccm_ext_in_pkt_SD_2,
|
||||
input logic dccm_ext_in_pkt_TEST_RNM_2,
|
||||
input logic dccm_ext_in_pkt_BC1_2,
|
||||
input logic dccm_ext_in_pkt_BC2_2,
|
||||
|
||||
input logic dccm_ext_in_pkt_TEST1_3,
|
||||
input logic dccm_ext_in_pkt_RME_3,
|
||||
input logic [3:0] dccm_ext_in_pkt_RM_3,
|
||||
input logic dccm_ext_in_pkt_LS_3,
|
||||
input logic dccm_ext_in_pkt_DS_3,
|
||||
input logic dccm_ext_in_pkt_SD_3,
|
||||
input logic dccm_ext_in_pkt_TEST_RNM_3,
|
||||
input logic dccm_ext_in_pkt_BC1_3,
|
||||
input logic dccm_ext_in_pkt_BC2_3,
|
||||
|
||||
//`endif
|
||||
|
||||
//ICCM ports
|
||||
input logic iccm_ext_in_pkt_TEST1_0,
|
||||
input logic iccm_ext_in_pkt_RME_0,
|
||||
input logic [3:0] iccm_ext_in_pkt_RM_0,
|
||||
input logic iccm_ext_in_pkt_LS_0,
|
||||
input logic iccm_ext_in_pkt_DS_0,
|
||||
input logic iccm_ext_in_pkt_SD_0,
|
||||
input logic iccm_ext_in_pkt_TEST_RNM_0,
|
||||
input logic iccm_ext_in_pkt_BC1_0,
|
||||
input logic iccm_ext_in_pkt_BC2_0,
|
||||
|
||||
input logic iccm_ext_in_pkt_TEST1_1,
|
||||
input logic iccm_ext_in_pkt_RME_1,
|
||||
input logic [3:0] iccm_ext_in_pkt_RM_1,
|
||||
input logic iccm_ext_in_pkt_LS_1,
|
||||
input logic iccm_ext_in_pkt_DS_1,
|
||||
input logic iccm_ext_in_pkt_SD_1,
|
||||
input logic iccm_ext_in_pkt_TEST_RNM_1,
|
||||
input logic iccm_ext_in_pkt_BC1_1,
|
||||
input logic iccm_ext_in_pkt_BC2_1,
|
||||
|
||||
input logic iccm_ext_in_pkt_TEST1_2,
|
||||
input logic iccm_ext_in_pkt_RME_2,
|
||||
input logic [3:0] iccm_ext_in_pkt_RM_2,
|
||||
input logic iccm_ext_in_pkt_LS_2,
|
||||
input logic iccm_ext_in_pkt_DS_2,
|
||||
input logic iccm_ext_in_pkt_SD_2,
|
||||
input logic iccm_ext_in_pkt_TEST_RNM_2,
|
||||
input logic iccm_ext_in_pkt_BC1_2,
|
||||
input logic iccm_ext_in_pkt_BC2_2,
|
||||
|
||||
input logic iccm_ext_in_pkt_TEST1_3,
|
||||
input logic iccm_ext_in_pkt_RME_3,
|
||||
input logic [3:0] iccm_ext_in_pkt_RM_3,
|
||||
input logic iccm_ext_in_pkt_LS_3,
|
||||
input logic iccm_ext_in_pkt_DS_3,
|
||||
input logic iccm_ext_in_pkt_SD_3,
|
||||
input logic iccm_ext_in_pkt_TEST_RNM_3,
|
||||
input logic iccm_ext_in_pkt_BC1_3,
|
||||
input logic iccm_ext_in_pkt_BC2_3,
|
||||
|
||||
input logic [ICCM_BITS-1:1] iccm_rw_addr,
|
||||
input logic iccm_buf_correct_ecc, // ICCM is doing a single bit error correct cycle
|
||||
|
@ -231,71 +76,10 @@ module mem#(
|
|||
input logic ic_rd_en,
|
||||
input logic [63:0] ic_premux_data, // Premux data to be muxed with each way of the Icache.
|
||||
input logic ic_sel_premux_data, // Premux data sel
|
||||
// input ic_data_ext_in_pkt_t [ICACHE_NUM_WAYS-1:0][ICACHE_BANKS_WAY-1:0] ic_data_ext_in_pkt,
|
||||
input logic ic_tag_ext_in_pkt_TEST1_0,
|
||||
input logic ic_tag_ext_in_pkt_RME_0,
|
||||
input logic [3:0] ic_tag_ext_in_pkt_RM_0,
|
||||
input logic ic_tag_ext_in_pkt_LS_0,
|
||||
input logic ic_tag_ext_in_pkt_DS_0,
|
||||
input logic ic_tag_ext_in_pkt_SD_0,
|
||||
input logic ic_tag_ext_in_pkt_TEST_RNM_0,
|
||||
input logic ic_tag_ext_in_pkt_BC1_0,
|
||||
input logic ic_tag_ext_in_pkt_BC2_0,
|
||||
|
||||
input logic ic_tag_ext_in_pkt_TEST1_1,
|
||||
input logic ic_tag_ext_in_pkt_RME_1,
|
||||
input logic [3:0] ic_tag_ext_in_pkt_RM_1,
|
||||
input logic ic_tag_ext_in_pkt_LS_1,
|
||||
input logic ic_tag_ext_in_pkt_DS_1,
|
||||
input logic ic_tag_ext_in_pkt_SD_1,
|
||||
input logic ic_tag_ext_in_pkt_TEST_RNM_1,
|
||||
input logic ic_tag_ext_in_pkt_BC1_1,
|
||||
input logic ic_tag_ext_in_pkt_BC2_1,
|
||||
|
||||
input logic ic_data_ext_in_pkt_0_TEST1_0,
|
||||
input logic ic_data_ext_in_pkt_0_RME_0,
|
||||
input logic [3:0] ic_data_ext_in_pkt_0_RM_0,
|
||||
input logic ic_data_ext_in_pkt_0_LS_0,
|
||||
input logic ic_data_ext_in_pkt_0_DS_0,
|
||||
input logic ic_data_ext_in_pkt_0_SD_0,
|
||||
input logic ic_data_ext_in_pkt_0_TEST_RNM_0,
|
||||
input logic ic_data_ext_in_pkt_0_BC1_0,
|
||||
input logic ic_data_ext_in_pkt_0_BC2_0,
|
||||
|
||||
input logic ic_data_ext_in_pkt_0_TEST1_1,
|
||||
input logic ic_data_ext_in_pkt_0_RME_1,
|
||||
input logic [3:0] ic_data_ext_in_pkt_0_RM_1,
|
||||
input logic ic_data_ext_in_pkt_0_LS_1,
|
||||
input logic ic_data_ext_in_pkt_0_DS_1,
|
||||
input logic ic_data_ext_in_pkt_0_SD_1,
|
||||
input logic ic_data_ext_in_pkt_0_TEST_RNM_1,
|
||||
input logic ic_data_ext_in_pkt_0_BC1_1,
|
||||
input logic ic_data_ext_in_pkt_0_BC2_1,
|
||||
|
||||
input logic ic_data_ext_in_pkt_1_TEST1_0,
|
||||
input logic ic_data_ext_in_pkt_1_RME_0,
|
||||
input logic [3:0] ic_data_ext_in_pkt_1_RM_0,
|
||||
input logic ic_data_ext_in_pkt_1_LS_0,
|
||||
input logic ic_data_ext_in_pkt_1_DS_0,
|
||||
input logic ic_data_ext_in_pkt_1_SD_0,
|
||||
input logic ic_data_ext_in_pkt_1_TEST_RNM_0,
|
||||
input logic ic_data_ext_in_pkt_1_BC1_0,
|
||||
input logic ic_data_ext_in_pkt_1_BC2_0,
|
||||
|
||||
input logic ic_data_ext_in_pkt_1_TEST1_1,
|
||||
input logic ic_data_ext_in_pkt_1_RME_1,
|
||||
input logic [3:0] ic_data_ext_in_pkt_1_RM_1,
|
||||
input logic ic_data_ext_in_pkt_1_LS_1,
|
||||
input logic ic_data_ext_in_pkt_1_DS_1,
|
||||
input logic ic_data_ext_in_pkt_1_SD_1,
|
||||
input logic ic_data_ext_in_pkt_1_TEST_RNM_1,
|
||||
input logic ic_data_ext_in_pkt_1_BC1_1,
|
||||
input logic ic_data_ext_in_pkt_1_BC2_1,
|
||||
|
||||
// input logic [ICACHE_BANKS_WAY-1:0][70:0] ic_wr_data, // Data to fill to the Icache. With ECC
|
||||
input logic [70:0] ic_wr_data_0, // Data to fill to the Icache. With ECC
|
||||
input logic [70:0] ic_wr_data_1, // Data to fill to the Icache. With ECC
|
||||
input logic [70:0] ic_debug_wr_data, // Debug wr cache.
|
||||
input logic [70:0] ic_wr_data_0, // Data to fill to the Icache. With ECC
|
||||
input logic [70:0] ic_wr_data_1,
|
||||
input logic [70:0] ic_debug_wr_data, // Debug wr cache.
|
||||
output logic [70:0] ic_debug_rd_data , // Data read from Icache. 2x64bits + parity bits. F2 stage. With ECC
|
||||
input logic [ICACHE_INDEX_HI:3] ic_debug_addr, // Read/Write addresss to the Icache.
|
||||
input logic ic_debug_rd_en, // Icache debug rd
|
||||
|
@ -317,160 +101,9 @@ module mem#(
|
|||
|
||||
);
|
||||
|
||||
iccm_ext_in_pkt_t [ICCM_NUM_BANKS-1:0] iccm_ext_in_pkt;
|
||||
dccm_ext_in_pkt_t [DCCM_NUM_BANKS-1:0] dccm_ext_in_pkt;
|
||||
ic_data_ext_in_pkt_t [ICACHE_NUM_WAYS-1:0][ICACHE_BANKS_WAY-1:0] ic_data_ext_in_pkt;
|
||||
ic_tag_ext_in_pkt_t [ICACHE_NUM_WAYS-1:0] ic_tag_ext_in_pkt;
|
||||
|
||||
|
||||
assign dccm_ext_in_pkt[0].TEST1 = dccm_ext_in_pkt_TEST1_0;
|
||||
assign dccm_ext_in_pkt[0].RME = dccm_ext_in_pkt_RME_0;
|
||||
assign dccm_ext_in_pkt[0].RM = dccm_ext_in_pkt_RM_0[3:0];
|
||||
assign dccm_ext_in_pkt[0].LS = dccm_ext_in_pkt_LS_0;
|
||||
assign dccm_ext_in_pkt[0].DS = dccm_ext_in_pkt_DS_0;
|
||||
assign dccm_ext_in_pkt[0].SD = dccm_ext_in_pkt_SD_0;
|
||||
assign dccm_ext_in_pkt[0].TEST_RNM = dccm_ext_in_pkt_TEST_RNM_0;
|
||||
assign dccm_ext_in_pkt[0].BC1 = dccm_ext_in_pkt_BC1_0;
|
||||
assign dccm_ext_in_pkt[0].BC2 = dccm_ext_in_pkt_BC2_0;
|
||||
|
||||
assign dccm_ext_in_pkt[1].TEST1 = dccm_ext_in_pkt_TEST1_1;
|
||||
assign dccm_ext_in_pkt[1].RME = dccm_ext_in_pkt_RME_1;
|
||||
assign dccm_ext_in_pkt[1].RM = dccm_ext_in_pkt_RM_1[3:0];
|
||||
assign dccm_ext_in_pkt[1].LS = dccm_ext_in_pkt_LS_1;
|
||||
assign dccm_ext_in_pkt[1].DS = dccm_ext_in_pkt_DS_1;
|
||||
assign dccm_ext_in_pkt[1].SD = dccm_ext_in_pkt_SD_1;
|
||||
assign dccm_ext_in_pkt[1].TEST_RNM = dccm_ext_in_pkt_TEST_RNM_1;
|
||||
assign dccm_ext_in_pkt[1].BC1 = dccm_ext_in_pkt_BC1_1;
|
||||
assign dccm_ext_in_pkt[1].BC2 = dccm_ext_in_pkt_BC2_1;
|
||||
|
||||
|
||||
assign dccm_ext_in_pkt[2].TEST1 = dccm_ext_in_pkt_TEST1_2;
|
||||
assign dccm_ext_in_pkt[2].RME = dccm_ext_in_pkt_RME_2;
|
||||
assign dccm_ext_in_pkt[2].RM = dccm_ext_in_pkt_RM_2[3:0];
|
||||
assign dccm_ext_in_pkt[2].LS = dccm_ext_in_pkt_LS_2;
|
||||
assign dccm_ext_in_pkt[2].DS = dccm_ext_in_pkt_DS_2;
|
||||
assign dccm_ext_in_pkt[2].SD = dccm_ext_in_pkt_SD_2;
|
||||
assign dccm_ext_in_pkt[2].TEST_RNM = dccm_ext_in_pkt_TEST_RNM_2;
|
||||
assign dccm_ext_in_pkt[2].BC1 = dccm_ext_in_pkt_BC1_2;
|
||||
assign dccm_ext_in_pkt[2].BC2 = dccm_ext_in_pkt_BC2_2;
|
||||
|
||||
assign dccm_ext_in_pkt[3].TEST1 = dccm_ext_in_pkt_TEST1_3;
|
||||
assign dccm_ext_in_pkt[3].RME = dccm_ext_in_pkt_RME_3;
|
||||
assign dccm_ext_in_pkt[3].RM = dccm_ext_in_pkt_RM_3[3:0];
|
||||
assign dccm_ext_in_pkt[3].LS = dccm_ext_in_pkt_LS_3;
|
||||
assign dccm_ext_in_pkt[3].DS = dccm_ext_in_pkt_DS_3;
|
||||
assign dccm_ext_in_pkt[3].SD = dccm_ext_in_pkt_SD_3;
|
||||
assign dccm_ext_in_pkt[3].TEST_RNM = dccm_ext_in_pkt_TEST_RNM_3;
|
||||
assign dccm_ext_in_pkt[3].BC1 = dccm_ext_in_pkt_BC1_3;
|
||||
assign dccm_ext_in_pkt[3].BC2 = dccm_ext_in_pkt_BC2_3;
|
||||
|
||||
assign iccm_ext_in_pkt[0].TEST1 = iccm_ext_in_pkt_TEST1_0;
|
||||
assign iccm_ext_in_pkt[0].RME = iccm_ext_in_pkt_RME_0;
|
||||
assign iccm_ext_in_pkt[0].RM = iccm_ext_in_pkt_RM_0[3:0];
|
||||
assign iccm_ext_in_pkt[0].LS = iccm_ext_in_pkt_LS_0;
|
||||
assign iccm_ext_in_pkt[0].DS = iccm_ext_in_pkt_DS_0;
|
||||
assign iccm_ext_in_pkt[0].SD = iccm_ext_in_pkt_SD_0;
|
||||
assign iccm_ext_in_pkt[0].TEST_RNM = iccm_ext_in_pkt_TEST_RNM_0;
|
||||
assign iccm_ext_in_pkt[0].BC1 = iccm_ext_in_pkt_BC1_0;
|
||||
assign iccm_ext_in_pkt[0].BC2 = iccm_ext_in_pkt_BC2_0;
|
||||
|
||||
assign iccm_ext_in_pkt[1].TEST1 = iccm_ext_in_pkt_TEST1_1;
|
||||
assign iccm_ext_in_pkt[1].RME = iccm_ext_in_pkt_RME_1;
|
||||
assign iccm_ext_in_pkt[1].RM = iccm_ext_in_pkt_RM_1[3:0];
|
||||
assign iccm_ext_in_pkt[1].LS = iccm_ext_in_pkt_LS_1;
|
||||
assign iccm_ext_in_pkt[1].DS = iccm_ext_in_pkt_DS_1;
|
||||
assign iccm_ext_in_pkt[1].SD = iccm_ext_in_pkt_SD_1;
|
||||
assign iccm_ext_in_pkt[1].TEST_RNM = iccm_ext_in_pkt_TEST_RNM_1;
|
||||
assign iccm_ext_in_pkt[1].BC1 = iccm_ext_in_pkt_BC1_1;
|
||||
assign iccm_ext_in_pkt[1].BC2 = iccm_ext_in_pkt_BC2_1;
|
||||
|
||||
|
||||
assign iccm_ext_in_pkt[2].TEST1 = iccm_ext_in_pkt_TEST1_2;
|
||||
assign iccm_ext_in_pkt[2].RME = iccm_ext_in_pkt_RME_2;
|
||||
assign iccm_ext_in_pkt[2].RM = iccm_ext_in_pkt_RM_2[3:0];
|
||||
assign iccm_ext_in_pkt[2].LS = iccm_ext_in_pkt_LS_2;
|
||||
assign iccm_ext_in_pkt[2].DS = iccm_ext_in_pkt_DS_2;
|
||||
assign iccm_ext_in_pkt[2].SD = iccm_ext_in_pkt_SD_2;
|
||||
assign iccm_ext_in_pkt[2].TEST_RNM = iccm_ext_in_pkt_TEST_RNM_2;
|
||||
assign iccm_ext_in_pkt[2].BC1 = iccm_ext_in_pkt_BC1_2;
|
||||
assign iccm_ext_in_pkt[2].BC2 = iccm_ext_in_pkt_BC2_2;
|
||||
|
||||
assign iccm_ext_in_pkt[3].TEST1 = iccm_ext_in_pkt_TEST1_3;
|
||||
assign iccm_ext_in_pkt[3].RME = iccm_ext_in_pkt_RME_3;
|
||||
assign iccm_ext_in_pkt[3].RM = iccm_ext_in_pkt_RM_3[3:0];
|
||||
assign iccm_ext_in_pkt[3].LS = iccm_ext_in_pkt_LS_3;
|
||||
assign iccm_ext_in_pkt[3].DS = iccm_ext_in_pkt_DS_3;
|
||||
assign iccm_ext_in_pkt[3].SD = iccm_ext_in_pkt_SD_3;
|
||||
assign iccm_ext_in_pkt[3].TEST_RNM = iccm_ext_in_pkt_TEST_RNM_3;
|
||||
assign iccm_ext_in_pkt[3].BC1 = iccm_ext_in_pkt_BC1_3;
|
||||
assign iccm_ext_in_pkt[3].BC2 = iccm_ext_in_pkt_BC2_3;
|
||||
|
||||
|
||||
assign ic_tag_ext_in_pkt[0].TEST1 = ic_tag_ext_in_pkt_TEST1_0;
|
||||
assign ic_tag_ext_in_pkt[0].RME = ic_tag_ext_in_pkt_RME_0;
|
||||
assign ic_tag_ext_in_pkt[0].RM = ic_tag_ext_in_pkt_RM_0[3:0];
|
||||
assign ic_tag_ext_in_pkt[0].LS = ic_tag_ext_in_pkt_LS_0;
|
||||
assign ic_tag_ext_in_pkt[0].DS = ic_tag_ext_in_pkt_DS_0;
|
||||
assign ic_tag_ext_in_pkt[0].SD = ic_tag_ext_in_pkt_SD_0;
|
||||
assign ic_tag_ext_in_pkt[0].TEST_RNM = ic_tag_ext_in_pkt_TEST_RNM_0;
|
||||
assign ic_tag_ext_in_pkt[0].BC1 = ic_tag_ext_in_pkt_BC1_0;
|
||||
assign ic_tag_ext_in_pkt[0].BC2 = ic_tag_ext_in_pkt_BC2_0;
|
||||
|
||||
assign ic_tag_ext_in_pkt[1].TEST1 = ic_tag_ext_in_pkt_TEST1_1;
|
||||
assign ic_tag_ext_in_pkt[1].RME = ic_tag_ext_in_pkt_RME_1;
|
||||
assign ic_tag_ext_in_pkt[1].RM = ic_tag_ext_in_pkt_RM_1[3:0];
|
||||
assign ic_tag_ext_in_pkt[1].LS = ic_tag_ext_in_pkt_LS_1;
|
||||
assign ic_tag_ext_in_pkt[1].DS = ic_tag_ext_in_pkt_DS_1;
|
||||
assign ic_tag_ext_in_pkt[1].SD = ic_tag_ext_in_pkt_SD_1;
|
||||
assign ic_tag_ext_in_pkt[1].TEST_RNM = ic_tag_ext_in_pkt_TEST_RNM_1;
|
||||
assign ic_tag_ext_in_pkt[1].BC1 = ic_tag_ext_in_pkt_BC1_1;
|
||||
assign ic_tag_ext_in_pkt[1].BC2 = ic_tag_ext_in_pkt_BC2_1;
|
||||
|
||||
// PKT connection
|
||||
assign ic_data_ext_in_pkt[0][0].TEST1 = ic_data_ext_in_pkt_0_TEST1_0;
|
||||
assign ic_data_ext_in_pkt[0][0].RME = ic_data_ext_in_pkt_0_RME_0;
|
||||
assign ic_data_ext_in_pkt[0][0].RM = ic_data_ext_in_pkt_0_RM_0[3:0];
|
||||
assign ic_data_ext_in_pkt[0][0].LS = ic_data_ext_in_pkt_0_LS_0;
|
||||
assign ic_data_ext_in_pkt[0][0].DS = ic_data_ext_in_pkt_0_DS_0;
|
||||
assign ic_data_ext_in_pkt[0][0].SD = ic_data_ext_in_pkt_0_SD_0;
|
||||
assign ic_data_ext_in_pkt[0][0].TEST_RNM = ic_data_ext_in_pkt_0_TEST_RNM_0;
|
||||
assign ic_data_ext_in_pkt[0][0].BC1 = ic_data_ext_in_pkt_0_BC1_0;
|
||||
assign ic_data_ext_in_pkt[0][0].BC2 = ic_data_ext_in_pkt_0_BC2_0;
|
||||
|
||||
assign ic_data_ext_in_pkt[0][1].TEST1 = ic_data_ext_in_pkt_1_TEST1_1;
|
||||
assign ic_data_ext_in_pkt[0][1].RME = ic_data_ext_in_pkt_1_RME_1;
|
||||
assign ic_data_ext_in_pkt[0][1].RM = ic_data_ext_in_pkt_1_RM_1[3:0];
|
||||
assign ic_data_ext_in_pkt[0][1].LS = ic_data_ext_in_pkt_1_LS_1;
|
||||
assign ic_data_ext_in_pkt[0][1].DS = ic_data_ext_in_pkt_1_DS_1;
|
||||
assign ic_data_ext_in_pkt[0][1].SD = ic_data_ext_in_pkt_1_SD_1;
|
||||
assign ic_data_ext_in_pkt[0][1].TEST_RNM = ic_data_ext_in_pkt_1_TEST_RNM_1;
|
||||
assign ic_data_ext_in_pkt[0][1].BC1 = ic_data_ext_in_pkt_1_BC1_1;
|
||||
assign ic_data_ext_in_pkt[0][1].BC2 = ic_data_ext_in_pkt_1_BC2_1;
|
||||
|
||||
assign ic_data_ext_in_pkt[1][0].TEST1 = ic_data_ext_in_pkt_1_TEST1_0;
|
||||
assign ic_data_ext_in_pkt[1][0].RME = ic_data_ext_in_pkt_1_RME_0;
|
||||
assign ic_data_ext_in_pkt[1][0].RM = ic_data_ext_in_pkt_1_RM_0[3:0];
|
||||
assign ic_data_ext_in_pkt[1][0].LS = ic_data_ext_in_pkt_1_LS_0;
|
||||
assign ic_data_ext_in_pkt[1][0].DS = ic_data_ext_in_pkt_1_DS_0;
|
||||
assign ic_data_ext_in_pkt[1][0].SD = ic_data_ext_in_pkt_1_SD_0;
|
||||
assign ic_data_ext_in_pkt[1][0].TEST_RNM = ic_data_ext_in_pkt_1_TEST_RNM_0;
|
||||
assign ic_data_ext_in_pkt[1][0].BC1 = ic_data_ext_in_pkt_1_BC1_0;
|
||||
assign ic_data_ext_in_pkt[1][0].BC2 = ic_data_ext_in_pkt_1_BC2_0;
|
||||
|
||||
assign ic_data_ext_in_pkt[1][1].TEST1 = ic_data_ext_in_pkt_1_TEST1_1;
|
||||
assign ic_data_ext_in_pkt[1][1].RME = ic_data_ext_in_pkt_1_RME_1;
|
||||
assign ic_data_ext_in_pkt[1][1].RM = ic_data_ext_in_pkt_1_RM_1[3:0];
|
||||
assign ic_data_ext_in_pkt[1][1].LS = ic_data_ext_in_pkt_1_LS_1;
|
||||
assign ic_data_ext_in_pkt[1][1].DS = ic_data_ext_in_pkt_1_DS_1;
|
||||
assign ic_data_ext_in_pkt[1][1].SD = ic_data_ext_in_pkt_1_SD_1;
|
||||
assign ic_data_ext_in_pkt[1][1].TEST_RNM = ic_data_ext_in_pkt_1_TEST_RNM_1;
|
||||
assign ic_data_ext_in_pkt[1][1].BC1 = ic_data_ext_in_pkt_1_BC1_1;
|
||||
assign ic_data_ext_in_pkt[1][1].BC2 = ic_data_ext_in_pkt_1_BC2_1;
|
||||
|
||||
wire active_clk;
|
||||
|
||||
rvoclkhdr active_cg ( .en(1'b1), .l1clk(active_clk), .* );
|
||||
|
||||
logic [ICACHE_BANKS_WAY-1:0][70:0] ic_wr_data;
|
||||
assign ic_wr_data [0] = ic_wr_data_0;
|
||||
assign ic_wr_data [1] = ic_wr_data_1;
|
||||
// DCCM Instantiation
|
||||
if (DCCM_ENABLE == 1) begin: Gen_dccm_enable
|
||||
lsu_dccm_mem #(
|
||||
|
@ -479,8 +112,7 @@ module mem#(
|
|||
.DCCM_NUM_BANKS(DCCM_NUM_BANKS),
|
||||
.DCCM_BANK_BITS(DCCM_BANK_BITS),
|
||||
.DCCM_SIZE(DCCM_SIZE),
|
||||
.DCCM_FDATA_WIDTH(DCCM_FDATA_WIDTH),
|
||||
.DCCM_WIDTH_BITS(DCCM_WIDTH_BITS)) dccm (
|
||||
.DCCM_FDATA_WIDTH(DCCM_FDATA_WIDTH)) dccm (
|
||||
.clk_override(dccm_clk_override),
|
||||
.*
|
||||
);
|
||||
|
@ -505,14 +137,7 @@ if ( ICACHE_ENABLE ) begin: icache
|
|||
.ICACHE_TAG_DEPTH(ICACHE_TAG_DEPTH),
|
||||
.ICACHE_WAYPACK(ICACHE_WAYPACK),
|
||||
.ICACHE_TAG_INDEX_LO(ICACHE_TAG_INDEX_LO),
|
||||
.ICACHE_DATA_DEPTH(ICACHE_DATA_DEPTH),
|
||||
.ICACHE_TAG_NUM_BYPASS(ICACHE_TAG_NUM_BYPASS),
|
||||
.ICACHE_TAG_NUM_BYPASS_WIDTH(ICACHE_TAG_NUM_BYPASS_WIDTH),
|
||||
.ICACHE_TAG_BYPASS_ENABLE(ICACHE_TAG_BYPASS_ENABLE),
|
||||
.ICACHE_NUM_BYPASS_WIDTH(ICACHE_NUM_BYPASS_WIDTH),
|
||||
.ICACHE_BYPASS_ENABLE(ICACHE_BYPASS_ENABLE),
|
||||
.ICACHE_NUM_BYPASS(ICACHE_NUM_BYPASS),
|
||||
.ICACHE_LN_SZ(ICACHE_LN_SZ)) icm (
|
||||
.ICACHE_DATA_DEPTH(ICACHE_DATA_DEPTH)) icm (
|
||||
.clk_override(icm_clk_override),
|
||||
.*
|
||||
);
|
||||
|
@ -527,13 +152,13 @@ end // else: !if( ICACHE_ENABLE )
|
|||
|
||||
|
||||
if (ICCM_ENABLE) begin : iccm
|
||||
ifu_iccm_mem #(
|
||||
ifu_iccm_mem #(
|
||||
.ICCM_BITS(ICCM_BITS),
|
||||
.ICCM_BANK_INDEX_LO(ICCM_BANK_INDEX_LO),
|
||||
.ICCM_INDEX_BITS(ICCM_INDEX_BITS),
|
||||
.ICCM_BANK_HI(ICCM_BANK_HI),
|
||||
.ICCM_NUM_BANKS(ICCM_NUM_BANKS),
|
||||
.ICCM_BANK_BITS(ICCM_BANK_BITS)) iccm (.*,
|
||||
.ICCM_BANK_BITS(ICCM_BANK_BITS)) iccm (.*,
|
||||
.clk_override(icm_clk_override),
|
||||
.iccm_rw_addr(iccm_rw_addr[ICCM_BITS-1:1]),
|
||||
.iccm_rd_data(iccm_rd_data[63:0])
|
||||
|
@ -546,4 +171,3 @@ end
|
|||
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -16,17 +16,7 @@
|
|||
`define EL2_LOCAL_RAM_TEST_IO \
|
||||
input logic WE, \
|
||||
input logic ME, \
|
||||
input logic CLK, \
|
||||
input logic TEST1, \
|
||||
input logic RME, \
|
||||
input logic [3:0] RM, \
|
||||
input logic LS, \
|
||||
input logic DS, \
|
||||
input logic SD, \
|
||||
input logic TEST_RNM, \
|
||||
input logic BC1, \
|
||||
input logic BC2, \
|
||||
output logic ROP
|
||||
input logic CLK
|
||||
|
||||
`define EL2_RAM(depth, width) \
|
||||
module ram_``depth``x``width( \
|
||||
|
@ -36,22 +26,11 @@ module ram_``depth``x``width( \
|
|||
`EL2_LOCAL_RAM_TEST_IO \
|
||||
); \
|
||||
reg [(width-1):0] ram_core [(depth-1):0]; \
|
||||
`ifdef GTLSIM \
|
||||
integer i; \
|
||||
initial begin \
|
||||
for (i=0; i<depth; i=i+1) \
|
||||
ram_core[i] = '0; \
|
||||
end \
|
||||
`endif \
|
||||
always @(posedge CLK) begin \
|
||||
`ifdef GTLSIM \
|
||||
if (ME && WE) ram_core[ADR] <= D; \
|
||||
`else \
|
||||
if (ME && WE) begin ram_core[ADR] <= D; Q <= 'x; end \
|
||||
`endif \
|
||||
\
|
||||
always @(posedge CLK) begin \
|
||||
if (ME && WE) ram_core[ADR] = D; \
|
||||
if (ME && ~WE) Q <= ram_core[ADR]; \
|
||||
end \
|
||||
assign ROP = ME; \
|
||||
\
|
||||
endmodule
|
||||
|
||||
|
@ -63,22 +42,12 @@ module ram_be_``depth``x``width( \
|
|||
`EL2_LOCAL_RAM_TEST_IO \
|
||||
); \
|
||||
reg [(width-1):0] ram_core [(depth-1):0]; \
|
||||
`ifdef GTLSIM \
|
||||
integer i; \
|
||||
initial begin \
|
||||
for (i=0; i<depth; i=i+1) \
|
||||
ram_core[i] = '0; \
|
||||
\
|
||||
always @(posedge CLK) begin \
|
||||
if (ME && WE) ram_core[ADR] = D & WEM | ~WEM & ram_core[ADR];\
|
||||
if (ME && ~WE) Q <= ram_core[ADR]; \
|
||||
end \
|
||||
`endif \
|
||||
always @(posedge CLK) begin \
|
||||
`ifdef GTLSIM \
|
||||
if (ME && WE) ram_core[ADR] <= D & WEM | ~WEM & ram_core[ADR]; \
|
||||
`else \
|
||||
if (ME && WE) begin ram_core[ADR] <= D & WEM | ~WEM & ram_core[ADR]; Q <= 'x; end \
|
||||
`endif \
|
||||
if (ME && ~WE) Q <= ram_core[ADR]; \
|
||||
end \
|
||||
assign ROP = ME; \
|
||||
\
|
||||
\
|
||||
endmodule
|
||||
|
||||
|
@ -92,11 +61,7 @@ output logic [(width-1):0] Q,
|
|||
reg [(width-1):0] ram_core [(depth-1):0];
|
||||
|
||||
always @(posedge CLK) begin
|
||||
`ifdef GTLSIM
|
||||
if (ME && WE) ram_core[ADR] <= D;
|
||||
`else
|
||||
if (ME && WE) begin ram_core[ADR] <= D; Q <= 'x; end
|
||||
`endif
|
||||
if (ME && WE) ram_core[ADR] = D;
|
||||
if (ME && ~WE) Q <= ram_core[ADR];
|
||||
end
|
||||
endmodule
|
||||
|
@ -207,7 +172,6 @@ endmodule
|
|||
`EL2_RAM_BE(256, 52)
|
||||
`EL2_RAM_BE(128, 52)
|
||||
`EL2_RAM_BE(64, 52)
|
||||
`EL2_RAM_BE(32, 52)
|
||||
`EL2_RAM_BE(4096, 104)
|
||||
`EL2_RAM_BE(2048, 104)
|
||||
`EL2_RAM_BE(1024, 104)
|
||||
|
@ -215,7 +179,6 @@ endmodule
|
|||
`EL2_RAM_BE(256, 104)
|
||||
`EL2_RAM_BE(128, 104)
|
||||
`EL2_RAM_BE(64, 104)
|
||||
`EL2_RAM_BE(32, 104)
|
||||
`EL2_RAM_BE(4096, 44)
|
||||
`EL2_RAM_BE(2048, 44)
|
||||
`EL2_RAM_BE(1024, 44)
|
||||
|
@ -223,7 +186,6 @@ endmodule
|
|||
`EL2_RAM_BE(256, 44)
|
||||
`EL2_RAM_BE(128, 44)
|
||||
`EL2_RAM_BE(64, 44)
|
||||
`EL2_RAM_BE(32, 44)
|
||||
`EL2_RAM_BE(4096, 88)
|
||||
`EL2_RAM_BE(2048, 88)
|
||||
`EL2_RAM_BE(1024, 88)
|
||||
|
@ -231,8 +193,6 @@ endmodule
|
|||
`EL2_RAM_BE(256, 88)
|
||||
`EL2_RAM_BE(128, 88)
|
||||
`EL2_RAM_BE(64, 88)
|
||||
`EL2_RAM_BE(32, 88)
|
||||
`EL2_RAM(64, 39)
|
||||
|
||||
|
||||
`undef EL2_RAM
|
||||
|
@ -240,4 +200,3 @@ endmodule
|
|||
`undef EL2_LOCAL_RAM_TEST_IO
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -62,4 +62,3 @@ module el2_btb_ghr_hash #(
|
|||
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
)
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -2,417 +2,337 @@ package dbg
|
|||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import lib._
|
||||
import include._
|
||||
import lib._
|
||||
import dec._
|
||||
|
||||
class dbg_dma extends Bundle {
|
||||
val dbg_dma_bubble = Input(Bool()) // Debug needs a bubble to send a valid
|
||||
val dma_dbg_ready = Output(Bool()) // DMA is ready to accept debug request
|
||||
|
||||
}
|
||||
|
||||
object state_t {
|
||||
val idle = 0.U(4.W)
|
||||
val halting = 1.U(4.W)
|
||||
val halted = 2.U(4.W)
|
||||
val core_cmd_start = 3.U(4.W)
|
||||
val core_cmd_wait = 4.U(4.W)
|
||||
val sb_cmd_start = 5.U(4.W)
|
||||
val sb_cmd_send = 6.U(4.W)
|
||||
val sb_cmd_resp = 7.U(4.W)
|
||||
val cmd_done = 8.U(4.W)
|
||||
val resuming = 9.U(4.W)
|
||||
val idle = 0.U(3.W)
|
||||
val halting = 1.U(3.W)
|
||||
val halted = 2.U(3.W)
|
||||
val cmd_start = 3.U(3.W)
|
||||
val cmd_wait = 4.U(3.W)
|
||||
val cmd_done = 5.U(3.W)
|
||||
val resuming = 6.U(3.W)
|
||||
}
|
||||
|
||||
object sb_state_t {
|
||||
val sbidle = 0.U(4.W)
|
||||
val wait_rd = 1.U(4.W)
|
||||
val wait_wr = 2.U(4.W)
|
||||
val cmd_rd = 3.U(4.W)
|
||||
val cmd_wr = 4.U(4.W)
|
||||
val cmd_wr_addr = 5.U(4.W)
|
||||
val cmd_wr_data = 6.U(4.W)
|
||||
val rsp_rd = 7.U(4.W)
|
||||
val rsp_wr = 8.U(4.W)
|
||||
val done = 9.U(4.W)
|
||||
val sbidle = 0.U(4.W)
|
||||
val wait_rd = 1.U(4.W)
|
||||
val wait_wr = 2.U(4.W)
|
||||
val cmd_rd = 3.U(4.W)
|
||||
val cmd_wr = 4.U(4.W)
|
||||
val cmd_wr_addr = 5.U(4.W)
|
||||
val cmd_wr_data = 6.U(4.W)
|
||||
val rsp_rd = 7.U(4.W)
|
||||
val rsp_wr = 8.U(4.W)
|
||||
val done = 9.U(4.W)
|
||||
}
|
||||
|
||||
class dbg extends Module with lib with RequireAsyncReset {
|
||||
val io = IO(new Bundle {
|
||||
val dbg_cmd_size = Output(UInt(2.W))
|
||||
val dbg_core_rst_l = Output(Bool())
|
||||
val core_dbg_rddata = Input(UInt(32.W))
|
||||
val core_dbg_cmd_done = Input(Bool())
|
||||
val core_dbg_cmd_fail = Input(Bool())
|
||||
val dbg_halt_req = Output(Bool())
|
||||
val dbg_resume_req = Output(Bool())
|
||||
val dec_tlu_debug_mode = Input(Bool())
|
||||
val dec_tlu_dbg_halted = Input(Bool())
|
||||
val dec_tlu_mpc_halted_only = Input(Bool())
|
||||
val dec_tlu_resume_ack = Input(Bool())
|
||||
val dmi_reg_en = Input(Bool())
|
||||
val dmi_reg_addr = Input(UInt(7.W))
|
||||
val dmi_reg_wr_en = Input(Bool())
|
||||
val dmi_reg_wdata = Input(UInt(32.W))
|
||||
val dmi_reg_rdata = Output(UInt(32.W))
|
||||
|
||||
val dbg_cmd_size = Output(UInt(2.W))
|
||||
val dbg_core_rst_l = Output(Bool())
|
||||
val core_dbg_rddata = Input(UInt(32.W))
|
||||
val core_dbg_cmd_done = Input(Bool())
|
||||
val core_dbg_cmd_fail = Input(Bool())
|
||||
val dbg_halt_req = Output(Bool())
|
||||
val dbg_resume_req = Output(Bool())
|
||||
val dec_tlu_debug_mode = Input(Bool())
|
||||
val dec_tlu_dbg_halted = Input(Bool())
|
||||
val dec_tlu_mpc_halted_only = Input(Bool())
|
||||
val dec_tlu_resume_ack = Input(Bool())
|
||||
val dmi_reg_en = Input(Bool())
|
||||
val dmi_reg_addr = Input(UInt(7.W))
|
||||
val dmi_reg_wr_en = Input(Bool())
|
||||
val dmi_reg_wdata = Input(UInt(32.W))
|
||||
val dmi_reg_rdata = Output(UInt(32.W))
|
||||
val sb_axi = new axi_channels(SB_BUS_TAG)
|
||||
val dbg_dec_dma = Flipped(new dec_dbg)
|
||||
// val dbg_dma = Flipped(new dec_dbg)
|
||||
val dbg_dma = Flipped(new dbg_dma)
|
||||
|
||||
val dbg_bus_clk_en = Input(Bool())
|
||||
val dbg_rst_l = Input(AsyncReset())
|
||||
val clk_override = Input(Bool())
|
||||
val scan_mode = Input(Bool())
|
||||
val dbg_bus_clk_en = Input(Bool())
|
||||
val dbg_rst_l = Input(Bool())
|
||||
val clk_override = Input(Bool())
|
||||
val scan_mode = Input(Bool())
|
||||
})
|
||||
|
||||
val dbg_state = WireInit(state_t.idle)
|
||||
val dbg_state_en = WireInit(false.B)
|
||||
val sb_state = WireInit(sb_state_t.sbidle)
|
||||
val sb_state_en = WireInit(Bool(), false.B)
|
||||
val dmcontrol_reg = WireInit(0.U(32.W))
|
||||
val sbaddress0_reg = WireInit(0.U(32.W))
|
||||
val sbcs_sbbusy_wren = WireInit(false.B)
|
||||
val sbcs_sberror_wren = WireInit(false.B)
|
||||
val sb_bus_rdata = WireInit(0.U(64.W))
|
||||
val sbaddress0_reg_wren1 = WireInit(false.B)
|
||||
val dmstatus_reg = WireInit(0.U(32.W))
|
||||
val dmstatus_havereset = WireInit(false.B)
|
||||
val dmstatus_haveresetn = WireInit(false.B)
|
||||
val dmstatus_resumeack = WireInit(false.B)
|
||||
val dmstatus_unavail = WireInit(false.B)
|
||||
val dmstatus_running = WireInit(false.B)
|
||||
val dmstatus_halted = WireInit(false.B)
|
||||
val abstractcs_busy_wren = WireInit(false.B)
|
||||
val abstractcs_busy_din = WireInit(false.B)
|
||||
val sb_bus_cmd_read = WireInit(false.B)
|
||||
val sb_bus_cmd_write_addr = WireInit(false.B)
|
||||
val sb_bus_cmd_write_data = WireInit(false.B)
|
||||
val sb_bus_rsp_read = WireInit(false.B)
|
||||
val sb_bus_rsp_error = WireInit(false.B)
|
||||
val sb_bus_rsp_write = WireInit(false.B)
|
||||
val sbcs_sbbusy_din = WireInit(false.B)
|
||||
val sbcs_sberror_din = WireInit(0.U(3.W))
|
||||
val data1_reg = WireInit(0.U(32.W))
|
||||
val sbcs_reg = WireInit(0.U(32.W))
|
||||
val execute_command = WireInit(false.B)
|
||||
val command_reg = WireInit(0.U(32.W))
|
||||
val dbg_sb_bus_error = WireInit(false.B)
|
||||
val command_wren = WireInit(false.B)
|
||||
val command_din = WireInit(0.U(32.W))
|
||||
val dbg_cmd_next_addr = WireInit(0.U(32.W))
|
||||
val data0_reg_wren2 = WireInit(false.B)
|
||||
val sb_abmem_cmd_done_in = WireInit(false.B)
|
||||
val sb_abmem_data_done_in = WireInit(false.B)
|
||||
val sb_abmem_cmd_done_en = WireInit(false.B)
|
||||
val sb_abmem_data_done_en = WireInit(false.B)
|
||||
val abmem_addr_external = WireInit(false.B)
|
||||
val sb_cmd_pending = WireInit(false.B)
|
||||
val sb_abmem_cmd_write = WireInit(false.B)
|
||||
val abmem_addr_in_dccm_region = WireInit(false.B)
|
||||
val abmem_addr_in_iccm_region = WireInit(false.B)
|
||||
val abmem_addr_in_pic_region = WireInit(false.B)
|
||||
val sb_abmem_cmd_size = WireInit(0.U(4.W))
|
||||
val abstractcs_error_din = WireInit(0.U(3.W))
|
||||
val dmcontrol_wren_Q = WireInit(false.B)
|
||||
val abstractcs_reg = WireInit(2.U(32.W))
|
||||
val dbg_state = WireInit(state_t.idle)
|
||||
val dbg_state_en = WireInit(false.B)
|
||||
val sb_state = WireInit(sb_state_t.sbidle)
|
||||
val sb_state_en = WireInit(Bool(), false.B)
|
||||
val dmcontrol_reg = WireInit(0.U(32.W))
|
||||
val sbaddress0_reg = WireInit(0.U(32.W))
|
||||
val sbcs_sbbusy_wren = WireInit(false.B)
|
||||
val sbcs_sberror_wren = WireInit(false.B)
|
||||
val sb_bus_rdata = WireInit(0.U(64.W))
|
||||
val sbaddress0_reg_wren1 = WireInit(false.B)
|
||||
val dmstatus_reg = WireInit(0.U(32.W))
|
||||
val dmstatus_havereset = WireInit(false.B)
|
||||
val dmstatus_resumeack = WireInit(false.B)
|
||||
val dmstatus_unavail = WireInit(false.B)
|
||||
val dmstatus_running = WireInit(false.B)
|
||||
val dmstatus_halted = WireInit(false.B)
|
||||
val abstractcs_busy_wren = WireInit(false.B)
|
||||
val abstractcs_busy_din = WireInit(false.B)
|
||||
val sb_bus_cmd_read = WireInit(false.B)
|
||||
val sb_bus_cmd_write_addr = WireInit(false.B)
|
||||
val sb_bus_cmd_write_data = WireInit(false.B)
|
||||
val sb_bus_rsp_read = WireInit(false.B)
|
||||
val sb_bus_rsp_error = WireInit(false.B)
|
||||
val sb_bus_rsp_write = WireInit(false.B)
|
||||
val sbcs_sbbusy_din = WireInit(false.B)
|
||||
val sbcs_sberror_din = WireInit(0.U(3.W))
|
||||
val data1_reg = WireInit(0.U(32.W))
|
||||
val sbcs_reg = WireInit(0.U(32.W))
|
||||
|
||||
val dbg_free_clken = io.dmi_reg_en | execute_command | (dbg_state =/= state_t.idle) | dbg_state_en | io.dec_tlu_dbg_halted |
|
||||
io.dec_tlu_mpc_halted_only | io.dec_tlu_debug_mode | io.dbg_halt_req | io.clk_override
|
||||
val sb_free_clken = io.dmi_reg_en | execute_command | sb_state_en | (sb_state =/= sb_state_t.sbidle) | io.clk_override;
|
||||
val dbg_free_clken = io.dmi_reg_en | (dbg_state =/= state_t.idle) | dbg_state_en | io.dec_tlu_dbg_halted | io.clk_override
|
||||
val sb_free_clken = io.dmi_reg_en | sb_state_en | (sb_state =/= sb_state_t.sbidle) | io.clk_override;
|
||||
val dbg_free_clk = rvclkhdr(clock, dbg_free_clken, io.scan_mode) // dbg_free_cgc
|
||||
val sb_free_clk = rvclkhdr(clock, sb_free_clken, io.scan_mode) // sb_free_cgc
|
||||
|
||||
val dbg_free_clk = rvoclkhdr(clock, dbg_free_clken, io.scan_mode) // dbg_free_cgc
|
||||
val sb_free_clk = rvoclkhdr(clock, sb_free_clken, io.scan_mode) // sb_free_cgc
|
||||
val dbg_dm_rst_l = (io.dbg_rst_l.asBool() & (dmcontrol_reg(0) | io.scan_mode)).asAsyncReset()
|
||||
dontTouch(dbg_dm_rst_l)
|
||||
val rst_temp = (dbg_dm_rst_l.asBool() & reset.asBool()).asAsyncReset()
|
||||
dontTouch(rst_temp)
|
||||
|
||||
val dbg_dm_rst_l = (io.dbg_rst_l.asBool() & (dmcontrol_reg(0) | io.scan_mode)).asAsyncReset()
|
||||
io.dbg_core_rst_l := (!dmcontrol_reg(1)).asBool() | io.scan_mode
|
||||
val sbcs_wren = (io.dmi_reg_addr === "h38".U(7.W)) & io.dmi_reg_en & io.dmi_reg_wr_en & (sb_state === sb_state_t.sbidle)
|
||||
val sbcs_sbbusyerror_wren = (sbcs_wren & io.dmi_reg_wdata(22)) | (sbcs_reg(21) & io.dmi_reg_en & ((io.dmi_reg_wr_en &
|
||||
(io.dmi_reg_addr === "h39".U(7.W))) | (io.dmi_reg_addr === "h3c".U(7.W)) |
|
||||
(io.dmi_reg_addr === "h3d".U(7.W))))
|
||||
io.dbg_core_rst_l := (!dmcontrol_reg(1)).asBool()
|
||||
val sbcs_wren = (io.dmi_reg_addr === "h38".U) & io.dmi_reg_en & io.dmi_reg_wr_en & (sb_state === sb_state_t.sbidle)
|
||||
val sbcs_sbbusyerror_wren = (sbcs_wren & io.dmi_reg_wdata(22)) | ((sb_state =/= sb_state_t.sbidle) & io.dmi_reg_en &
|
||||
((io.dmi_reg_addr === "h39".U) | (io.dmi_reg_addr === "h3c".U) | (io.dmi_reg_addr === "h3d".U)))
|
||||
|
||||
val sbcs_sbbusyerror_din = (~(sbcs_wren & io.dmi_reg_wdata(22))).asUInt()
|
||||
val temp_sbcs_22 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(sbcs_sbbusyerror_din, 0.U, sbcs_sbbusyerror_wren)} // sbcs_sbbusyerror_reg
|
||||
val temp_sbcs_21 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(sbcs_sbbusy_din, 0.U, sbcs_sbbusy_wren)} // sbcs_sbbusy_reg
|
||||
val temp_sbcs_20 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(io.dmi_reg_wdata(20), 0.U, sbcs_wren)} // sbcs_sbreadonaddr_reg
|
||||
val temp_sbcs_19_15 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(Cat(io.dmi_reg_wdata(19), ~io.dmi_reg_wdata(18), io.dmi_reg_wdata(17, 15)), 0.U, sbcs_wren)} // sbcs_misc_reg
|
||||
val temp_sbcs_14_12 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(sbcs_sberror_din(2, 0), 0.U, sbcs_sberror_wren)} // sbcs_error_reg
|
||||
val sbcs_sbbusyerror_din = (~(sbcs_wren & io.dmi_reg_wdata(22))).asUInt()
|
||||
val temp_sbcs_22 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(sbcs_sbbusyerror_din, 0.U, sbcs_sbbusyerror_wren)
|
||||
} // sbcs_sbbusyerror_reg
|
||||
|
||||
sbcs_reg := Cat(1.U(3.W), 0.U(6.W), temp_sbcs_22, temp_sbcs_21, temp_sbcs_20, temp_sbcs_19_15(4), ~temp_sbcs_19_15(3),
|
||||
temp_sbcs_19_15(2,0), temp_sbcs_14_12, "h20".U(7.W), "b01111".U(5.W))
|
||||
val temp_sbcs_21 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(sbcs_sbbusy_din, 0.U, sbcs_sbbusy_wren)
|
||||
} // sbcs_sbbusy_reg
|
||||
|
||||
val sbcs_unaligned = (sbcs_reg(19, 17) === 1.U(3.W)) & sbaddress0_reg(0) |
|
||||
(sbcs_reg(19, 17) === 2.U(3.W)) & sbaddress0_reg(1, 0).orR |
|
||||
(sbcs_reg(19, 17) === 3.U(3.W)) & sbaddress0_reg(2, 0).orR
|
||||
val temp_sbcs_20 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(io.dmi_reg_wdata(20), 0.U, sbcs_wren)
|
||||
} // sbcs_sbreadonaddr_reg
|
||||
|
||||
val temp_sbcs_19_15 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(io.dmi_reg_wdata(19, 15), 0.U, sbcs_wren)
|
||||
} // sbcs_misc_reg
|
||||
|
||||
val temp_sbcs_14_12 = withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(sbcs_sberror_din(2, 0), 0.U, sbcs_sberror_wren)
|
||||
} // sbcs_error_reg
|
||||
sbcs_reg := Cat(1.U(3.W), 0.U(6.W), temp_sbcs_22, temp_sbcs_21, temp_sbcs_20, temp_sbcs_19_15, temp_sbcs_14_12, "h20".U(7.W), "b01111".U(5.W))
|
||||
|
||||
val sbcs_unaligned = (sbcs_reg(19, 17) === "b001".U(3.W)) & sbaddress0_reg(0) |
|
||||
(sbcs_reg(19, 17) === "b010".U(3.W)) & sbaddress0_reg(1, 0).orR |
|
||||
(sbcs_reg(19, 17) === "b011".U(3.W)) & sbaddress0_reg(2, 0).orR
|
||||
|
||||
val sbcs_illegal_size = sbcs_reg(19)
|
||||
val sbaddress0_incr = Fill(4, (sbcs_reg(19, 17) === 0.U(3.W))) & 1.U(4.W) | Fill(4, (sbcs_reg(19, 17) === 1.U(3.W))) & 2.U(4.W) |
|
||||
Fill(4, (sbcs_reg(19, 17) === 2.U(3.W))) & 4.U(4.W) | Fill(4, (sbcs_reg(19, 17) === 3.U(3.W))) & 8.U(4.W)
|
||||
val sbaddress0_incr = Fill(4, (sbcs_reg(19, 17) === "h0".U)) & "b0001".U(4.W) | Fill(4, (sbcs_reg(19, 17) === "h1".U)) & "b0010".U(4.W) |
|
||||
Fill(4, (sbcs_reg(19, 17) === "h2".U)) & "b0100".U(4.W) | Fill(4, (sbcs_reg(19, 17) === "h3".U)) & "b1000".U(4.W)
|
||||
|
||||
val sbdata0_reg_wren0 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h3c".U)
|
||||
val sbdata0_reg_wren1 = (sb_state === sb_state_t.rsp_rd) & sb_state_en & !sbcs_sberror_wren
|
||||
val sbdata0_reg_wren = sbdata0_reg_wren0 | sbdata0_reg_wren1
|
||||
val sbdata0_reg_wren = sbdata0_reg_wren0 | sbdata0_reg_wren1
|
||||
val sbdata1_reg_wren0 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h3d".U)
|
||||
val sbdata1_reg_wren1 = (sb_state === sb_state_t.rsp_rd) & sb_state_en & !sbcs_sberror_wren
|
||||
val sbdata1_reg_wren = sbdata1_reg_wren0 | sbdata1_reg_wren1
|
||||
val sbdata0_din = Fill(32, sbdata0_reg_wren0) & io.dmi_reg_wdata | Fill(32, sbdata0_reg_wren1) & sb_bus_rdata(31, 0)
|
||||
val sbdata1_din = Fill(32, sbdata1_reg_wren0) & io.dmi_reg_wdata | Fill(32, sbdata1_reg_wren1) & sb_bus_rdata(63, 32)
|
||||
val sbdata1_reg_wren = sbdata1_reg_wren0 | sbdata1_reg_wren1
|
||||
val sbdata0_din = Fill(32, sbdata0_reg_wren0) & io.dmi_reg_wdata |
|
||||
Fill(32, sbdata0_reg_wren1) & sb_bus_rdata(31, 0)
|
||||
|
||||
val sbdata0_reg = withReset(dbg_dm_rst_l) { rvdffe(sbdata0_din, sbdata0_reg_wren, clock, io.scan_mode)} // dbg_sbdata0_reg
|
||||
val sbdata1_reg = withReset(dbg_dm_rst_l) { rvdffe(sbdata1_din, sbdata1_reg_wren, clock, io.scan_mode)} // dbg_sbdata1_reg
|
||||
val sbdata1_din = Fill(32, sbdata1_reg_wren0) & io.dmi_reg_wdata |
|
||||
Fill(32, sbdata1_reg_wren1) & sb_bus_rdata(63, 32)
|
||||
|
||||
val sbaddress0_reg_wren0 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h39".U)
|
||||
val sbaddress0_reg_wren = sbaddress0_reg_wren0 | sbaddress0_reg_wren1
|
||||
val sbaddress0_reg_din = Fill(32, sbaddress0_reg_wren0) & io.dmi_reg_wdata |
|
||||
val sbdata0_reg = withReset(dbg_dm_rst_l) {
|
||||
rvdffe(sbdata0_din, sbdata0_reg_wren, clock, io.scan_mode)
|
||||
} // dbg_sbdata0_reg
|
||||
|
||||
val sbdata1_reg = withReset(dbg_dm_rst_l) {
|
||||
rvdffe(sbdata1_din, sbdata1_reg_wren, clock, io.scan_mode)
|
||||
} // dbg_sbdata1_reg
|
||||
|
||||
val sbaddress0_reg_wren0 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h39".U)
|
||||
val sbaddress0_reg_wren = sbaddress0_reg_wren0 | sbaddress0_reg_wren1
|
||||
val sbaddress0_reg_din = Fill(32, sbaddress0_reg_wren0) & io.dmi_reg_wdata |
|
||||
Fill(32, sbaddress0_reg_wren1) & (sbaddress0_reg + Cat(0.U(28.W), sbaddress0_incr))
|
||||
|
||||
sbaddress0_reg := withReset(dbg_dm_rst_l) { rvdffe(sbaddress0_reg_din, sbaddress0_reg_wren, clock, io.scan_mode)} // dbg_sbaddress0_reg
|
||||
sbaddress0_reg := withReset(dbg_dm_rst_l) {
|
||||
rvdffe(sbaddress0_reg_din, sbaddress0_reg_wren, clock, io.scan_mode)
|
||||
} // dbg_sbaddress0_reg
|
||||
|
||||
val sbreadonaddr_access = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h39".U) & sbcs_reg(20)
|
||||
val sbreadondata_access = io.dmi_reg_en & !io.dmi_reg_wr_en & (io.dmi_reg_addr === "h3c".U) & sbcs_reg(15)
|
||||
val sbdata0wr_access = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h3c".U)
|
||||
val dmcontrol_wren = (io.dmi_reg_addr === "h10".U) & io.dmi_reg_en & io.dmi_reg_wr_en
|
||||
val resumereq = (dmcontrol_reg(30) & !dmcontrol_reg(31) & dmcontrol_wren_Q).asBool()
|
||||
val sbdata0wr_access = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h3c".U)
|
||||
val dmcontrol_wren = (io.dmi_reg_addr === "h10".U) & io.dmi_reg_en & io.dmi_reg_wr_en
|
||||
val dm_temp = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(
|
||||
Cat(io.dmi_reg_wdata(31, 30), io.dmi_reg_wdata(28), io.dmi_reg_wdata(1)),
|
||||
0.U, dmcontrol_wren)
|
||||
} // dmcontrolff
|
||||
|
||||
val dm_temp = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(Cat(io.dmi_reg_wdata(31, 30), io.dmi_reg_wdata(28), io.dmi_reg_wdata(1)),0.U, dmcontrol_wren)} // dmcontrolff
|
||||
val dm_temp_0 = withClockAndReset(dbg_free_clk, io.dbg_rst_l) {
|
||||
RegEnable(io.dmi_reg_wdata(0), 0.U, dmcontrol_wren)} // dmcontrol_dmactive_ff
|
||||
val temp = Cat(dm_temp(3, 2), 0.U, dm_temp(1), 0.U(26.W), dm_temp(0), dm_temp_0)
|
||||
dmcontrol_reg := temp
|
||||
val dm_temp_0 = withClockAndReset(dbg_free_clk, io.dbg_rst_l.asAsyncReset()) {
|
||||
RegEnable(io.dmi_reg_wdata(0), 0.U, dmcontrol_wren)
|
||||
} // dmcontrol_dmactive_ff
|
||||
|
||||
dmcontrol_wren_Q := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
|
||||
RegNext(dmcontrol_wren, 0.U)} // dmcontrol_wrenff
|
||||
val temp = Cat(dm_temp(3, 2), 0.U, dm_temp(1), 0.U(26.W), dm_temp(0), dm_temp_0)
|
||||
dmcontrol_reg := temp
|
||||
|
||||
dmstatus_reg := Cat(0.U(12.W), Fill(2, dmstatus_havereset), Fill(2, dmstatus_resumeack), 0.U(2.W), Fill(2, dmstatus_unavail),
|
||||
Fill(2, dmstatus_running), Fill(2, dmstatus_halted), 1.U(1.W), 0.U(3.W), 2.U(4.W))
|
||||
val dmcontrol_wren_Q = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
|
||||
RegNext(dmcontrol_wren, 0.U)
|
||||
} // dmcontrol_wrenff
|
||||
|
||||
val dmstatus_resumeack_wren = (dbg_state === state_t.resuming) & io.dec_tlu_resume_ack | dmstatus_resumeack & resumereq & dmstatus_halted
|
||||
val dmstatus_resumeack_din = (dbg_state === state_t.resuming) & io.dec_tlu_resume_ack
|
||||
val dmstatus_haveresetn_wren = (io.dmi_reg_addr === "h10".U) & io.dmi_reg_wdata(28) & io.dmi_reg_en & io.dmi_reg_wr_en & dmcontrol_reg(0)
|
||||
dmstatus_havereset := ~dmstatus_haveresetn
|
||||
dmstatus_reg := Cat(0.U(12.W), Fill(2, dmstatus_havereset), Fill(2, dmstatus_resumeack), 0.U(2.W), Fill(2, dmstatus_unavail), Fill(2, dmstatus_running), Fill(2, dmstatus_halted), 1.U(1.W), 0.U(3.W), 2.U(4.W))
|
||||
|
||||
val temp_rst = reset.asBool()
|
||||
val dmstatus_resumeack_wren = (dbg_state === state_t.resuming) & io.dec_tlu_resume_ack | dmstatus_resumeack & !dmcontrol_reg(30)
|
||||
val dmstatus_resumeack_din = (dbg_state === state_t.resuming) & io.dec_tlu_resume_ack
|
||||
val dmstatus_havereset_wren = (io.dmi_reg_addr === "h10".U) & io.dmi_reg_wdata(1) & io.dmi_reg_en & io.dmi_reg_wr_en
|
||||
val dmstatus_havereset_rst = (io.dmi_reg_addr === "h10".U) & io.dmi_reg_wdata(28) & io.dmi_reg_en & io.dmi_reg_wr_en;
|
||||
val temp_rst = reset.asBool()
|
||||
dmstatus_unavail := (dmcontrol_reg(1) | !(temp_rst)).asBool()
|
||||
dmstatus_running := ~(dmstatus_unavail | dmstatus_halted)
|
||||
|
||||
dmstatus_resumeack := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(dmstatus_resumeack_din, 0.U, dmstatus_resumeack_wren.asBool())} // dmstatus_resumeack_reg
|
||||
dmstatus_halted := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
|
||||
RegNext(io.dec_tlu_dbg_halted & !io.dec_tlu_mpc_halted_only, 0.U)} // dmstatus_halted_reg
|
||||
dmstatus_haveresetn := withClock(dbg_free_clk) {
|
||||
RegEnable(true.B, 0.U, dmstatus_haveresetn_wren)} // dmstatus_haveresetn_reg
|
||||
RegEnable(dmstatus_resumeack_din, 0.U, dmstatus_resumeack_wren)
|
||||
} // dmstatus_resumeack_reg
|
||||
|
||||
val haltsum0_reg = Cat(0.U(31.W), dmstatus_halted)
|
||||
dmstatus_halted := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
|
||||
RegNext(io.dec_tlu_dbg_halted & !io.dec_tlu_mpc_halted_only, 0.U)
|
||||
} // dmstatus_halted_reg
|
||||
|
||||
val abstractcs_error_sel0 = abstractcs_reg(12) & ~(abstractcs_reg(10,8).orR) & io.dmi_reg_en & ((io.dmi_reg_wr_en & ((io.dmi_reg_addr === "h16".U(7.W)) |
|
||||
(io.dmi_reg_addr === "h17".U(7.W))) | (io.dmi_reg_addr === "h18".U(7.W))) | (io.dmi_reg_addr === 4.U(7.W)) |
|
||||
(io.dmi_reg_addr === 5.U(7.W)))
|
||||
val abstractcs_error_sel1 = execute_command & ~(abstractcs_reg(10,8).orR) &
|
||||
((!((command_reg(31,24) === 0.U(8.W)) | (command_reg(31,24) === 2.U(8.W)))) | // Illegal command
|
||||
(((command_reg(22,20) === 3.U(3.W)) | (command_reg(22))) & (command_reg(31,24) === 2.U(8.W))) | // Illegal abstract memory size (can't be DW or higher)
|
||||
((command_reg(22,20) =/= 2.U(3.W)) & ((command_reg(31,24) === 0.U(8.W)) & command_reg(17))) | // Illegal abstract reg size
|
||||
((command_reg(31,24) === 0.U(8.W)) & command_reg(18))) // postexec for abstract register access
|
||||
val abstractcs_error_sel2 = ((io.core_dbg_cmd_done & io.core_dbg_cmd_fail) | // exception from core
|
||||
(execute_command & (command_reg(31,24) === 0.U(8.W)) & // unimplemented regs
|
||||
(((command_reg(15,12) === 1.U(4.W)) & (command_reg(11,5) =/= 0.U(7.W))) | (command_reg(15,13) =/= 0.U(3.W))))) & ~(abstractcs_reg(10,8).orR)
|
||||
val abstractcs_error_sel3 = execute_command & (dbg_state =/= state_t.halted) & ~(abstractcs_reg(10,8).orR)
|
||||
val abstractcs_error_sel4 = dbg_sb_bus_error & io.dbg_bus_clk_en & ~(abstractcs_reg(10,8).orR) // sb bus error for abstract memory command
|
||||
val abstractcs_error_sel5 = execute_command & (command_reg(31,24) === 2.U(8.W)) & ~(abstractcs_reg(10,8).orR) &
|
||||
(((command_reg(22,20) === 1.U(3.W)) & data1_reg(0)) | ((command_reg(22,20) === 2.U(3.W)) & (data1_reg(1,0).orR))) //Unaligned address for abstract memory
|
||||
val abstractcs_error_sel6 = (io.dmi_reg_addr === "h16".U(7.W)) & io.dmi_reg_en & io.dmi_reg_wr_en
|
||||
dmstatus_havereset := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
|
||||
RegNext(Mux(dmstatus_havereset_wren, true.B, dmstatus_havereset) & !dmstatus_havereset_rst, false.B)
|
||||
} // dmstatus_havereset_reg
|
||||
|
||||
val haltsum0_reg = Cat(0.U(31.W), dmstatus_halted)
|
||||
val abstractcs_reg = WireInit(2.U(32.W))
|
||||
|
||||
val abstractcs_error_sel0 = abstractcs_reg(12) & io.dmi_reg_en & (io.dmi_reg_wr_en & ((io.dmi_reg_addr === "h16".U) | (io.dmi_reg_addr === "h17".U)) | (io.dmi_reg_addr === "h4".U))
|
||||
val abstractcs_error_sel1 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h17".U) & !((io.dmi_reg_wdata(31, 24) === 0.U) | (io.dmi_reg_wdata(31, 24) === "h2".U))
|
||||
val abstractcs_error_sel2 = io.core_dbg_cmd_done & io.core_dbg_cmd_fail
|
||||
val abstractcs_error_sel3 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h17".U) & !dmstatus_reg(9);
|
||||
val abstractcs_error_sel4 = (io.dmi_reg_addr === "h17".U) & io.dmi_reg_en & io.dmi_reg_wr_en &
|
||||
((io.dmi_reg_wdata(22, 20) =/= "b010".U(3.W)) | ((io.dmi_reg_wdata(31, 24) === "h2".U) && data1_reg(1, 0).orR))
|
||||
|
||||
val abstractcs_error_sel5 = (io.dmi_reg_addr === "h16".U) & io.dmi_reg_en & io.dmi_reg_wr_en
|
||||
val abstractcs_error_selor = abstractcs_error_sel0 | abstractcs_error_sel1 | abstractcs_error_sel2 | abstractcs_error_sel3 | abstractcs_error_sel4 | abstractcs_error_sel5
|
||||
val abstractcs_error_din = (Fill(3, abstractcs_error_sel0) & "b001".U(3.W)) |
|
||||
(Fill(3, abstractcs_error_sel1) & "b010".U(3.W)) |
|
||||
(Fill(3, abstractcs_error_sel2) & "b011".U(3.W)) |
|
||||
(Fill(3, abstractcs_error_sel3) & "b100".U(3.W)) |
|
||||
(Fill(3, abstractcs_error_sel4) & "b111".U(3.W)) |
|
||||
(Fill(3, abstractcs_error_sel5) & (~io.dmi_reg_wdata(10, 8)).asUInt() & abstractcs_reg(10, 8)) |
|
||||
(Fill(3, (~abstractcs_error_selor).asUInt()) & abstractcs_reg(10, 8))
|
||||
|
||||
val abs_temp_12 = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(abstractcs_busy_din, 0.U, abstractcs_busy_wren)
|
||||
} // dmabstractcs_busy_reg
|
||||
|
||||
abstractcs_error_din := MuxCase(abstractcs_reg(10,8), Array(
|
||||
abstractcs_error_sel0 -> 1.U(3.W),
|
||||
abstractcs_error_sel1 -> 2.U(3.W),
|
||||
abstractcs_error_sel2 -> 3.U(3.W),
|
||||
abstractcs_error_sel3 -> 4.U(3.W),
|
||||
abstractcs_error_sel4 -> 5.U(3.W),
|
||||
abstractcs_error_sel5 -> 7.U(3.W),
|
||||
abstractcs_error_sel6 -> (~io.dmi_reg_wdata(10,8) & abstractcs_reg(10,8))
|
||||
))
|
||||
val abs_temp_12 = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(abstractcs_busy_din, 0.U, abstractcs_busy_wren)} // dmabstractcs_busy_reg
|
||||
val abs_temp_10_8 = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
|
||||
RegNext(abstractcs_error_din, 0.U)} // dmabstractcs_error_reg
|
||||
RegNext(abstractcs_error_din(2, 0), 0.U)
|
||||
} // dmabstractcs_error_reg
|
||||
|
||||
abstractcs_reg := Cat(0.U(19.W), abs_temp_12, 0.U(1.W), abs_temp_10_8, 2.U(8.W))
|
||||
abstractcs_reg := Cat(0.U(19.W), abs_temp_12, 0.U(1.W), abs_temp_10_8, 2.U(8.W))
|
||||
|
||||
val abstractauto_reg_wren = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h18".U(7.W)) & !abstractcs_reg(12)
|
||||
val abstractauto_reg = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(io.dmi_reg_wdata(1,0), 0.U, abstractauto_reg_wren)} // dbg_abstractauto_reg
|
||||
val command_wren = (io.dmi_reg_addr === "h17".U) & io.dmi_reg_en & io.dmi_reg_wr_en & (dbg_state === state_t.halted)
|
||||
val command_din = Cat(io.dmi_reg_wdata(31, 24), 0.U(1.W), io.dmi_reg_wdata(22, 20), 0.U(3.W), io.dmi_reg_wdata(16, 0))
|
||||
val command_reg = withReset(dbg_dm_rst_l) {
|
||||
rvdffe(command_din, command_wren,clock,io.scan_mode)
|
||||
} // dmcommand_reg
|
||||
|
||||
val execute_command_ns = command_wren | (io.dmi_reg_en & !abstractcs_reg(12) & (((io.dmi_reg_addr === 4.U(7.W)) &
|
||||
abstractauto_reg(0)) | ((io.dmi_reg_addr === 5.U(7.W)) & abstractauto_reg(1))))
|
||||
command_wren := (io.dmi_reg_addr === "h17".U(7.W)) & io.dmi_reg_en & io.dmi_reg_wr_en
|
||||
val command_regno_wren = command_wren | ((command_reg(31,24) === 0.U(8.W)) & command_reg(19) & (dbg_state === state_t.cmd_done) &
|
||||
~(abstractcs_reg(10,8).orR)) // aarpostincrement
|
||||
val data0_reg_wren0 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h4".U) & (dbg_state === state_t.halted)
|
||||
val data0_reg_wren1 = io.core_dbg_cmd_done & (dbg_state === state_t.cmd_wait) & !command_reg(16)
|
||||
|
||||
val command_postexec_din = (io.dmi_reg_wdata(31,24) === 0.U(8.W)) & io.dmi_reg_wdata(18)
|
||||
val command_transfer_din = (io.dmi_reg_wdata(31,24) === 0.U(8.W)) & io.dmi_reg_wdata(17)
|
||||
val temp_command_din_31_16 = Cat(io.dmi_reg_wdata(31,24), 0.U, io.dmi_reg_wdata(22,19), command_postexec_din, command_transfer_din, io.dmi_reg_wdata(16))
|
||||
val temp_command_din_15_0 = Mux(command_wren, io.dmi_reg_wdata(15,0), dbg_cmd_next_addr(15,0))
|
||||
|
||||
command_din := Cat(temp_command_din_31_16, temp_command_din_15_0)
|
||||
execute_command := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
|
||||
RegNext(execute_command_ns, false.B)} // execute_commandff
|
||||
|
||||
val temp_command_reg_31_16 = withReset(dbg_dm_rst_l) {
|
||||
rvdffe(command_din(31,16), command_wren, clock, io.scan_mode)} // dmcommand_reg
|
||||
val temp_command_reg_15_0 = withReset(dbg_dm_rst_l) {
|
||||
rvdffe(command_din(15,0), command_regno_wren, clock, io.scan_mode)} // dmcommand_regno_reg
|
||||
|
||||
command_reg := Cat(temp_command_reg_31_16, temp_command_reg_15_0)
|
||||
|
||||
val data0_reg_wren0 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h4".U) & (dbg_state === state_t.halted) & !abstractcs_reg(12)
|
||||
val data0_reg_wren1 = io.core_dbg_cmd_done & (dbg_state === state_t.core_cmd_wait) & !command_reg(16)
|
||||
val data0_reg_wren = data0_reg_wren0 | data0_reg_wren1 | data0_reg_wren2
|
||||
|
||||
val data0_din = Fill(32, data0_reg_wren0) & io.dmi_reg_wdata |
|
||||
Fill(32, data0_reg_wren1) & io.core_dbg_rddata |
|
||||
Fill(32, data0_reg_wren2) & sb_bus_rdata(31,0)
|
||||
val data0_reg = withReset(dbg_dm_rst_l.asAsyncReset()) {
|
||||
rvdffe(data0_din, data0_reg_wren, clock, io.scan_mode)
|
||||
val data0_reg_wren = data0_reg_wren0 | data0_reg_wren1
|
||||
val data0_din = Fill(32, data0_reg_wren0) & io.dmi_reg_wdata | Fill(32, data0_reg_wren1) & io.core_dbg_rddata
|
||||
val data0_reg = withReset(dbg_dm_rst_l) {
|
||||
rvdffe(data0_din,data0_reg_wren,clock,io.scan_mode)
|
||||
} // dbg_data0_reg
|
||||
|
||||
val data1_reg_wren0 = (io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === 5.U(7.W)) & (dbg_state === state_t.halted)) & !abstractcs_reg(12)
|
||||
val data1_reg_wren1 = (dbg_state === state_t.cmd_done) & (command_reg(31,24) === 2.U(8.W)) & command_reg(19) & ~(abstractcs_reg(10,8).orR) // aampostincrement
|
||||
val data1_reg_wren = data1_reg_wren0 | data1_reg_wren1
|
||||
|
||||
val data1_din = Fill(32, data1_reg_wren0) & io.dmi_reg_wdata | Fill(32, data1_reg_wren1) & dbg_cmd_next_addr(31,0)
|
||||
data1_reg := withReset(dbg_dm_rst_l.asAsyncReset()) {
|
||||
rvdffe(data1_din, data1_reg_wren, clock, io.scan_mode)} // dbg_data1_reg
|
||||
val sb_abmem_cmd_done = withClockAndReset(dbg_free_clk, dbg_dm_rst_l){
|
||||
RegEnable(sb_abmem_cmd_done_in, false.B, sb_abmem_cmd_done_en)} // sb_abmem_cmd_doneff
|
||||
val sb_abmem_data_done = withClockAndReset(dbg_free_clk, dbg_dm_rst_l){
|
||||
RegEnable(sb_abmem_data_done_in, false.B, sb_abmem_data_done_en)} // sb_abmem_data_doneff
|
||||
val data1_reg_wren = (io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h5".U) & (dbg_state === state_t.halted))
|
||||
val data1_din = Fill(32, data1_reg_wren) & io.dmi_reg_wdata
|
||||
data1_reg := withReset(dbg_dm_rst_l) {
|
||||
rvdffe(data1_din, data1_reg_wren, clock, io.scan_mode)
|
||||
} // dbg_data1_reg
|
||||
|
||||
val dbg_nxtstate = WireInit(state_t.idle)
|
||||
dbg_nxtstate := state_t.idle
|
||||
dbg_state_en := false.B
|
||||
abstractcs_busy_wren := false.B
|
||||
abstractcs_busy_din := false.B
|
||||
io.dbg_halt_req := false.B
|
||||
io.dbg_resume_req := false.B
|
||||
dbg_sb_bus_error := false.B
|
||||
data0_reg_wren2 := false.B
|
||||
sb_abmem_cmd_done_in := false.B
|
||||
sb_abmem_data_done_in := false.B
|
||||
sb_abmem_cmd_done_en := false.B
|
||||
sb_abmem_data_done_en := false.B
|
||||
dbg_nxtstate := state_t.idle
|
||||
dbg_state_en := false.B
|
||||
abstractcs_busy_wren := false.B
|
||||
abstractcs_busy_din := false.B
|
||||
io.dbg_halt_req := false.B
|
||||
io.dbg_resume_req := false.B
|
||||
switch(dbg_state) {
|
||||
is(state_t.idle) {
|
||||
dbg_nxtstate := Mux(dmstatus_reg(9) | io.dec_tlu_mpc_halted_only, state_t.halted, state_t.halting)
|
||||
dbg_state_en := ((dmcontrol_reg(31) | dmstatus_reg(9) | io.dec_tlu_mpc_halted_only))
|
||||
io.dbg_halt_req := dmcontrol_reg(31).asBool()
|
||||
dbg_nxtstate := Mux(dmstatus_reg(9) | io.dec_tlu_mpc_halted_only, state_t.halted, state_t.halting)
|
||||
dbg_state_en := ((dmcontrol_reg(31) & !io.dec_tlu_debug_mode) | dmstatus_reg(9) | io.dec_tlu_mpc_halted_only) & !dmcontrol_reg(1)
|
||||
io.dbg_halt_req := (dmcontrol_reg(31) & !dmcontrol_reg(1)).asBool()
|
||||
}
|
||||
is(state_t.halting) {
|
||||
dbg_nxtstate := state_t.halted
|
||||
dbg_state_en := dmstatus_reg(9) | io.dec_tlu_mpc_halted_only
|
||||
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
|
||||
dbg_nxtstate := Mux(dmcontrol_reg(1), state_t.idle, state_t.halted)
|
||||
dbg_state_en := dmstatus_reg(9) | dmcontrol_reg(1)
|
||||
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31) & (~dmcontrol_reg(1)).asUInt()).asBool()
|
||||
}
|
||||
is(state_t.halted) {
|
||||
dbg_nxtstate := Mux(dmstatus_reg(9), Mux(resumereq, state_t.resuming, Mux((command_reg(31, 24) === 2.U(8.W)) & abmem_addr_external,
|
||||
state_t.sb_cmd_start, state_t.core_cmd_start)), Mux(dmcontrol_reg(31), state_t.halting, state_t.idle)) // This is MPC halted case
|
||||
dbg_state_en := dmstatus_reg(9) & resumereq | execute_command | !(dmstatus_reg(9) | io.dec_tlu_mpc_halted_only)
|
||||
|
||||
abstractcs_busy_wren := dbg_state_en & ((dbg_nxtstate === state_t.core_cmd_start) | (dbg_nxtstate === state_t.sb_cmd_start))
|
||||
abstractcs_busy_din := "b1".U
|
||||
io.dbg_resume_req := (dbg_state_en & (dbg_nxtstate === state_t.resuming)).asBool()
|
||||
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
|
||||
dbg_nxtstate := Mux(dmstatus_reg(9) & !dmcontrol_reg(1),
|
||||
Mux(dmcontrol_reg(30) & !dmcontrol_reg(31), state_t.resuming, state_t.cmd_start),
|
||||
Mux(dmcontrol_reg(31), state_t.halting, state_t.idle))
|
||||
dbg_state_en := dmstatus_reg(9) & dmcontrol_reg(30) & !dmcontrol_reg(31) & dmcontrol_wren_Q | command_wren |
|
||||
dmcontrol_reg(1) | !(dmstatus_reg(9) | io.dec_tlu_mpc_halted_only)
|
||||
abstractcs_busy_wren := dbg_state_en & (dbg_nxtstate === state_t.cmd_start)
|
||||
abstractcs_busy_din := "b1".U
|
||||
io.dbg_resume_req := (dbg_state_en & (dbg_nxtstate === state_t.resuming)).asBool()
|
||||
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31) & (~dmcontrol_reg(1)).asUInt()).asBool()
|
||||
}
|
||||
is(state_t.core_cmd_start) {
|
||||
dbg_nxtstate := Mux(abstractcs_reg(10, 8).orR | ((command_reg(31, 24) === 0.U(8.W)) & !command_reg(17)), state_t.cmd_done, state_t.core_cmd_wait)
|
||||
dbg_state_en := io.dbg_dec_dma.dbg_ib.dbg_cmd_valid | abstractcs_reg(10, 8).orR | ((command_reg(31, 24) === 0.U(8.W)) & !command_reg(17))
|
||||
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
|
||||
is(state_t.cmd_start) {
|
||||
dbg_nxtstate := Mux(dmcontrol_reg(1), state_t.idle, Mux(abstractcs_reg(10, 8).orR, state_t.cmd_done, state_t.cmd_wait))
|
||||
dbg_state_en := io.dbg_dec_dma.dbg_ib.dbg_cmd_valid | abstractcs_reg(10, 8).orR | dmcontrol_reg(1)
|
||||
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31) & (~dmcontrol_reg(1)).asUInt()).asBool()
|
||||
}
|
||||
is(state_t.core_cmd_wait) {
|
||||
dbg_nxtstate := state_t.cmd_done
|
||||
dbg_state_en := io.core_dbg_cmd_done
|
||||
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
|
||||
}
|
||||
is(state_t.sb_cmd_start) {
|
||||
dbg_nxtstate := Mux(abstractcs_reg(10, 8).orR, state_t.cmd_done, state_t.sb_cmd_send)
|
||||
dbg_state_en := (io.dbg_bus_clk_en & !sb_cmd_pending) | abstractcs_reg(10, 8).orR
|
||||
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
|
||||
}
|
||||
is(state_t.sb_cmd_send) {
|
||||
sb_abmem_cmd_done_in := true.B
|
||||
sb_abmem_data_done_in := true.B
|
||||
sb_abmem_cmd_done_en := (sb_bus_cmd_read | sb_bus_cmd_write_addr) & io.dbg_bus_clk_en
|
||||
sb_abmem_data_done_en := (sb_bus_cmd_read | sb_bus_cmd_write_data) & io.dbg_bus_clk_en
|
||||
dbg_nxtstate := state_t.sb_cmd_resp
|
||||
dbg_state_en := (sb_abmem_cmd_done | sb_abmem_cmd_done_en) & (sb_abmem_data_done | sb_abmem_data_done_en) & io.dbg_bus_clk_en
|
||||
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
|
||||
}
|
||||
is(state_t.sb_cmd_resp) {
|
||||
dbg_nxtstate := state_t.cmd_done
|
||||
dbg_state_en := (sb_bus_rsp_read | sb_bus_rsp_write) & io.dbg_bus_clk_en
|
||||
dbg_sb_bus_error := (sb_bus_rsp_read | sb_bus_rsp_write) & sb_bus_rsp_error & io.dbg_bus_clk_en
|
||||
data0_reg_wren2 := dbg_state_en & !sb_abmem_cmd_write & !dbg_sb_bus_error
|
||||
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
|
||||
is(state_t.cmd_wait) {
|
||||
dbg_nxtstate := Mux(dmcontrol_reg(1), state_t.idle, state_t.cmd_done)
|
||||
dbg_state_en := io.core_dbg_cmd_done | dmcontrol_reg(1)
|
||||
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31) & (~dmcontrol_reg(1)).asUInt()).asBool()
|
||||
}
|
||||
is(state_t.cmd_done) {
|
||||
dbg_nxtstate := state_t.halted
|
||||
dbg_state_en := true.B
|
||||
abstractcs_busy_wren := dbg_state_en
|
||||
abstractcs_busy_din := false.B
|
||||
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
|
||||
sb_abmem_cmd_done_in := false.B
|
||||
sb_abmem_data_done_in := false.B
|
||||
sb_abmem_cmd_done_en := true.B
|
||||
sb_abmem_data_done_en := true.B
|
||||
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
|
||||
dbg_nxtstate := Mux(dmcontrol_reg(1), state_t.idle, state_t.halted)
|
||||
dbg_state_en := true.B
|
||||
abstractcs_busy_wren := dbg_state_en
|
||||
abstractcs_busy_din := "b0".U
|
||||
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31) & (~dmcontrol_reg(1)).asUInt()).asBool()
|
||||
}
|
||||
is(state_t.resuming) {
|
||||
dbg_nxtstate := state_t.idle;
|
||||
dbg_state_en := dmstatus_reg(17)
|
||||
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31)).asBool()
|
||||
dbg_state_en := dmstatus_reg(17) | dmcontrol_reg(1)
|
||||
io.dbg_halt_req := (dmcontrol_wren_Q & dmcontrol_reg(31) & (~dmcontrol_reg(1)).asUInt()).asBool()
|
||||
}}
|
||||
|
||||
val dmi_reg_rdata_din = Fill(32, io.dmi_reg_addr === "h4".U(7.W)).asUInt & data0_reg |
|
||||
Fill(32, io.dmi_reg_addr === "h5".U(7.W)) & data1_reg |
|
||||
Fill(32, io.dmi_reg_addr === "h10".U(7.W)) & Cat(0.U(2.W), dmcontrol_reg(29), 0.U, dmcontrol_reg(27,0)) |
|
||||
Fill(32, io.dmi_reg_addr === "h11".U(7.W)) & dmstatus_reg |
|
||||
Fill(32, io.dmi_reg_addr === "h16".U(7.W)) & abstractcs_reg |
|
||||
Fill(32, io.dmi_reg_addr === "h17".U(7.W)) & command_reg |
|
||||
Fill(32, io.dmi_reg_addr === "h18".U(7.W)) & Cat(0.U(30.W), abstractauto_reg(1,0)) |
|
||||
Fill(32, io.dmi_reg_addr === "h40".U(7.W)) & haltsum0_reg |
|
||||
Fill(32, io.dmi_reg_addr === "h38".U(7.W)) & sbcs_reg |
|
||||
Fill(32, io.dmi_reg_addr === "h39".U(7.W)) & sbaddress0_reg |
|
||||
Fill(32, io.dmi_reg_addr === "h3c".U(7.W)) & sbdata0_reg |
|
||||
Fill(32, io.dmi_reg_addr === "h3d".U(7.W)) & sbdata1_reg
|
||||
val dmi_reg_rdata_din = Fill(32, io.dmi_reg_addr === "h4".U).asUInt & data0_reg | Fill(32, io.dmi_reg_addr === "h5".U) & data1_reg |
|
||||
Fill(32, io.dmi_reg_addr === "h10".U) & dmcontrol_reg | Fill(32, io.dmi_reg_addr === "h11".U) & dmstatus_reg |
|
||||
Fill(32, io.dmi_reg_addr === "h16".U) & abstractcs_reg | Fill(32, io.dmi_reg_addr === "h17".U) & command_reg |
|
||||
Fill(32, io.dmi_reg_addr === "h40".U) & haltsum0_reg | Fill(32, io.dmi_reg_addr === "h38".U) & sbcs_reg |
|
||||
Fill(32, io.dmi_reg_addr === "h39".U) & sbaddress0_reg | Fill(32, io.dmi_reg_addr === "h3c".U) & sbdata0_reg |
|
||||
Fill(32, io.dmi_reg_addr === "h3d".U) & sbdata1_reg
|
||||
|
||||
dbg_state := withClockAndReset(dbg_free_clk, (dbg_dm_rst_l.asBool() & temp_rst).asAsyncReset()) {
|
||||
RegEnable(dbg_nxtstate, 0.U, dbg_state_en)} // dbg_state_reg
|
||||
dbg_state := withClockAndReset(dbg_free_clk, rst_temp) {
|
||||
RegEnable(dbg_nxtstate, 0.U, dbg_state_en)
|
||||
} // dbg_state_reg
|
||||
|
||||
io.dmi_reg_rdata := withReset(dbg_dm_rst_l) {
|
||||
rvdffe(dmi_reg_rdata_din, io.dmi_reg_en, clock, io.scan_mode)} // dmi_rddata_reg
|
||||
|
||||
val abmem_addr = data1_reg
|
||||
val abmem_addr_core_local = (abmem_addr_in_dccm_region | abmem_addr_in_iccm_region | abmem_addr_in_pic_region)
|
||||
abmem_addr_external := !abmem_addr_core_local
|
||||
io.dmi_reg_rdata := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(dmi_reg_rdata_din, 0.U, io.dmi_reg_en)
|
||||
} // dmi_rddata_reg
|
||||
|
||||
abmem_addr_in_dccm_region := (abmem_addr(31,28) === DCCM_REGION.asUInt) & (DCCM_ENABLE==1).B
|
||||
abmem_addr_in_iccm_region := (abmem_addr(31,28) === ICCM_REGION.asUInt) & (ICCM_ENABLE==1).B
|
||||
abmem_addr_in_pic_region := (abmem_addr(31,28) === PIC_REGION.asUInt)
|
||||
|
||||
io.dbg_dec_dma.dbg_ib.dbg_cmd_addr := Mux((command_reg(31, 24) === "h2".U), data1_reg, Cat(0.U(20.W), command_reg(11, 0)))
|
||||
io.dbg_dec_dma.dbg_ib.dbg_cmd_addr := Mux((command_reg(31, 24) === "h2".U), Cat(data1_reg(31, 2), "b00".U(2.W)), Cat(0.U(20.W), command_reg(11, 0)))
|
||||
io.dbg_dec_dma.dbg_dctl.dbg_cmd_wrdata := data0_reg(31, 0)
|
||||
io.dbg_dec_dma.dbg_ib.dbg_cmd_valid := (dbg_state === state_t.core_cmd_start) & !((abstractcs_reg(10,8).orR) | ((command_reg(31,24) === 0.U(8.W)) & !command_reg(17)) |
|
||||
((command_reg(31,24) === 2.U(8.W)) & abmem_addr_external)) & io.dbg_dma.dma_dbg_ready
|
||||
io.dbg_dec_dma.dbg_ib.dbg_cmd_write := command_reg(16).asBool()
|
||||
io.dbg_dec_dma.dbg_ib.dbg_cmd_type := Mux((command_reg(31, 24) === "h2".U), "b10".U, Cat("b0".U, (command_reg(15, 12) === "b0".U)))
|
||||
io.dbg_cmd_size := command_reg(21, 20)
|
||||
|
||||
val dbg_cmd_addr_incr = Mux((command_reg(31,24) === 2.U(8.W)), (1.U(4.W) << sb_abmem_cmd_size(1,0)), 1.U(4.W))
|
||||
val dbg_cmd_curr_addr = Mux((command_reg(31,24) === 2.U(8.W)), data1_reg, Cat(0.U(16.W), command_reg(15,0)))
|
||||
dbg_cmd_next_addr := dbg_cmd_curr_addr + Cat(0.U(28.W), dbg_cmd_addr_incr)
|
||||
|
||||
io.dbg_dma.dbg_dma_bubble := ((dbg_state === state_t.core_cmd_start) & ~(abstractcs_reg(10, 8).orR) | (dbg_state === state_t.core_cmd_wait)).asBool()
|
||||
|
||||
sb_cmd_pending := (sb_state === sb_state_t.cmd_rd) | (sb_state === sb_state_t.cmd_wr) | (sb_state === sb_state_t.cmd_wr_addr) |
|
||||
(sb_state === sb_state_t.cmd_wr_data) | (sb_state === sb_state_t.rsp_rd) | (sb_state === sb_state_t.rsp_wr)
|
||||
val sb_abmem_cmd_pending = (dbg_state === state_t.sb_cmd_start) | (dbg_state === state_t.sb_cmd_send) | (dbg_state === state_t.sb_cmd_resp)
|
||||
io.dbg_dec_dma.dbg_ib.dbg_cmd_valid := ((dbg_state === state_t.cmd_start) & !(abstractcs_reg(10, 8).orR) & io.dbg_dma.dma_dbg_ready).asBool()
|
||||
io.dbg_dec_dma.dbg_ib.dbg_cmd_write := command_reg(16).asBool()
|
||||
io.dbg_dec_dma.dbg_ib.dbg_cmd_type := Mux((command_reg(31, 24) === "h2".U), "b10".U(2.W), Cat("b0".U, (command_reg(15, 12) === "b0".U)))
|
||||
io.dbg_cmd_size := command_reg(21, 20)
|
||||
io.dbg_dma.dbg_dma_bubble := ((dbg_state === state_t.cmd_start) & !(abstractcs_reg(10, 8).orR) | (dbg_state === state_t.cmd_wait)).asBool()
|
||||
|
||||
val sb_nxtstate = WireInit(sb_state_t.sbidle)
|
||||
sb_nxtstate := sb_state_t.sbidle
|
||||
|
@ -425,31 +345,30 @@ class dbg extends Module with lib with RequireAsyncReset {
|
|||
switch(sb_state) {
|
||||
is(sb_state_t.sbidle) {
|
||||
sb_nxtstate := Mux(sbdata0wr_access, sb_state_t.wait_wr, sb_state_t.wait_rd)
|
||||
sb_state_en := (sbdata0wr_access | sbreadondata_access | sbreadonaddr_access) & ~(sbcs_reg(14,12).orR) & !sbcs_reg(22)
|
||||
sb_state_en := sbdata0wr_access | sbreadondata_access | sbreadonaddr_access
|
||||
sbcs_sbbusy_wren := sb_state_en
|
||||
sbcs_sbbusy_din := true.B
|
||||
sbcs_sberror_wren := sbcs_wren & io.dmi_reg_wdata(14, 12).orR
|
||||
sbcs_sberror_din := ~io.dmi_reg_wdata(14, 12) & sbcs_reg(14, 12)
|
||||
}
|
||||
is(sb_state_t.wait_rd) {
|
||||
sb_nxtstate := Mux(sbcs_unaligned | sbcs_illegal_size, sb_state_t.done, sb_state_t.cmd_rd)
|
||||
sb_state_en := (io.dbg_bus_clk_en & !sb_abmem_cmd_pending) | sbcs_unaligned | sbcs_illegal_size
|
||||
sb_nxtstate := Mux(sbcs_unaligned | sbcs_illegal_size, sb_state_t.done, sb_state_t.cmd_rd)
|
||||
sb_state_en := io.dbg_bus_clk_en | sbcs_unaligned | sbcs_illegal_size
|
||||
sbcs_sberror_wren := sbcs_unaligned | sbcs_illegal_size
|
||||
sbcs_sberror_din := Mux(sbcs_unaligned, "b011".U(3.W), "b100".U(3.W))
|
||||
sbcs_sberror_din := Mux(sbcs_unaligned, "b011".U(3.W), "b100".U(3.W))
|
||||
}
|
||||
is(sb_state_t.wait_wr) {
|
||||
sb_nxtstate := Mux(sbcs_unaligned | sbcs_illegal_size, sb_state_t.done, sb_state_t.cmd_wr)
|
||||
sb_state_en := (io.dbg_bus_clk_en & !sb_abmem_cmd_pending) | sbcs_unaligned | sbcs_illegal_size
|
||||
sb_nxtstate := Mux(sbcs_unaligned | sbcs_illegal_size, sb_state_t.done, sb_state_t.cmd_wr)
|
||||
sb_state_en := io.dbg_bus_clk_en | sbcs_unaligned | sbcs_illegal_size
|
||||
sbcs_sberror_wren := sbcs_unaligned | sbcs_illegal_size;
|
||||
sbcs_sberror_din := Mux(sbcs_unaligned, "b011".U(3.W), "b100".U(3.W))
|
||||
sbcs_sberror_din := Mux(sbcs_unaligned, "b011".U(3.W), "b100".U)
|
||||
}
|
||||
is(sb_state_t.cmd_rd) {
|
||||
sb_nxtstate := sb_state_t.rsp_rd
|
||||
sb_state_en := sb_bus_cmd_read & io.dbg_bus_clk_en
|
||||
}
|
||||
is(sb_state_t.cmd_wr) {
|
||||
sb_nxtstate := Mux(sb_bus_cmd_write_addr & sb_bus_cmd_write_data, sb_state_t.rsp_wr,
|
||||
Mux(sb_bus_cmd_write_data, sb_state_t.cmd_wr_addr, sb_state_t.cmd_wr_data))
|
||||
sb_nxtstate := Mux(sb_bus_cmd_write_addr & sb_bus_cmd_write_data, sb_state_t.rsp_wr, Mux(sb_bus_cmd_write_data, sb_state_t.cmd_wr_addr, sb_state_t.cmd_wr_data))
|
||||
sb_state_en := (sb_bus_cmd_write_addr | sb_bus_cmd_write_data) & io.dbg_bus_clk_en
|
||||
}
|
||||
is(sb_state_t.cmd_wr_addr) {
|
||||
|
@ -477,88 +396,64 @@ class dbg extends Module with lib with RequireAsyncReset {
|
|||
sb_state_en := true.B
|
||||
sbcs_sbbusy_wren := true.B
|
||||
sbcs_sbbusy_din := false.B
|
||||
sbaddress0_reg_wren1 := sbcs_reg(16) & (sbcs_reg(14,12) === 0.U(3.W))
|
||||
sbaddress0_reg_wren1 := sbcs_reg(16)
|
||||
}}
|
||||
|
||||
sb_state := withClockAndReset(sb_free_clk, dbg_dm_rst_l.asAsyncReset()) {
|
||||
sb_state := withClockAndReset(sb_free_clk, dbg_dm_rst_l) {
|
||||
RegEnable(sb_nxtstate, 0.U, sb_state_en)
|
||||
} // sb_state_reg
|
||||
|
||||
sb_abmem_cmd_write := command_reg(16)
|
||||
sb_abmem_cmd_size := Cat(0.U(1.W), command_reg(21,20))
|
||||
val sb_abmem_cmd_addr = abmem_addr
|
||||
val sb_abmem_cmd_wdata = data0_reg
|
||||
|
||||
val sb_cmd_size = sbcs_reg(19,17)
|
||||
val sb_cmd_wdata = Cat(sbdata1_reg(31,0), sbdata0_reg(31,0))
|
||||
val sb_cmd_addr = sbaddress0_reg(31,0)
|
||||
|
||||
val sb_abmem_cmd_awvalid = (dbg_state === state_t.sb_cmd_send) & sb_abmem_cmd_write & !sb_abmem_cmd_done
|
||||
val sb_abmem_cmd_wvalid = (dbg_state === state_t.sb_cmd_send) & sb_abmem_cmd_write & !sb_abmem_data_done
|
||||
val sb_abmem_cmd_arvalid = (dbg_state === state_t.sb_cmd_send) & !sb_abmem_cmd_write & !sb_abmem_cmd_done & !sb_abmem_data_done
|
||||
val sb_abmem_read_pend = (dbg_state === state_t.sb_cmd_resp) & !sb_abmem_cmd_write
|
||||
|
||||
val sb_cmd_awvalid = ((sb_state === sb_state_t.cmd_wr) | (sb_state === sb_state_t.cmd_wr_addr))
|
||||
val sb_cmd_wvalid = ((sb_state === sb_state_t.cmd_wr) | (sb_state === sb_state_t.cmd_wr_data))
|
||||
val sb_cmd_arvalid = (sb_state === sb_state_t.cmd_rd)
|
||||
val sb_read_pend = (sb_state === sb_state_t.cmd_rd)
|
||||
|
||||
val sb_axi_size = Mux((sb_abmem_cmd_awvalid | sb_abmem_cmd_wvalid | sb_abmem_cmd_arvalid | sb_abmem_read_pend), sb_abmem_cmd_size(2,0), sb_cmd_size(2,0))
|
||||
val sb_axi_addr = Mux((sb_abmem_cmd_awvalid | sb_abmem_cmd_wvalid | sb_abmem_cmd_arvalid | sb_abmem_read_pend), sb_abmem_cmd_addr(31,0), sb_cmd_addr(31,0))
|
||||
val sb_axi_wrdata = Mux((sb_abmem_cmd_awvalid | sb_abmem_cmd_wvalid), Fill(2, sb_abmem_cmd_wdata(31,0)), sb_cmd_wdata(63,0))
|
||||
|
||||
sb_bus_cmd_read := io.sb_axi.ar.valid & io.sb_axi.ar.ready
|
||||
sb_bus_cmd_read := io.sb_axi.ar.valid & io.sb_axi.ar.ready
|
||||
sb_bus_cmd_write_addr := io.sb_axi.aw.valid & io.sb_axi.aw.ready
|
||||
sb_bus_cmd_write_data := io.sb_axi.w.valid & io.sb_axi.w.ready
|
||||
sb_bus_rsp_read := io.sb_axi.r.valid & io.sb_axi.r.ready
|
||||
sb_bus_rsp_write := io.sb_axi.b.valid & io.sb_axi.b.ready
|
||||
sb_bus_rsp_error := sb_bus_rsp_read & io.sb_axi.r.bits.resp(1, 0).orR | sb_bus_rsp_write & io.sb_axi.b.bits.resp(1, 0).orR
|
||||
sb_bus_rsp_read := io.sb_axi.r.valid & io.sb_axi.r.ready
|
||||
sb_bus_rsp_write := io.sb_axi.b.valid & io.sb_axi.b.ready
|
||||
sb_bus_rsp_error := sb_bus_rsp_read & io.sb_axi.r.bits.resp(1, 0).orR | sb_bus_rsp_write & io.sb_axi.b.bits.resp(1, 0).orR
|
||||
io.sb_axi.aw.valid := ((sb_state === sb_state_t.cmd_wr) | (sb_state === sb_state_t.cmd_wr_addr)).asBool()
|
||||
io.sb_axi.aw.bits.addr := sbaddress0_reg
|
||||
io.sb_axi.aw.bits.id := 0.U
|
||||
io.sb_axi.aw.bits.size := sbcs_reg(19, 17)
|
||||
io.sb_axi.aw.bits.prot := 0.U
|
||||
io.sb_axi.aw.bits.cache := "b1111".U
|
||||
io.sb_axi.aw.bits.region := sbaddress0_reg(31, 28)
|
||||
io.sb_axi.aw.bits.len := 0.U
|
||||
io.sb_axi.aw.bits.burst := "b01".U(2.W)
|
||||
io.sb_axi.aw.bits.qos := 0.U
|
||||
io.sb_axi.aw.bits.lock := false.B
|
||||
io.sb_axi.w.valid := ((sb_state === sb_state_t.cmd_wr) | (sb_state === sb_state_t.cmd_wr_data)).asBool()
|
||||
io.sb_axi.w.bits.data := Fill(64, (sbcs_reg(19, 17) === 0.U)) & Fill(8, (sbdata0_reg(7, 0))) | Fill(64, (sbcs_reg(19, 17) === "h1".U)) & Fill(4, sbdata0_reg(15, 0)) |
|
||||
Fill(64, (sbcs_reg(19, 17) === "h2".U)) & Fill(2, (sbdata0_reg(31, 0))) | Fill(64, (sbcs_reg(19, 17) === "h3".U)) & Cat(sbdata1_reg(31, 0), sbdata0_reg(31, 0))
|
||||
|
||||
io.sb_axi.aw.valid := sb_abmem_cmd_awvalid | sb_cmd_awvalid
|
||||
io.sb_axi.aw.bits.addr := sb_axi_addr
|
||||
io.sb_axi.aw.bits.id := 0.U
|
||||
io.sb_axi.aw.bits.size := sb_axi_size
|
||||
io.sb_axi.aw.bits.prot := 1.U(3.W)
|
||||
io.sb_axi.aw.bits.cache := "b1111".U(4.W)
|
||||
io.sb_axi.aw.bits.region := sb_axi_addr(31, 28)
|
||||
io.sb_axi.aw.bits.len := 0.U
|
||||
io.sb_axi.aw.bits.burst := "b01".U(2.W)
|
||||
io.sb_axi.aw.bits.qos := 0.U
|
||||
io.sb_axi.aw.bits.lock := false.B
|
||||
|
||||
io.sb_axi.w.valid := sb_abmem_cmd_wvalid | sb_cmd_wvalid
|
||||
io.sb_axi.w.bits.data := Fill(64, (sb_axi_size === 0.U(3.W))) & Fill(8, (sb_axi_wrdata(7, 0))) |
|
||||
Fill(64, (sb_axi_size === 1.U(3.W))) & Fill(4, sb_axi_wrdata(15, 0)) |
|
||||
Fill(64, (sb_axi_size === 2.U(3.W))) & Fill(2, (sb_axi_wrdata(31, 0))) |
|
||||
Fill(64, (sb_axi_size === 3.U(3.W))) & sb_axi_wrdata
|
||||
|
||||
io.sb_axi.w.bits.strb := Fill(8, (sb_axi_size === 0.U(3.W))) & ("h1".U(8.W) << sb_axi_addr(2, 0)) |
|
||||
Fill(8, (sb_axi_size === 1.U(3.W))) & ("h3".U(8.W) << Cat(sb_axi_addr(2, 1), 0.U(1.W))) |
|
||||
Fill(8, (sb_axi_size === 2.U(3.W))) & ("hf".U(8.W) << Cat(sb_axi_addr(2), 0.U(2.W))) |
|
||||
Fill(8, (sb_axi_size === 3.U(3.W))) & "hff".U(8.W)
|
||||
|
||||
io.sb_axi.w.bits.last := true.B
|
||||
io.sb_axi.ar.valid := sb_abmem_cmd_arvalid | sb_cmd_arvalid
|
||||
io.sb_axi.ar.bits.addr := sb_axi_addr
|
||||
io.sb_axi.ar.bits.id := 0.U
|
||||
io.sb_axi.ar.bits.size := sb_axi_size
|
||||
io.sb_axi.ar.bits.prot := 1.U(3.W)
|
||||
io.sb_axi.ar.bits.cache := 0.U(4.W)
|
||||
io.sb_axi.ar.bits.region := sb_axi_addr(31, 28)
|
||||
io.sb_axi.ar.bits.len := 0.U
|
||||
io.sb_axi.ar.bits.burst := 1.U(2.W)
|
||||
io.sb_axi.ar.bits.qos := 0.U
|
||||
io.sb_axi.ar.bits.lock := false.B
|
||||
io.sb_axi.w.bits.strb := Fill(8, (sbcs_reg(19, 17) === "h0".U)) & ("h1".U(8.W) << sbaddress0_reg(2, 0)) |
|
||||
Fill(8, (sbcs_reg(19, 17) === "h1".U)) & ("h3".U(8.W) << Cat(sbaddress0_reg(2, 1), "b0".U)) |
|
||||
Fill(8, (sbcs_reg(19, 17) === "h2".U)) & ("hf".U(8.W) << Cat(sbaddress0_reg(2), "b00".U(2.W))) |
|
||||
Fill(8, (sbcs_reg(19, 17) === "h3".U)) & "hff".U
|
||||
|
||||
io.sb_axi.w.bits.last := true.B
|
||||
io.sb_axi.ar.valid := (sb_state === sb_state_t.cmd_rd).asBool()
|
||||
io.sb_axi.ar.bits.addr := sbaddress0_reg
|
||||
io.sb_axi.ar.bits.id := 0.U
|
||||
io.sb_axi.ar.bits.size := sbcs_reg(19, 17)
|
||||
io.sb_axi.ar.bits.prot := 0.U
|
||||
io.sb_axi.ar.bits.cache := 0.U
|
||||
io.sb_axi.ar.bits.region := sbaddress0_reg(31, 28)
|
||||
io.sb_axi.ar.bits.len := 0.U
|
||||
io.sb_axi.ar.bits.burst := "b01".U(2.W)
|
||||
io.sb_axi.ar.bits.qos := 0.U
|
||||
io.sb_axi.ar.bits.lock := false.B
|
||||
io.sb_axi.b.ready := true.B
|
||||
io.sb_axi.r.ready := true.B
|
||||
sb_bus_rdata := Fill(64, (sbcs_reg(19, 17) === "h0".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 8.U * sbaddress0_reg(2, 0)) & "hff".U(64.W)) |
|
||||
Fill(64, (sbcs_reg(19, 17) === "h1".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 16.U * sbaddress0_reg(2, 1)) & "hffff".U(64.W)) |
|
||||
Fill(64, (sbcs_reg(19, 17) === "h2".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 32.U * sbaddress0_reg(2)) & "hffff_ffff".U(64.W)) |
|
||||
Fill(64, (sbcs_reg(19, 17) === "h3".U)) & io.sb_axi.r.bits.data(63, 0)
|
||||
|
||||
sb_bus_rdata := Fill(64, (sb_axi_size === "h0".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 8.U * sb_axi_addr(2, 0)) & "hff".U(64.W)) |
|
||||
Fill(64, (sb_axi_size === "h1".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 16.U * sb_axi_addr(2, 1)) & "hffff".U(64.W)) |
|
||||
Fill(64, (sb_axi_size === "h2".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 32.U * sb_axi_addr(2)) & "hffff_ffff".U(64.W)) |
|
||||
Fill(64, (sb_axi_size === "h3".U)) & io.sb_axi.r.bits.data(63, 0)
|
||||
|
||||
// io.dbg_dma.dbg_ib.dbg_cmd_addr := io.dbg_dec_dma.dbg_ib.dbg_cmd_addr
|
||||
// io.dbg_dma.dbg_dctl.dbg_cmd_wrdata := io.dbg_dec_dma.dbg_dctl.dbg_cmd_wrdata
|
||||
// io.dbg_dma.dbg_ib.dbg_cmd_valid := io.dbg_dec_dma.dbg_ib.dbg_cmd_valid
|
||||
// io.dbg_dma.dbg_ib.dbg_cmd_write := io.dbg_dec_dma.dbg_ib.dbg_cmd_write
|
||||
// io.dbg_dma.dbg_ib.dbg_cmd_type := io.dbg_dec_dma.dbg_ib.dbg_cmd_type
|
||||
}
|
||||
|
||||
object debug extends App {
|
||||
(new chisel3.stage.ChiselStage).emitVerilog(new dbg)
|
||||
}
|
||||
|
||||
|
|
|
@ -8,16 +8,12 @@ import lsu._
|
|||
class dec_IO extends Bundle with lib {
|
||||
val free_clk = Input(Clock())
|
||||
val active_clk = Input(Clock())
|
||||
val free_l2clk = Input(Clock())
|
||||
val lsu_fastint_stall_any = Input(Bool()) // needed by lsu for 2nd pass of dma with ecc correction, stall next cycle
|
||||
val dec_pause_state_cg = Output(Bool()) // to top for active state clock gating
|
||||
val dec_tlu_core_empty = Output(Bool())
|
||||
val rst_vec = Input(UInt(31.W)) // [31:1] reset vector, from core pins
|
||||
val ifu_i0_fa_index = Input(UInt(log2Ceil(BTB_SIZE).W))
|
||||
val dec_fa_error_index = Output(UInt(log2Ceil(BTB_SIZE).W))
|
||||
|
||||
val nmi_int = Input(Bool()) // NMI pin
|
||||
val nmi_vec = Input(UInt(31.W)) // [31:1] NMI vector, from pins
|
||||
val lsu_nonblock_load_data = Input(UInt(32.W))
|
||||
|
||||
val i_cpu_halt_req = Input(Bool()) // Asynchronous Halt request to CPU
|
||||
val i_cpu_run_req = Input(Bool()) // Asynchronous Restart request to CPU
|
||||
|
@ -70,7 +66,6 @@ class dec_IO extends Bundle with lib {
|
|||
val dec_tlu_resume_ack = Output(Bool()) // Resume acknowledge
|
||||
val dec_tlu_mpc_halted_only = Output(Bool()) // Core is halted only due to MPC
|
||||
val dec_dbg_rddata = Output(UInt(32.W)) // debug command read data
|
||||
val dec_csr_rddata_d = Output(UInt(32.W))
|
||||
|
||||
val dec_dbg_cmd_done = Output(Bool()) // abstract command is done
|
||||
val dec_dbg_cmd_fail = Output(Bool()) // abstract command failed (illegal reg address)
|
||||
|
@ -84,9 +79,8 @@ class dec_IO extends Bundle with lib {
|
|||
val dec_tlu_perfcnt1 = Output(Bool()) // toggles when slot0 perf counter 1 has an event inc
|
||||
val dec_tlu_perfcnt2 = Output(Bool()) // toggles when slot0 perf counter 2 has an event inc
|
||||
val dec_tlu_perfcnt3 = Output(Bool()) // toggles when slot0 perf counter 3 has an event inc
|
||||
val dec_tlu_flush_lower_wb = Output(Bool())
|
||||
val dec_lsu_valid_raw_d = Output(Bool())
|
||||
val trace_rv_trace_pkt = Output(new trace_pkt_t) // trace packet
|
||||
val rv_trace_pkt = (new trace_pkt_t) // trace packet
|
||||
|
||||
// clock gating overrides from mcgc
|
||||
val dec_tlu_misc_clk_override = Output(Bool()) // override misc clock domain gating
|
||||
|
@ -94,12 +88,9 @@ class dec_IO extends Bundle with lib {
|
|||
val dec_tlu_lsu_clk_override = Output(Bool()) // override load/store clock domain gating
|
||||
val dec_tlu_bus_clk_override = Output(Bool()) // override bus clock domain gating
|
||||
val dec_tlu_pic_clk_override = Output(Bool()) // override PIC clock domain gating
|
||||
val dec_tlu_picio_clk_override = Output(Bool())
|
||||
val dec_tlu_dccm_clk_override = Output(Bool()) // override DCCM clock domain gating
|
||||
val dec_tlu_icm_clk_override = Output(Bool()) // override ICCM clock domain gating
|
||||
|
||||
val dec_i0_decode_d = Output(Bool())
|
||||
|
||||
val scan_mode = Input(Bool())
|
||||
val ifu_dec = Flipped(new ifu_dec)
|
||||
val dec_exu = Flipped(new dec_exu)
|
||||
|
@ -120,10 +111,6 @@ class dec extends Module with param with RequireAsyncReset{
|
|||
val dec_tlu_exc_cause_wb1 = WireInit(UInt(5.W),0.U)
|
||||
val dec_tlu_mtval_wb1 = WireInit(UInt(32.W),0.U)
|
||||
val dec_tlu_i0_exc_valid_wb1 = WireInit(Bool(),0.B)
|
||||
val dec_tlu_trace_disable = WireInit(Bool(),0.B)
|
||||
// val dec_i0_bp_fa_index = WireInit(UInt(log2Ceil(BTB_SIZE).W),0.U)
|
||||
//val dec_debug_valid_d = WireInit(Bool(),0.B)
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------//
|
||||
|
@ -138,20 +125,17 @@ class dec extends Module with param with RequireAsyncReset{
|
|||
instbuff.io.ifu_ib <> io.ifu_dec.dec_aln.aln_ib
|
||||
instbuff.io.ib_exu <> io.dec_exu.ib_exu
|
||||
instbuff.io.dbg_ib <> io.dec_dbg.dbg_ib
|
||||
instbuff.io.ifu_i0_fa_index := io.ifu_i0_fa_index
|
||||
dec_trigger.io.dec_i0_pc_d := instbuff.io.ib_exu.dec_i0_pc_d
|
||||
dec_trigger.io.trigger_pkt_any := tlu.io.trigger_pkt_any
|
||||
|
||||
val dec_i0_trigger_match_d = dec_trigger.io.dec_i0_trigger_match_d
|
||||
dontTouch(dec_i0_trigger_match_d)
|
||||
decode.io.dec_aln <> io.ifu_dec.dec_aln.aln_dec
|
||||
io.dec_i0_decode_d := decode.io.dec_i0_decode_d
|
||||
|
||||
decode.io.decode_exu<> io.dec_exu.decode_exu
|
||||
decode.io.dec_alu<> io.dec_exu.dec_alu
|
||||
decode.io.dec_div<> io.dec_exu.dec_div
|
||||
decode.io.dctl_dma <> io.dec_dma.dctl_dma
|
||||
decode.io.dec_tlu_trace_disable := tlu.io.dec_tlu_trace_disable
|
||||
decode.io.dec_debug_valid_d := instbuff.io.dec_debug_valid_d
|
||||
decode.io.dec_tlu_flush_extint := tlu.io.dec_tlu_flush_extint
|
||||
decode.io.dec_tlu_force_halt := tlu.io.tlu_mem.dec_tlu_force_halt
|
||||
decode.io.dctl_busbuff <> io.lsu_dec.dctl_busbuff
|
||||
|
@ -161,18 +145,18 @@ class dec extends Module with param with RequireAsyncReset{
|
|||
decode.io.lsu_trigger_match_m := io.lsu_trigger_match_m
|
||||
decode.io.lsu_pmu_misaligned_m := io.lsu_pmu_misaligned_m
|
||||
decode.io.dec_tlu_debug_stall := tlu.io.dec_tlu_debug_stall
|
||||
decode.io.dec_i0_bp_fa_index := instbuff.io.dec_i0_bp_fa_index
|
||||
decode.io.dec_tlu_flush_leak_one_r := tlu.io.tlu_bp.dec_tlu_flush_leak_one_wb
|
||||
decode.io.dec_debug_fence_d := instbuff.io.dec_debug_fence_d
|
||||
decode.io.dbg_dctl <> io.dec_dbg.dbg_dctl
|
||||
decode.io.dec_i0_icaf_d := instbuff.io.dec_i0_icaf_d
|
||||
decode.io.dec_i0_icaf_second_d := instbuff.io.dec_i0_icaf_second_d
|
||||
decode.io.dec_i0_icaf_f1_d := instbuff.io.dec_i0_icaf_f1_d
|
||||
decode.io.dec_i0_icaf_type_d := instbuff.io.dec_i0_icaf_type_d
|
||||
decode.io.dec_i0_dbecc_d := instbuff.io.dec_i0_dbecc_d
|
||||
decode.io.dec_i0_brp := instbuff.io.dec_i0_brp
|
||||
decode.io.dec_i0_bp_index := instbuff.io.dec_i0_bp_index
|
||||
decode.io.dec_i0_bp_fghr := instbuff.io.dec_i0_bp_fghr
|
||||
decode.io.dec_i0_bp_btag := instbuff.io.dec_i0_bp_btag
|
||||
decode.io.dec_i0_pc_d := instbuff.io.ib_exu.dec_i0_pc_d
|
||||
decode.io.lsu_idle_any := io.lsu_idle_any
|
||||
decode.io.lsu_load_stall_any := io.lsu_load_stall_any
|
||||
decode.io.lsu_store_stall_any := io.lsu_store_stall_any
|
||||
|
@ -192,19 +176,16 @@ class dec extends Module with param with RequireAsyncReset{
|
|||
decode.io.exu_flush_final := io.exu_flush_final
|
||||
decode.io.dec_i0_instr_d := instbuff.io.dec_i0_instr_d
|
||||
decode.io.dec_ib0_valid_d := instbuff.io.dec_ib0_valid_d
|
||||
decode.io.free_l2clk := io.free_l2clk
|
||||
decode.io.free_clk := io.free_clk
|
||||
decode.io.active_clk := io.active_clk
|
||||
decode.io.clk_override := tlu.io.dec_tlu_dec_clk_override
|
||||
decode.io.scan_mode := io.scan_mode
|
||||
dec_i0_inst_wb1 := decode.io.dec_i0_inst_wb //for tracer
|
||||
dec_i0_pc_wb1 := decode.io.dec_i0_pc_wb //for tracer
|
||||
io.lsu_p := decode.io.lsu_p
|
||||
io.dec_lsu_valid_raw_d := decode.io.dec_lsu_valid_raw_d
|
||||
io.dec_lsu_offset_d := decode.io.dec_lsu_offset_d
|
||||
io.dec_pause_state_cg := decode.io.dec_pause_state_cg
|
||||
io.dec_exu.decode_exu.dec_qual_lsu_d := decode.io.decode_exu.dec_qual_lsu_d
|
||||
io.dec_fa_error_index :=decode.io.dec_fa_error_index
|
||||
|
||||
dec_i0_inst_wb1 := decode.io.dec_i0_inst_wb1 //for tracer
|
||||
dec_i0_pc_wb1 := decode.io.dec_i0_pc_wb1 //for tracer
|
||||
io.lsu_p := decode.io.lsu_p
|
||||
io.dec_lsu_valid_raw_d := decode.io.dec_lsu_valid_raw_d
|
||||
io.dec_lsu_offset_d := decode.io.dec_lsu_offset_d
|
||||
io.dec_pause_state_cg := decode.io.dec_pause_state_cg
|
||||
gpr.io.raddr0 := decode.io.dec_i0_rs1_d
|
||||
gpr.io.raddr1 := decode.io.dec_i0_rs2_d
|
||||
gpr.io.wen0 := decode.io.dec_i0_wen_r
|
||||
|
@ -212,19 +193,18 @@ class dec extends Module with param with RequireAsyncReset{
|
|||
gpr.io.wd0 := decode.io.dec_i0_wdata_r
|
||||
gpr.io.wen1 := decode.io.dec_nonblock_load_wen
|
||||
gpr.io.waddr1 := decode.io.dec_nonblock_load_waddr
|
||||
gpr.io.wd1 := io.lsu_nonblock_load_data
|
||||
gpr.io.wd1 := io.lsu_dec.dctl_busbuff.lsu_nonblock_load_data
|
||||
gpr.io.wen2 := io.exu_div_wren
|
||||
gpr.io.waddr2 := decode.io.div_waddr_wb
|
||||
gpr.io.wd2 := io.exu_div_result
|
||||
gpr.io.scan_mode := io.scan_mode
|
||||
io.dec_exu.gpr_exu <> gpr.io.gpr_exu
|
||||
|
||||
tlu.io.tlu_mem <> io.ifu_dec.dec_mem_ctrl
|
||||
tlu.io.tlu_ifc <> io.ifu_dec.dec_ifc
|
||||
tlu.io.tlu_bp <> io.ifu_dec.dec_bp
|
||||
tlu.io.tlu_exu <> io.dec_exu.tlu_exu
|
||||
tlu.io.tlu_dma <> io.dec_dma.tlu_dma
|
||||
tlu.io.free_l2clk := io.free_l2clk
|
||||
tlu.io.active_clk := io.active_clk
|
||||
tlu.io.free_clk := io.free_clk
|
||||
tlu.io.scan_mode := io.scan_mode
|
||||
tlu.io.rst_vec := io.rst_vec
|
||||
|
@ -259,7 +239,7 @@ class dec extends Module with param with RequireAsyncReset{
|
|||
tlu.io.dec_tlu_i0_pc_r := decode.io.dec_tlu_i0_pc_r
|
||||
tlu.io.dec_tlu_packet_r := decode.io.dec_tlu_packet_r
|
||||
tlu.io.dec_illegal_inst := decode.io.dec_illegal_inst
|
||||
tlu.io.dec_i0_decode_d := decode.io.dec_i0_decode_d
|
||||
tlu.io.dec_i0_decode_d := decode.io.dec_aln.dec_i0_decode_d
|
||||
tlu.io.exu_i0_br_way_r := io.exu_i0_br_way_r
|
||||
tlu.io.dbg_halt_req := io.dbg_halt_req
|
||||
tlu.io.dbg_resume_req := io.dbg_resume_req
|
||||
|
@ -302,26 +282,20 @@ class dec extends Module with param with RequireAsyncReset{
|
|||
io.dec_tlu_pic_clk_override := tlu.io.dec_tlu_pic_clk_override
|
||||
io.dec_tlu_dccm_clk_override := tlu.io.dec_tlu_dccm_clk_override
|
||||
io.dec_tlu_icm_clk_override := tlu.io.dec_tlu_icm_clk_override
|
||||
io.dec_tlu_picio_clk_override := tlu.io.dec_tlu_picio_clk_override
|
||||
io.dec_tlu_core_empty := tlu.io.dec_tlu_core_empty
|
||||
io.dec_csr_rddata_d := tlu.io.dec_csr_rddata_d
|
||||
io.dec_tlu_flush_lower_wb := tlu.io.dec_tlu_flush_lower_wb
|
||||
|
||||
//--------------------------------------------------------------------------//
|
||||
|
||||
io.trace_rv_trace_pkt.rv_i_insn_ip := decode.io.dec_i0_inst_wb
|
||||
io.trace_rv_trace_pkt.rv_i_address_ip := Cat(decode.io.dec_i0_pc_wb, 0.U)
|
||||
io.trace_rv_trace_pkt.rv_i_valid_ip := tlu.io.dec_tlu_int_valid_wb1 | tlu.io.dec_tlu_i0_valid_wb1 | tlu.io.dec_tlu_i0_exc_valid_wb1
|
||||
io.trace_rv_trace_pkt.rv_i_exception_ip := tlu.io.dec_tlu_int_valid_wb1 | tlu.io.dec_tlu_i0_exc_valid_wb1
|
||||
io.trace_rv_trace_pkt.rv_i_ecause_ip := tlu.io.dec_tlu_exc_cause_wb1(4,0)
|
||||
io.trace_rv_trace_pkt.rv_i_interrupt_ip := tlu.io.dec_tlu_int_valid_wb1
|
||||
io.trace_rv_trace_pkt.rv_i_tval_ip := tlu.io.dec_tlu_mtval_wb1
|
||||
io.rv_trace_pkt.rv_i_insn_ip := decode.io.dec_i0_inst_wb1
|
||||
io.rv_trace_pkt.rv_i_address_ip := Cat(decode.io.dec_i0_pc_wb1, 0.U)
|
||||
io.rv_trace_pkt.rv_i_valid_ip := Cat(tlu.io.dec_tlu_int_valid_wb1, tlu.io.dec_tlu_i0_valid_wb1 | tlu.io.dec_tlu_i0_exc_valid_wb1)
|
||||
io.rv_trace_pkt.rv_i_exception_ip := Cat(tlu.io.dec_tlu_int_valid_wb1, tlu.io.dec_tlu_i0_exc_valid_wb1)
|
||||
io.rv_trace_pkt.rv_i_ecause_ip := tlu.io.dec_tlu_exc_cause_wb1(4,0)
|
||||
io.rv_trace_pkt.rv_i_interrupt_ip := Cat(tlu.io.dec_tlu_int_valid_wb1, 0.U)
|
||||
io.rv_trace_pkt.rv_i_tval_ip := tlu.io.dec_tlu_mtval_wb1
|
||||
|
||||
|
||||
// debug command read data
|
||||
io.dec_dbg_rddata := decode.io.dec_i0_wdata_r
|
||||
}
|
||||
object dec_main extends App {
|
||||
println((new chisel3.stage.ChiselStage).emitVerilog(new dec()))
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,254 +17,105 @@ class dec_dec_ctl extends Module with lib{
|
|||
pat.reduce(_&_)
|
||||
}
|
||||
|
||||
io.out.alu := pattern(List(30,24,23,-22,-21,-20,14,-5,4)) | pattern(List(29,-27,-24,4)) |
|
||||
pattern(List(-25,-13,-12,4)) | pattern(List(-30,-25,13,12)) | pattern(List(27,25,14,4)) |
|
||||
pattern(List(29,27,-14,4)) | pattern(List(29,-14,5,4)) | pattern(List(-27,-25,14,4)) |
|
||||
pattern(List(30,-29,-13,4)) | pattern(List(-30,-27,-25,4)) | pattern(List(13,-5,4)) |
|
||||
pattern(List(-12,-5,4)) | pattern(List(2)) | pattern(List(6)) | pattern(List(30,24,23,22,21,20,-5,4)) |
|
||||
pattern(List(-30,29,-24,-23,22,21,20,-5,4)) | pattern(List(-30,24,-23,-22,-21,-20,-5,4))
|
||||
|
||||
io.out.rs1 := pattern(List(-14,-13,-2)) | pattern(List(-13,11,-2)) | pattern(List(19,13,-2)) |
|
||||
pattern(List(-13,10,-2)) | pattern(List(18,13,-2)) | pattern(List(-13,9,-2)) | pattern(List(17,13,-2)) |
|
||||
pattern(List(-13,8,-2)) | pattern(List(16,13,-2)) | pattern(List(-13,7,-2)) |
|
||||
pattern(List(15,13,-2)) | pattern(List(-4,-3)) | pattern(List(-6,-2))
|
||||
|
||||
io.out.alu := io.ins(2) | io.ins(6) | (!io.ins(25)&io.ins(4)) | (!io.ins(5)&io.ins(4))
|
||||
io.out.rs1 := pattern(List(-14,-13,-2)) | pattern(List(-13,11,-2)) |
|
||||
pattern(List(19,13,-2)) | pattern(List(-13,10,-2)) |
|
||||
pattern(List(18,13,-2)) | pattern(List(-13,9,-2)) |
|
||||
pattern(List(17,13,-2)) | pattern(List(-13,8,-2)) |
|
||||
pattern(List(16,13,-2)) | pattern(List(-13,7,-2)) |
|
||||
pattern(List(15,13,-2)) |pattern(List(-4,-3)) | pattern(List(-6,-2))
|
||||
io.out.rs2 := pattern(List(5,-4,-2)) | pattern(List(-6,5,-2))
|
||||
|
||||
io.out.imm12 := pattern(List(-4,-3,2)) | pattern(List(13,-5,4,-2)) | pattern(List(-13,-12,6,4)) | pattern(List(-12,-5,4,-2))
|
||||
|
||||
io.out.rd := pattern(List(-5,-2)) | pattern(List(5,2)) | pattern(List(4))
|
||||
|
||||
io.out.shimm5 := pattern(List(27,-13,12,-5,4,-2)) | pattern(List(-30,-13,12,-5,4,-2)) | pattern(List(14,-13,12,-5,4,-2))
|
||||
|
||||
io.out.imm20 := pattern(List(5,3)) | pattern(List(4,2))
|
||||
|
||||
io.out.pc := pattern(List(-5,-3,2)) | pattern(List(5,3))
|
||||
|
||||
io.out.imm12 := pattern(List(-4,-3,2)) | pattern(List(13,-5,4,-2)) |
|
||||
pattern(List(-13,-12,6,4)) | pattern(List(-12,-5,4,-2))
|
||||
io.out.rd := (!io.ins(5) & !io.ins(2)) | (io.ins(5) & io.ins(2)) | io.ins(4)
|
||||
io.out.shimm5 := pattern(List(-13,12,-5,4,-2))
|
||||
io.out.imm20 := (io.ins(5)&io.ins(3)) | (io.ins(4)&io.ins(2))
|
||||
io.out.pc := (!io.ins(5) & !io.ins(3) & io.ins(2)) | (io.ins(5) & io.ins(3))
|
||||
io.out.load := pattern(List(-5,-4,-2))
|
||||
|
||||
io.out.store := pattern(List(-6,5,-4))
|
||||
|
||||
io.out.lsu := pattern(List(-6,-4,-2))
|
||||
|
||||
io.out.add := pattern(List(-14,-13,-12,-5,4)) | pattern(List(-5,-3,2)) | pattern(List(-30,-25,-14,-13,-12,-6,4,-2))
|
||||
|
||||
io.out.sub := pattern(List(30,-14,-12,-6,5,4,-2)) | pattern(List(-29,-25,-14,13,-6,4,-2)) |
|
||||
pattern(List(27,25,14,-6,5,-2)) | pattern(List(-14,13,-5,4,-2)) | pattern(List(6,-4,-2))
|
||||
|
||||
io.out.land := pattern(List(-27,-25,14,13,12,-6,-2)) | pattern(List(14,13,12,-5,-2))
|
||||
|
||||
io.out.lor := pattern(List(-6,3)) | pattern(List(-29,-27,-25,14,13,-12,-6,-2)) | pattern(List(5,4,2)) |
|
||||
pattern(List(-13,-12,6,4)) | pattern(List(14,13,-12,-5,-2))
|
||||
|
||||
io.out.lxor := pattern(List(-29,-27,-25,14,-13,-12,4,-2)) | pattern(List(14,-13,-12,-5,4,-2))
|
||||
|
||||
io.out.sll := pattern(List(-29,-27,-25,-14,-13,12,-6,4,-2))
|
||||
|
||||
io.out.sra := pattern(List(30,-29,-27,-13,12,-6,4,-2))
|
||||
|
||||
io.out.srl := pattern(List(-30,-29,-27,-25,14,-13,12,-6,4,-2))
|
||||
|
||||
io.out.slt := pattern(List(-29,-25,-14,13,-6,4,-2)) | pattern(List(-14,13,-5,4,-2))
|
||||
|
||||
io.out.unsign := pattern(List(-27,25,14,12,-6,5,-2)) | pattern(List(-14,13,12,-5,-2)) |
|
||||
pattern(List(13,6,-4,-2)) | pattern(List(14,-5,-4)) | pattern(List(-25,-14,13,12,-6,-2)) |
|
||||
pattern(List(27,25,14,13,-6,5,-2))
|
||||
|
||||
io.out.add := pattern(List(-14,-13,-12,-5,4)) | pattern(List(-5,-3,2)) |
|
||||
pattern(List(-30,-25,-14,-13,-12,-6,4,-2))
|
||||
io.out.sub := pattern(List(30,-12,-6,5,4,-2)) | pattern(List(-25,-14,13,-6,4,-2)) |
|
||||
pattern(List(-14,13,-5,4,-2)) | pattern(List(6,-4,-2))
|
||||
io.out.land := pattern(List(14,13,12,-5,-2)) | pattern(List(-25,14,13,12,-6,-2))
|
||||
io.out.lor := pattern(List(-6,3)) | pattern(List(-25,14,13,-12,-6,-2)) |
|
||||
pattern(List(5,4,2)) | pattern(List(-13,-12,6,4)) |
|
||||
pattern(List(14,13,-12,-5,-2))
|
||||
io.out.lxor := pattern(List(-25,14,-13,-12,4,-2)) | pattern(List(14,-13,-12,-5,4,-2))
|
||||
io.out.sll := pattern(List(-25,-14,-13,12,-6,4,-2))
|
||||
io.out.sra := pattern(List(30,-13,12,-6,4,-2))
|
||||
io.out.srl := pattern(List(-30,-25,14,-13,12,-6,4,-2))
|
||||
io.out.slt := pattern(List(-25,-14,13,-6,4,-2)) | pattern(List(-14,13,-5,4,-2))
|
||||
io.out.unsign := pattern(List(-14,13,12,-5,-2)) | pattern(List(13,6,-4,-2)) |
|
||||
pattern(List(14,-5,-4)) | pattern(List(-25,-14,13,12,-6,-2)) |
|
||||
pattern(List(25,14,12,-6,5,-2))
|
||||
io.out.condbr := pattern(List(6,-4,-2))
|
||||
|
||||
io.out.beq := pattern(List(-14,-12,6,-4,-2))
|
||||
|
||||
io.out.bne := pattern(List(-14,12,6,-4,-2))
|
||||
|
||||
io.out.bge := pattern(List(14,12,5,-4,-2))
|
||||
|
||||
io.out.blt := pattern(List(14,-12,5,-4,-2))
|
||||
|
||||
io.out.jal := pattern(List(6,2))
|
||||
|
||||
io.out.by := pattern(List(-13,-12,-6,-4,-2))
|
||||
|
||||
io.out.half := pattern(List(12,-6,-4,-2))
|
||||
|
||||
io.out.word := pattern(List(13,-6,-4))
|
||||
|
||||
io.out.csr_read := pattern(List(13,6,4)) | pattern(List(7,6,4)) | pattern(List(8,6,4)) |
|
||||
pattern(List(9,6,4)) | pattern(List(10,6,4)) | pattern(List(11,6,4))
|
||||
|
||||
io.out.csr_read := pattern(List(13,6,4)) | pattern(List(7,6,4)) |
|
||||
pattern(List(8,6,4)) | pattern(List(9,6,4)) | pattern(List(10,6,4)) |
|
||||
pattern(List(11,6,4))
|
||||
io.out.csr_clr := pattern(List(15,13,12,6,4)) | pattern(List(16,13,12,6,4)) |
|
||||
pattern(List(17,13,12,6,4)) | pattern(List(18,13,12,6,4)) | pattern(List(19,13,12,6,4))
|
||||
|
||||
io.out.csr_set := pattern(List(15,-12,6,4)) | pattern(List(16,-12,6,4)) | pattern(List(17,-12,6,4)) |
|
||||
pattern(List(18,-12,6,4)) | pattern(List(19,-12,6,4))
|
||||
|
||||
pattern(List(17,13,12,6,4)) | pattern(List(18,13,12,6,4)) |
|
||||
pattern(List(19,13,12,6,4))
|
||||
io.out.csr_write := pattern(List(-13,12,6,4))
|
||||
|
||||
io.out.csr_imm := pattern(List(14,-13,6,4)) | pattern(List(15,14,6,4)) | pattern(List(16,14,6,4)) |
|
||||
pattern(List(17,14,6,4)) | pattern(List(18,14,6,4)) | pattern(List(19,14,6,4))
|
||||
|
||||
io.out.presync := pattern(List(-5,3)) | pattern(List(-13,7,6,4)) | pattern(List(-13,8,6,4)) |
|
||||
pattern(List(-13,9,6,4)) | pattern(List(-13,10,6,4)) | pattern(List(-13,11,6,4)) |
|
||||
pattern(List(15,13,6,4)) | pattern(List(16,13,6,4)) | pattern(List(17,13,6,4)) |
|
||||
pattern(List(18,13,6,4)) | pattern(List(19,13,6,4))
|
||||
|
||||
io.out.postsync := pattern(List(12,-5,3)) | pattern(List(-22,-13,-12,6,4)) |
|
||||
pattern(List(-13,7,6,4)) | pattern(List(-13,8,6,4)) | pattern(List(-13,9,6,4)) | pattern(List(-13,10,6,4)) |
|
||||
pattern(List(-13,11,6,4)) | pattern(List(15,13,6,4)) | pattern(List(16,13,6,4)) | pattern(List(17,13,6,4)) |
|
||||
pattern(List(18,13,6,4)) | pattern(List(19,13,6,4))
|
||||
|
||||
io.out.csr_imm := pattern(List(14,-13,6,4)) | pattern(List(15,14,6,4)) |
|
||||
pattern(List(16,14,6,4)) | pattern(List(17,14,6,4)) |
|
||||
pattern(List(18,14,6,4)) | pattern(List(19,14,6,4))
|
||||
io.out.csr_set := pattern(List(15,-12,6,4)) | pattern(List(16,-12,6,4)) |
|
||||
pattern(List(17,-12,6,4)) | pattern(List(18,-12,6,4)) |
|
||||
pattern(List(19,-12,6,4))
|
||||
io.out.ebreak := pattern(List(-22,20,-13,-12,6,4))
|
||||
|
||||
io.out.ecall := pattern(List(-21,-20,-13,-12,6,4))
|
||||
|
||||
io.out.mret := pattern(List(29,-13,-12,6,4))
|
||||
|
||||
io.out.mul := pattern(List(-30,27,24,20,14,-13,12,-5,4,-2)) | pattern(List(29,27,-24,23,14,-13,12,-5,4,-2)) |
|
||||
pattern(List(29,27,-24,-20,14,-13,12,-5,4,-2)) | pattern(List(27,-25,13,-12,-6,5,4,-2)) |
|
||||
pattern(List(30,27,13,-6,5,4,-2)) | pattern(List(29,27,22,-20,14,-13,12,-5,4,-2)) |
|
||||
pattern(List(29,27,-21,20,14,-13,12,-5,4,-2)) | pattern(List(29,27,-22,21,14,-13,12,-5,4,-2)) |
|
||||
pattern(List(30,29,27,-23,14,-13,12,-5,4,-2)) | pattern(List(-30,27,23,14,-13,12,-5,4,-2)) |
|
||||
pattern(List(-30,-29,27,-25,-13,12,-6,4,-2)) | pattern(List(25,-14,-6,5,4,-2)) |
|
||||
pattern(List(30,-27,24,-14,-13,12,-5,4,-2)) | pattern(List(29,27,14,-6,5,-2))
|
||||
|
||||
io.out.rs1_sign := pattern(List(-27,25,-14,13,-12,-6,5,4,-2)) | pattern(List(-27,25,-14,-13,12,-6,4,-2))
|
||||
|
||||
io.out.rs2_sign := pattern(List(-27,25,-14,-13,12,-6,4,-2))
|
||||
|
||||
io.out.mul := pattern(List(25,-14,-6,5,4,-2))
|
||||
io.out.rs1_sign := pattern(List(25,-14,13,-12,-6,5,4,-2)) |
|
||||
pattern(List(25,-14,-13,12,-6,4,-2))
|
||||
io.out.rs2_sign := pattern(List(25,-14,-13,12,-6,4,-2))
|
||||
io.out.low := pattern(List(25,-14,-13,-12,5,4,-2))
|
||||
|
||||
io.out.div := pattern(List(-27,25,14,-6,5,-2))
|
||||
|
||||
io.out.rem := pattern(List(-27,25,14,13,-6,5,-2))
|
||||
|
||||
io.out.div := pattern(List(25,14,-6,5,-2))
|
||||
io.out.rem := pattern(List(25,14,13,-6,5,-2))
|
||||
io.out.fence := pattern(List(-5,3))
|
||||
|
||||
io.out.fence_i := pattern(List(12,-5,3))
|
||||
|
||||
io.out.clz := pattern(List(30,-27,-24,-22,-21,-20,-14,-13,12,-5,4,-2))
|
||||
|
||||
io.out.ctz := pattern(List(30,-27,-24,-22,20,-14,-13,12,-5,4,-2))
|
||||
|
||||
io.out.pcnt := pattern(List(30,-27,-24,21,-14,-13,12,-5,4,-2))
|
||||
|
||||
io.out.sext_b := pattern(List(30,-27,22,-20,-14,-13,12,-5,4,-2))
|
||||
|
||||
io.out.sext_h := pattern(List(30,-27,22,20,-14,-13,12,-5,4,-2))
|
||||
|
||||
io.out.slo := pattern(List(-30,29,-27,-14,-13,12,-6,4,-2))
|
||||
|
||||
io.out.sro := pattern(List(-30,29,-27,14,-13,12,-6,4,-2))
|
||||
|
||||
io.out.min := pattern(List(27,25,14,-12,-6,5,-2))
|
||||
|
||||
io.out.max := pattern(List(27,25,14,12,-6,5,-2))
|
||||
|
||||
io.out.pack := pattern(List(-30,27,-25,-13,-12,5,4,-2))
|
||||
|
||||
io.out.packu := pattern(List(30,27,-13,-12,5,4,-2))
|
||||
|
||||
io.out.packh := pattern(List(-30,27,-25,13,12,-6,5,-2))
|
||||
|
||||
io.out.rol := pattern(List(30,-27,-14,12,-6,5,4,-2))
|
||||
|
||||
io.out.ror := pattern(List(30,29,-27,14,-13,12,-6,4,-2))
|
||||
|
||||
io.out.zbb := pattern(List(30,-27,-24,-14,-13,12,-5,4,-2)) | pattern(List(-30,27,14,13,12,-6,5,-2)) |
|
||||
pattern(List(30,29,-27,14,-13,12,-5,4,-2)) | pattern(List(27,-13,-12,5,4,-2)) |
|
||||
pattern(List(30,14,-13,-12,-6,5,-2)) | pattern(List(30,-27,13,-6,5,4,-2)) |
|
||||
pattern(List(30,29,-27,-6,5,4,-2)) | pattern(List(30,29,24,23,22,21,20,14,-13,12,-5,4,-2)) |
|
||||
pattern(List(-30,29,27,-24,-23,22,21,20,14,-13,12,-5,4,-2)) |
|
||||
pattern(List(-30,27,24,-23,-22,-21,-20,14,-13,12,-5,4,-2)) |
|
||||
pattern(List(30,29,24,23,-22,-21,-20,14,-13,12,-5,4,-2)) | pattern(List(27,25,14,-6,5,-2))
|
||||
|
||||
io.out.sbset := pattern(List(-30,29,27,-14,-13,12,-6,4,-2))
|
||||
|
||||
io.out.sbclr := pattern(List(30,-29,-14,-13,12,-6,4,-2))
|
||||
|
||||
io.out.sbinv := pattern(List(30,29,27,-14,-13,12,-6,4,-2))
|
||||
|
||||
io.out.sbext := pattern(List(30,-29,27,14,-13,12,-6,4,-2))
|
||||
|
||||
io.out.zbs := pattern(List(29,27,-14,-13,12,-6,4,-2)) | pattern(List(30,-29,27,-13,12,-6,4,-2))
|
||||
|
||||
io.out.bext := pattern(List(-30,27,-25,13,-12,-6,5,4,-2))
|
||||
|
||||
io.out.bdep := pattern(List(30,27,13,-12,-6,5,4,-2))
|
||||
|
||||
io.out.zbe := pattern(List(27,-25,13,-12,-6,5,4,-2))
|
||||
|
||||
io.out.clmul := pattern(List(27,25,-14,-13,-6,5,4,-2))
|
||||
|
||||
io.out.clmulh := pattern(List(27,-14,13,12,-6,5,-2))
|
||||
|
||||
io.out.clmulr := pattern(List(27,-14,-12,-6,5,4,-2))
|
||||
|
||||
io.out.zbc := pattern(List(27,25,-14,-6,5,4,-2))
|
||||
|
||||
io.out.grev := pattern(List(30,29,27,14,-13,12,-6,4,-2))
|
||||
|
||||
io.out.gorc := pattern(List(-30,29,27,14,-13,12,-6,4,-2))
|
||||
|
||||
io.out.shfl := pattern(List(-30,-29,27,-25,-14,-13,12,-6,4,-2))
|
||||
|
||||
io.out.unshfl := pattern(List(-30,-29,27,-25,14,-13,12,-6,4,-2))
|
||||
|
||||
io.out.zbp := pattern(List(-30,29,-27,-13,12,-5,4,-2)) | pattern(List(-30,-29,27,-13,12,-5,4,-2)) |
|
||||
pattern(List(30,-27,13,-6,5,4,-2)) | pattern(List(27,-25,-13,-12,5,4,-2)) |
|
||||
pattern(List(30,14,-13,-12,5,4,-2)) | pattern(List(29,-27,12,-6,5,4,-2)) |
|
||||
pattern(List(-30,-29,27,-25,12,-6,5,4,-2)) | pattern(List(29,14,-13,12,-6,4,-2))
|
||||
|
||||
io.out.crc32_b := pattern(List(30,-27,24,-23,-21,-20,-14,-13,12,-5,4,-2))
|
||||
|
||||
io.out.crc32_h := pattern(List(30,-27,24,-23,20,-14,-13,12,-5,4,-2))
|
||||
|
||||
io.out.crc32_w := pattern(List(30,-27,24,-23,21,-14,-13,12,-5,4,-2))
|
||||
|
||||
io.out.crc32c_b := pattern(List(30,-27,23,-21,-20,-14,-13,12,-5 ,4,-2))
|
||||
|
||||
io.out.crc32c_h := pattern(List(30,-27,23,20,-14,-13,12,-5,4,-2))
|
||||
|
||||
io.out.crc32c_w := pattern(List(30,-27,23,21,-14,-13,12,-5,4,-2))
|
||||
|
||||
io.out.zbr := pattern(List(30,-27,24,-14,-13,12,-5,4,-2))
|
||||
|
||||
io.out.bfp := pattern(List(30,27,13,12,-6,5,-2))
|
||||
|
||||
io.out.zbf := pattern(List(30,27,13,12,-6,5,-2))
|
||||
|
||||
io.out.sh1add := pattern(List(29,-14,-12,-6,5,4,-2))
|
||||
|
||||
io.out.sh2add := pattern(List(29,14,-13,-12,5,4,-2))
|
||||
|
||||
io.out.sh3add := pattern(List(29,14,13,-6,5,-2))
|
||||
|
||||
io.out.zba := pattern(List(29,-12,-6,5,4,-2))
|
||||
|
||||
io.out.pm_alu := pattern(List(28,22,-13,-12,4)) | pattern(List(-30,-29,-27,-25,-6,4)) |
|
||||
pattern(List(-29,-27,-25,-13,12,-6,4)) | pattern(List(-29,-27,-25,-14,-6,4)) |
|
||||
pattern(List(13,-5,4)) | pattern(List(4,2)) | pattern(List(-12,-5,4))
|
||||
|
||||
|
||||
io.out.legal := pattern(List(-31,-30,-29,28,-27,-26,-25,-24,-23,22,-21,20,-19,-18,-17,-16,-15,-14,-11,-10,-9,-8,-7,6,5,4,-3,-2,1,0)) |
|
||||
pattern(List(-31,-30,29,28,-27,-26,-25,-24,-23,-22,21,-20,-19,-18,-17,-16,-15,-14,-11,-10,-9,-8,-7,6,5,4,-3,-2,1,0)) |
|
||||
io.out.pm_alu := pattern(List(28,22,-13,-12,4)) | pattern(List(4,2)) |
|
||||
pattern(List(-25,-6,4)) | pattern(List(-5,4))
|
||||
io.out.presync := pattern(List(-5,3)) | pattern(List(-13,7,6,4)) |
|
||||
pattern(List(-13,8,6,4)) | pattern(List(-13,9,6,4)) |
|
||||
pattern(List(-13,10,6,4)) | pattern(List(-13,11,6,4)) |
|
||||
pattern(List(15,13,6,4)) | pattern(List(16,13,6,4)) |
|
||||
pattern(List(17,13,6,4)) | pattern(List(18,13,6,4)) |
|
||||
pattern(List(19,13,6,4))
|
||||
io.out.postsync := pattern(List(12,-5,3)) | pattern(List(-22,-13,-12,6,4)) |
|
||||
pattern(List(-13,7,6,4)) | pattern(List(-13,8,6,4)) |
|
||||
pattern(List(-13,9,6,4)) | pattern(List(-13,10,6,4)) |
|
||||
pattern(List(-13,11,6,4)) | pattern(List(15,13,6,4)) |
|
||||
pattern(List(16,13,6,4)) | pattern(List(17,13,6,4)) |
|
||||
pattern(List(18,13,6,4)) | pattern(List(19,13,6,4))
|
||||
io.out.legal := pattern(List(-31,-30,29,28,-27,-26,-25,-24,-23,-22,21,-20,-19,-18,-17,-16,-15,-14,-11,-10,-9,-8,-7,6,5,4,-3,-2,1,0)) |
|
||||
pattern(List(-31,-30,-29,28,-27,-26,-25,-24,-23,22,-21,20,-19,-18,-17,-16,-15,-14,-11,-10,-9,-8,-7,6,5,4,-3,-2,1,0)) |
|
||||
pattern(List(-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-19,-18,-17,-16,-15,-14,-11,-10,-9,-8,-7,5,4,-3,-2,1,0)) |
|
||||
pattern(List(-31,29,-28,-26,-25,24,-22,-20,-6,-5,4,-3,1,0)) | pattern(List(-31,29,-28,-26,-25,24,-22,-21,-6,-5,4,-3,1,0)) |
|
||||
pattern(List(-31,29,-28,-26,-25,-23,-22,-20,-6,-5,4,-3,1,0)) | pattern(List(-31,29,-28,-26,-25,-24,-23,-21,-6,-5,4,-3,1,0)) |
|
||||
pattern(List(-31,-30,-29,-28,-26,25,13,-6,4,-3,1,0)) | pattern(List(-31,-30,-28,-26,-25,-24,-6,-5,4,-3,1,0)) |
|
||||
pattern(List(-31,-30,-28,-27,-26,-25,14,-12,-6,4,-3,1,0)) | pattern(List(-31,-30,-28,-27,-26,-25,13,-12,-6,4,-3,1,0)) |
|
||||
pattern(List(-31,-29,-28,-27,-26,-25,-13,-12,-6,4,-3,1,0)) | pattern(List(-31,-28,-27,-26,-25,14,-6,-5,4,-3,1,0)) |
|
||||
pattern(List(-31,-30,-29,-28,-26,-13,12,5,4,-3,-2,1,0)) | pattern(List(-31,-30,-29,-28,-26,14,-6,5,4,-3,1,0)) |
|
||||
pattern(List(-31,30,-28,27,-26,-25,-13,12,-6,4,-3,1,0)) | pattern(List(-31,29,-28,27,-26,-25 ,-6,-5,4,-3,1,0)) |
|
||||
pattern(List(-31,-30,-28,-27,-26,-25,-6,-5,4,-3,1,0)) | pattern(List(-31,-30,-29,-28,-27,-26,-6,5,4,-3,1,0)) |
|
||||
pattern(List(-14,-13,-12,6,5,-4,-3,1,0)) | pattern(List(-31,-29,-28,-26,-25,14,-6,5,4,-3,1,0)) |
|
||||
pattern(List(-31,29,-28,-26,-25,-13,12,5,4,-3,-2,1,0)) | pattern(List(14,6,5,-4,-3,-2,1,0)) |
|
||||
pattern(List(-14,-13,5,-4,-3,-2,1,0)) | pattern(List(-12,-6,-5,4,-3,1,0)) | pattern(List(-13,12,6,5,-3,-2,1,0)) |
|
||||
pattern(List(-31,-30,-29,-28,-27,-26,-25,-6,4,-3,1,0)) |
|
||||
pattern(List(-31,-29,-28,-27,-26,-25,-14,-13,-12,-6,-3,-2,1,0)) |
|
||||
pattern(List(-31,-29,-28,-27,-26,-25,14,-13,12,-6,4,-3,1,0)) |
|
||||
pattern(List(-31,-30,-29,-28,-27,-26,-6,5,4,-3,1,0)) |
|
||||
pattern(List(-14,-13,-12,6,5,-4,-3,1,0)) |
|
||||
pattern(List(14,6,5,-4,-3,-2,1,0)) |
|
||||
pattern(List(-12,-6,-5,4,-3,1,0)) |
|
||||
pattern(List(-14,-13,5,-4,-3,-2,1,0)) |
|
||||
pattern(List(12,6,5,4,-3,-2,1,0)) |
|
||||
pattern(List(-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15,-14,-13,-11,-10,-9,-8,-7,-6,-5,-4,3,2,1,0)) |
|
||||
pattern(List(-31,-30,-29,-28,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,3,2,1,0)) |
|
||||
pattern(List(13,6,5,4,-3,-2,1,0)) | pattern(List(6,5,-4,3,2,1,0)) | pattern(List(-14,-12,-6,-4,-3,-2,1,0)) |
|
||||
pattern(List(-13,-6,-5,-4,-3,-2,1,0)) | pattern(List(13,-6,-5,4,-3,1,0)) | pattern(List(-6,4,-3,2,1,0))
|
||||
|
||||
}
|
||||
object dec_dec extends App {
|
||||
(new chisel3.stage.ChiselStage).emitVerilog(new dec_dec_ctl())
|
||||
pattern(List(13,6,5,4,-3,-2,1,0)) |
|
||||
pattern(List(-13,-6,-5,-4,-3,-2,1,0)) |
|
||||
pattern(List(6,5,-4,3,2,1,0)) |
|
||||
pattern(List(13,-6,-5,4,-3,1,0)) |
|
||||
pattern(List(-14,-12,-6,-4,-3,-2,1,0)) |
|
||||
pattern(List(-6,4,-3,2,1,0))
|
||||
}
|
||||
|
|
|
@ -17,17 +17,10 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
val dctl_dma = new dctl_dma //connection with dma
|
||||
val dec_aln = Flipped(new aln_dec) //connection with aligner
|
||||
val dbg_dctl = new dbg_dctl() //connection with dbg
|
||||
|
||||
val dec_tlu_trace_disable = Input(Bool())
|
||||
val dec_debug_valid_d = Input(Bool())
|
||||
|
||||
|
||||
val dec_tlu_flush_extint = Input(Bool())
|
||||
val dec_tlu_force_halt = Input(Bool()) // invalidate nonblock load cam on a force halt event
|
||||
|
||||
val dec_i0_inst_wb = Output(UInt(32.W)) // 32b instruction at wb+1 for trace encoder
|
||||
val dec_i0_pc_wb = Output(UInt(31.W)) // 31b pc at wb+1 for trace encoder
|
||||
|
||||
val dec_i0_inst_wb1 = Output(UInt(32.W)) // 32b instruction at wb+1 for trace encoder
|
||||
val dec_i0_pc_wb1 = Output(UInt(31.W)) // 31b pc at wb+1 for trace encoder
|
||||
val dec_i0_trigger_match_d = Input(UInt(4.W)) // i0 decode trigger matches
|
||||
val dec_tlu_wr_pause_r = Input(Bool()) // pause instruction at r
|
||||
val dec_tlu_pipelining_disable = Input(Bool()) // pipeline disable - presync, i0 decode only
|
||||
|
@ -37,19 +30,14 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
val dec_tlu_flush_leak_one_r = Input(Bool()) // leak1 instruction
|
||||
val dec_debug_fence_d = Input(Bool()) // debug fence instruction
|
||||
val dec_i0_icaf_d = Input(Bool()) // icache access fault
|
||||
|
||||
val dec_i0_icaf_second_d = Input(Bool()) // i0 instruction access fault at decode for f1 fetch group
|
||||
|
||||
val dec_i0_icaf_f1_d = Input(Bool()) // i0 instruction access fault at decode for f1 fetch group
|
||||
val dec_i0_icaf_type_d = Input(UInt(2.W)) // i0 instruction access fault type
|
||||
val dec_i0_dbecc_d = Input(Bool()) // icache/iccm double-bit error
|
||||
val dec_i0_brp = Flipped(Valid(new br_pkt_t)) // branch packet
|
||||
val dec_i0_bp_index = Input(UInt(((BTB_ADDR_HI-BTB_ADDR_LO)+1).W)) // i0 branch index
|
||||
val dec_i0_bp_fghr = Input(UInt(BHT_GHR_SIZE.W)) // BP FGHR
|
||||
val dec_i0_bp_btag = Input(UInt(BTB_BTAG_SIZE.W)) // BP tag
|
||||
|
||||
val dec_i0_bp_fa_index = Input(UInt(log2Ceil(BTB_SIZE).W)) // Fully associt btb index
|
||||
|
||||
// val dec_i0_pc_d = Input(UInt(31.W)) // pc
|
||||
val dec_i0_pc_d = Input(UInt(31.W)) // pc
|
||||
val lsu_idle_any = Input(Bool()) // lsu idle: if fence instr & !!!!!!!!!!!!!!!!!!!!!!!!!lsu_idle then stall decode
|
||||
val lsu_load_stall_any = Input(Bool()) // stall any load at decode
|
||||
val lsu_store_stall_any = Input(Bool()) // stall any store at decode6
|
||||
|
@ -69,21 +57,14 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
val exu_flush_final = Input(Bool()) // lower flush or i0 flush at X or D
|
||||
val dec_i0_instr_d = Input(UInt(32.W)) // inst at decode
|
||||
val dec_ib0_valid_d = Input(Bool()) // inst valid at decode
|
||||
|
||||
val active_clk = Input(Clock()) // Clock only while core active. Through two clock headers. For flops without second clock header built in.
|
||||
val free_l2clk = Input(Clock()) // Clock always. Through one clock header. For flops with second header built in.
|
||||
val clk_override = Input(Bool()) // Override non-functional clock gating
|
||||
|
||||
val free_clk = Input(Clock())
|
||||
val active_clk = Input(Clock()) // clk except for halt / pause
|
||||
val clk_override = Input(Bool()) // test stuff
|
||||
val dec_i0_rs1_d = Output(UInt(5.W)) // rs1 logical source
|
||||
val dec_i0_rs2_d = Output(UInt(5.W))
|
||||
val dec_i0_waddr_r = Output(UInt(5.W)) // i0 logical source to write to gpr's
|
||||
val dec_i0_wen_r = Output(Bool()) // i0 write enable
|
||||
val dec_i0_wdata_r = Output(UInt(32.W)) // i0 write data
|
||||
|
||||
// val dec_i0_branch_d = Output(Bool()) // Branch in D-stage
|
||||
// val dec_i0_result_r = Output(UInt(32.W)) // Result R-stage
|
||||
// val dec_qual_lsu_d = Output(Bool())// LSU instruction at D. Use to quiet LSU operands
|
||||
|
||||
val lsu_p = Valid(new lsu_pkt_t) // load/store packet
|
||||
val div_waddr_wb = Output(UInt(5.W)) // DIV write address to GPR
|
||||
val dec_lsu_valid_raw_d = Output(Bool())
|
||||
|
@ -99,9 +80,6 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
val dec_tlu_packet_r = Output(new trap_pkt_t) // trap packet
|
||||
val dec_tlu_i0_pc_r = Output(UInt(31.W)) // i0 trap pc
|
||||
val dec_illegal_inst = Output(UInt(32.W)) // illegal inst
|
||||
|
||||
val dec_fa_error_index = Output(UInt(log2Ceil(BTB_SIZE).W)) // Fully associt btb error index
|
||||
|
||||
val dec_pmu_instr_decoded = Output(Bool()) // number of instructions decode this cycle encoded
|
||||
val dec_pmu_decode_stall = Output(Bool()) // decode is stalled
|
||||
val dec_pmu_presync_stall = Output(Bool()) // decode has presync stall
|
||||
|
@ -112,8 +90,7 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
val dec_pause_state_cg = Output(Bool()) // pause state for clock-gating
|
||||
val dec_div_active = Output(Bool()) // non-block divide is active
|
||||
val scan_mode = Input(Bool())
|
||||
val dec_i0_decode_d = Output(Bool())
|
||||
})
|
||||
})
|
||||
//packets zero initialization
|
||||
io.decode_exu.mul_p := 0.U.asTypeOf(io.decode_exu.mul_p)
|
||||
// Vals defined
|
||||
|
@ -196,88 +173,54 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
val i0_immed_d = WireInit(UInt(32.W), 0.U)
|
||||
val i0_result_x = WireInit(UInt(32.W), 0.U)
|
||||
val i0_result_r = WireInit(UInt(32.W), 0.U)
|
||||
val i0_br_error_all = WireInit(Bool(),0.B)
|
||||
val i0_brp_valid = WireInit(Bool(),0.B)
|
||||
val btb_error_found_f = WireInit(Bool(),0.B)
|
||||
val fa_error_index_ns = WireInit(Bool(),0.B)
|
||||
val btb_error_found = WireInit(Bool(),0.B)
|
||||
val div_active_in = WireInit(Bool(),0.B)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Start - Data gating {{
|
||||
val data_gate_en = (io.dec_tlu_wr_pause_r ^ tlu_wr_pause_r1 ) | // replaces free_clk
|
||||
(tlu_wr_pause_r1 ^ tlu_wr_pause_r2 ) | // replaces free_clk
|
||||
(io.dec_tlu_flush_extint ^ io.decode_exu.dec_extint_stall) |
|
||||
(leak1_i1_stall_in ^ leak1_i1_stall ) | // replaces free_clk
|
||||
(leak1_i0_stall_in ^ leak1_i0_stall ) | // replaces free_clk
|
||||
(pause_state_in ^ pause_state ) | // replaces free_clk
|
||||
(ps_stall_in ^ postsync_stall ) | // replaces free_clk
|
||||
(io.exu_flush_final ^ flush_final_r ) | // replaces free_clk
|
||||
(illegal_lockout_in ^ illegal_lockout ) // replaces active_clk
|
||||
|
||||
leak1_i1_stall := rvdffie(leak1_i1_stall_in, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
|
||||
leak1_i0_stall := rvdffie(leak1_i0_stall_in, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
|
||||
io.decode_exu.dec_extint_stall := rvdffie(io.dec_tlu_flush_extint, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
|
||||
pause_state := rvdffie(pause_state_in, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
|
||||
tlu_wr_pause_r1 := rvdffie(io.dec_tlu_wr_pause_r, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
|
||||
tlu_wr_pause_r2 := rvdffie(tlu_wr_pause_r1, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
|
||||
illegal_lockout := rvdffie(illegal_lockout_in, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
|
||||
postsync_stall := rvdffie(ps_stall_in, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
|
||||
|
||||
val lsu_trigger_match_r = rvdffie(io.lsu_trigger_match_m, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
|
||||
val lsu_pmu_misaligned_r = rvdffie(io.lsu_pmu_misaligned_m, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
|
||||
io.dec_div_active := rvdffie(div_active_in, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
|
||||
flush_final_r := rvdffie(io.exu_flush_final, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
|
||||
val debug_valid_x = rvdffie(io.dec_debug_valid_d, io.free_l2clk, reset.asAsyncReset(), io.scan_mode)
|
||||
val i0_icaf_d = io.dec_i0_icaf_d | io.dec_i0_dbecc_d
|
||||
if(BTB_ENABLE){
|
||||
i0_brp_valid := io.dec_i0_brp.valid & !leak1_mode & !i0_icaf_d
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.misp := 0.U
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.ataken := 0.U
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.boffset := 0.U
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.pcall := i0_pcall // don't mark as pcall if branch error
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.pja := i0_pja
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.pret := i0_pret
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.prett := io.dec_i0_brp.bits.prett
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.pc4 := io.dec_i0_pc4_d
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.hist := io.dec_i0_brp.bits.hist
|
||||
io.decode_exu.dec_i0_predict_p_d.valid := i0_brp_valid & i0_legal_decode_d
|
||||
val i0_notbr_error = i0_brp_valid & !(i0_dp_raw.condbr | i0_pcall_raw | i0_pja_raw | i0_pret_raw)
|
||||
val data_gate_clk = rvclkhdr(clock,data_gate_en.asBool(),io.scan_mode)
|
||||
// End - Data gating
|
||||
|
||||
// no toffset error for a pret
|
||||
val i0_br_toffset_error = i0_brp_valid & io.dec_i0_brp.bits.hist(1) & (io.dec_i0_brp.bits.toffset =/= i0_br_offset) & !i0_pret_raw
|
||||
val i0_ret_error = i0_brp_valid & (io.dec_i0_brp.bits.ret ^ i0_pret_raw)
|
||||
val i0_br_error = io.dec_i0_brp.bits.br_error | i0_notbr_error | i0_br_toffset_error | i0_ret_error
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.br_error := i0_br_error & i0_legal_decode_d & !leak1_mode
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.br_start_error := io.dec_i0_brp.bits.br_start_error & i0_legal_decode_d & !leak1_mode
|
||||
io.decode_exu.i0_predict_index_d := io.dec_i0_bp_index
|
||||
io.decode_exu.i0_predict_btag_d := io.dec_i0_bp_btag
|
||||
i0_br_error_all := (i0_br_error | io.dec_i0_brp.bits.br_start_error) & !leak1_mode
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.toffset := i0_br_offset
|
||||
io.decode_exu.i0_predict_fghr_d := io.dec_i0_bp_fghr
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.way := io.dec_i0_brp.bits.way
|
||||
if(BTB_FULLYA){
|
||||
|
||||
io.dec_fa_error_index := withClock(io.active_clk){RegNext(fa_error_index_ns,0.U)}
|
||||
val btb_error_found_f = withClock(io.active_clk){RegNext(btb_error_found,0.B)}
|
||||
btb_error_found := (i0_br_error_all | btb_error_found_f) & ~io.dec_tlu_flush_lower_r
|
||||
fa_error_index_ns := Mux(i0_br_error_all & ~btb_error_found_f, io.dec_i0_bp_fa_index , io.dec_fa_error_index)
|
||||
|
||||
}else{
|
||||
io.dec_fa_error_index := 0.U
|
||||
}
|
||||
|
||||
}else{
|
||||
io.decode_exu.dec_i0_predict_p_d := 0.U
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.pcall := i0_pcall // don't mark as pcall if branch error
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.pja := i0_pja
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.pret := i0_pret
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.pc4 := io.dec_i0_pc4_d
|
||||
|
||||
i0_br_error_all := 0.U
|
||||
io.decode_exu.i0_predict_index_d := 0.U
|
||||
io.decode_exu.i0_predict_btag_d := 0.U
|
||||
io.decode_exu.i0_predict_fghr_d := 0.U
|
||||
i0_brp_valid := 0.U
|
||||
}
|
||||
val i0_brp_valid = io.dec_i0_brp.valid & !leak1_mode
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.misp := 0.U
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.ataken := 0.U
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.boffset := 0.U
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.pcall := i0_pcall // don't mark as pcall if branch error
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.pja := i0_pja
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.pret := i0_pret
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.prett := io.dec_i0_brp.bits.prett
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.pc4 := io.dec_i0_pc4_d
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.hist := io.dec_i0_brp.bits.hist
|
||||
io.decode_exu.dec_i0_predict_p_d.valid := i0_brp_valid & i0_legal_decode_d
|
||||
val i0_notbr_error = i0_brp_valid & !(i0_dp_raw.condbr | i0_pcall_raw | i0_pja_raw | i0_pret_raw)
|
||||
|
||||
// no toffset error for a pret
|
||||
val i0_br_toffset_error = i0_brp_valid & io.dec_i0_brp.bits.hist(1) & (io.dec_i0_brp.bits.toffset =/= i0_br_offset) & !i0_pret_raw
|
||||
val i0_ret_error = i0_brp_valid & io.dec_i0_brp.bits.ret & !i0_pret_raw;
|
||||
val i0_br_error = io.dec_i0_brp.bits.br_error | i0_notbr_error | i0_br_toffset_error | i0_ret_error
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.br_error := i0_br_error & i0_legal_decode_d & !leak1_mode
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.br_start_error := io.dec_i0_brp.bits.br_start_error & i0_legal_decode_d & !leak1_mode
|
||||
io.decode_exu.i0_predict_index_d := io.dec_i0_bp_index
|
||||
io.decode_exu.i0_predict_btag_d := io.dec_i0_bp_btag
|
||||
val i0_br_error_all = (i0_br_error | io.dec_i0_brp.bits.br_start_error) & !leak1_mode
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.toffset := i0_br_offset
|
||||
io.decode_exu.i0_predict_fghr_d := io.dec_i0_bp_fghr
|
||||
io.decode_exu.dec_i0_predict_p_d.bits.way := io.dec_i0_brp.bits.way
|
||||
// end
|
||||
|
||||
// on br error turn anything into a nop
|
||||
// on i0 instruction fetch access fault turn anything into a nop
|
||||
// nop => alu rs1 imm12 rd lor
|
||||
|
||||
val i0_instr_error = i0_icaf_d
|
||||
val i0_icaf_d = io.dec_i0_icaf_d | io.dec_i0_dbecc_d
|
||||
val i0_instr_error = i0_icaf_d;
|
||||
i0_dp := i0_dp_raw
|
||||
when((i0_br_error_all | i0_instr_error).asBool){
|
||||
i0_dp := 0.U.asTypeOf(i0_dp)
|
||||
|
@ -293,7 +236,7 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
io.decode_exu.dec_i0_select_pc_d := i0_dp.pc
|
||||
|
||||
// branches that can be predicted
|
||||
val i0_predict_br = i0_dp.condbr | i0_pcall | i0_pja | i0_pret
|
||||
val i0_predict_br = i0_dp.condbr | i0_pcall | i0_pja | i0_pret;
|
||||
val i0_predict_nt = !(io.dec_i0_brp.bits.hist(1) & i0_brp_valid) & i0_predict_br
|
||||
val i0_predict_t = (io.dec_i0_brp.bits.hist(1) & i0_brp_valid) & i0_predict_br
|
||||
val i0_ap_pc2 = !io.dec_i0_pc4_d
|
||||
|
@ -301,50 +244,24 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
io.decode_exu.i0_ap.predict_nt := i0_predict_nt
|
||||
io.decode_exu.i0_ap.predict_t := i0_predict_t
|
||||
|
||||
|
||||
io.decode_exu.i0_ap.add := i0_dp.add
|
||||
io.decode_exu.i0_ap.sub := i0_dp.sub
|
||||
io.decode_exu.i0_ap.land := i0_dp.land
|
||||
io.decode_exu.i0_ap.lor := i0_dp.lor
|
||||
io.decode_exu.i0_ap.lxor := i0_dp.lxor
|
||||
io.decode_exu.i0_ap.sll := i0_dp.sll
|
||||
io.decode_exu.i0_ap.srl := i0_dp.srl
|
||||
io.decode_exu.i0_ap.sra := i0_dp.sra
|
||||
io.decode_exu.i0_ap.slt := i0_dp.slt
|
||||
io.decode_exu.i0_ap.unsign := i0_dp.unsign
|
||||
io.decode_exu.i0_ap.beq := i0_dp.beq
|
||||
io.decode_exu.i0_ap.bne := i0_dp.bne
|
||||
io.decode_exu.i0_ap.blt := i0_dp.blt
|
||||
io.decode_exu.i0_ap.bge := i0_dp.bge
|
||||
io.decode_exu.i0_ap.clz := i0_dp.clz
|
||||
io.decode_exu.i0_ap.ctz := i0_dp.ctz
|
||||
io.decode_exu.i0_ap.pcnt := i0_dp.pcnt
|
||||
io.decode_exu.i0_ap.sext_b := i0_dp.sext_b
|
||||
io.decode_exu.i0_ap.sext_h := i0_dp.sext_h
|
||||
io.decode_exu.i0_ap.sh1add := i0_dp.sh1add
|
||||
io.decode_exu.i0_ap.sh2add := i0_dp.sh2add
|
||||
io.decode_exu.i0_ap.sh3add := i0_dp.sh3add
|
||||
io.decode_exu.i0_ap.zba := i0_dp.zba
|
||||
io.decode_exu.i0_ap.slo := i0_dp.slo
|
||||
io.decode_exu.i0_ap.sro := i0_dp.sro
|
||||
io.decode_exu.i0_ap.min := i0_dp.min
|
||||
io.decode_exu.i0_ap.max := i0_dp.max
|
||||
io.decode_exu.i0_ap.pack := i0_dp.pack
|
||||
io.decode_exu.i0_ap.packu := i0_dp.packu
|
||||
io.decode_exu.i0_ap.packh := i0_dp.packh
|
||||
io.decode_exu.i0_ap.rol := i0_dp.rol
|
||||
io.decode_exu.i0_ap.ror := i0_dp.ror
|
||||
io.decode_exu.i0_ap.grev := i0_dp.grev
|
||||
io.decode_exu.i0_ap.gorc := i0_dp.gorc
|
||||
io.decode_exu.i0_ap.zbb := i0_dp.zbb
|
||||
io.decode_exu.i0_ap.sbset := i0_dp.sbset
|
||||
io.decode_exu.i0_ap.sbclr := i0_dp.sbclr
|
||||
io.decode_exu.i0_ap.sbinv := i0_dp.sbinv
|
||||
io.decode_exu.i0_ap.sbext := i0_dp.sbext
|
||||
io.decode_exu.i0_ap.csr_write := i0_csr_write_only_d
|
||||
io.decode_exu.i0_ap.csr_imm := i0_dp.csr_imm
|
||||
io.decode_exu.i0_ap.jal := i0_jal
|
||||
|
||||
io.decode_exu.i0_ap.add := i0_dp.add
|
||||
io.decode_exu.i0_ap.sub := i0_dp.sub
|
||||
io.decode_exu.i0_ap.land := i0_dp.land
|
||||
io.decode_exu.i0_ap.lor := i0_dp.lor
|
||||
io.decode_exu.i0_ap.lxor := i0_dp.lxor
|
||||
io.decode_exu.i0_ap.sll := i0_dp.sll
|
||||
io.decode_exu.i0_ap.srl := i0_dp.srl
|
||||
io.decode_exu.i0_ap.sra := i0_dp.sra
|
||||
io.decode_exu.i0_ap.slt := i0_dp.slt
|
||||
io.decode_exu.i0_ap.unsign := i0_dp.unsign
|
||||
io.decode_exu.i0_ap.beq := i0_dp.beq
|
||||
io.decode_exu.i0_ap.bne := i0_dp.bne
|
||||
io.decode_exu.i0_ap.blt := i0_dp.blt
|
||||
io.decode_exu.i0_ap.bge := i0_dp.bge
|
||||
io.decode_exu.i0_ap.csr_write := i0_csr_write_only_d
|
||||
io.decode_exu.i0_ap.csr_imm := i0_dp.csr_imm
|
||||
io.decode_exu.i0_ap.jal := i0_jal
|
||||
|
||||
// non block load cam logic
|
||||
// val found=Wire(UInt(1.W))
|
||||
cam_wen := Mux1H((0 until LSU_NUM_NBLOAD).map(i=>(0 to i).map(j=> if(i==j) !cam(j).valid else cam(j).valid).reduce(_.asBool&_.asBool).asBool -> (cam_write << i)))
|
||||
|
@ -386,12 +303,12 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
when(nonblock_load_valid_m_delay===1.U && (io.dctl_busbuff.lsu_nonblock_load_inv_tag_r === cam(i).bits.tag) && cam(i).valid===1.U){
|
||||
cam_in(i).bits.wb := 1.U
|
||||
}
|
||||
// force debug halt forces cam valids to 0 highest priority
|
||||
// force debug halt forces cam valids to 0; highest priority
|
||||
when(io.dec_tlu_force_halt){
|
||||
cam_in(i).valid := 0.U
|
||||
}
|
||||
|
||||
cam_raw(i):=rvdffie(cam_in(i),clock,reset.asAsyncReset(),io.scan_mode)
|
||||
cam_raw(i):=withClock(io.free_clk){RegNext(cam_in(i),0.U.asTypeOf(cam(0)))}
|
||||
nonblock_load_write(i) := (load_data_tag === cam_raw(i).bits.tag) & cam_raw(i).valid
|
||||
}
|
||||
|
||||
|
@ -430,7 +347,6 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
( csr_read & csr_write).asBool -> CSRRW,
|
||||
(!csr_read & csr_write).asBool -> CSRWRITE,
|
||||
( csr_read & !csr_write).asBool -> CSRREAD,
|
||||
(i0_dp.zbb | i0_dp.zbs | i0_dp.zbe | i0_dp.zbc | i0_dp.zbp | i0_dp.zbr | i0_dp.zbf | i0_dp.zba) -> BITMANIPU,
|
||||
i0_dp.pm_alu -> ALU,
|
||||
i0_dp.store -> STORE,
|
||||
i0_dp.load -> LOAD,
|
||||
|
@ -445,8 +361,10 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
|
||||
// can't make this clock active_clock
|
||||
leak1_i1_stall_in := (io.dec_tlu_flush_leak_one_r | (leak1_i1_stall & !io.dec_tlu_flush_lower_r))
|
||||
leak1_i1_stall := withClock(data_gate_clk){RegNext(leak1_i1_stall_in,0.U)}
|
||||
leak1_mode := leak1_i1_stall
|
||||
leak1_i0_stall_in := ((io.dec_i0_decode_d & leak1_i1_stall) | (leak1_i0_stall & !io.dec_tlu_flush_lower_r))
|
||||
leak1_i0_stall_in := ((io.dec_aln.dec_i0_decode_d & leak1_i1_stall) | (leak1_i0_stall & !io.dec_tlu_flush_lower_r))
|
||||
leak1_i0_stall := withClock(data_gate_clk){RegNext(leak1_i0_stall_in,0.U)}
|
||||
|
||||
// 12b jal's can be predicted - these are calls
|
||||
|
||||
|
@ -474,23 +392,8 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
io.decode_exu.mul_p.bits.rs1_sign := i0_dp.rs1_sign
|
||||
io.decode_exu.mul_p.bits.rs2_sign := i0_dp.rs2_sign
|
||||
io.decode_exu.mul_p.bits.low := i0_dp.low
|
||||
io.decode_exu.mul_p.bits.bext := i0_dp.bext
|
||||
io.decode_exu.mul_p.bits.bdep := i0_dp.bdep
|
||||
io.decode_exu.mul_p.bits.clmul := i0_dp.clmul
|
||||
io.decode_exu.mul_p.bits.clmulh := i0_dp.clmulh
|
||||
io.decode_exu.mul_p.bits.clmulr := i0_dp.clmulr
|
||||
io.decode_exu.mul_p.bits.grev := i0_dp.grev
|
||||
io.decode_exu.mul_p.bits.gorc := i0_dp.gorc
|
||||
io.decode_exu.mul_p.bits.shfl := i0_dp.shfl
|
||||
io.decode_exu.mul_p.bits.unshfl := i0_dp.unshfl
|
||||
io.decode_exu.mul_p.bits.crc32_b := i0_dp.crc32_b
|
||||
io.decode_exu.mul_p.bits.crc32_h := i0_dp.crc32_h
|
||||
io.decode_exu.mul_p.bits.crc32_w := i0_dp.crc32_w
|
||||
io.decode_exu.mul_p.bits.crc32c_b := i0_dp.crc32c_b
|
||||
io.decode_exu.mul_p.bits.crc32c_h := i0_dp.crc32c_h
|
||||
io.decode_exu.mul_p.bits.crc32c_w := i0_dp.crc32c_w
|
||||
io.decode_exu.mul_p.bits.bfp := i0_dp.bfp
|
||||
|
||||
io.decode_exu.dec_extint_stall := withClock(data_gate_clk){RegNext(io.dec_tlu_flush_extint,0.U)}
|
||||
|
||||
io.lsu_p := 0.U.asTypeOf(io.lsu_p)
|
||||
when (io.decode_exu.dec_extint_stall){
|
||||
|
@ -498,8 +401,6 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
io.lsu_p.bits.word := 1.U(1.W)
|
||||
io.lsu_p.bits.fast_int := 1.U(1.W)
|
||||
io.lsu_p.valid := 1.U(1.W)
|
||||
|
||||
|
||||
}.otherwise {
|
||||
io.lsu_p.valid := lsu_decode_d
|
||||
io.lsu_p.bits.load := i0_dp.load
|
||||
|
@ -507,7 +408,6 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
io.lsu_p.bits.by := i0_dp.by
|
||||
io.lsu_p.bits.half := i0_dp.half
|
||||
io.lsu_p.bits.word := i0_dp.word
|
||||
io.lsu_p.bits.stack := (i0r.rs1 === 2.U(5.W)) // stack reference
|
||||
io.lsu_p.bits.load_ldst_bypass_d := load_ldst_bypass_d
|
||||
io.lsu_p.bits.store_data_bypass_d := store_data_bypass_d
|
||||
io.lsu_p.bits.store_data_bypass_m := store_data_bypass_m
|
||||
|
@ -515,8 +415,8 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
io.dec_alu.dec_csr_ren_d := i0_dp.csr_read & io.dec_ib0_valid_d//H: ing csr read enable signal decoded from decode_ctl going as input to EXU
|
||||
csr_ren_qual_d := i0_dp.csr_read & i0_legal_decode_d.asBool //csr_ren_qual_d ed as csr_read above
|
||||
io.dec_alu.dec_csr_ren_d := i0_dp.csr_read //H: assigning csr read enable signal decoded from decode_ctl going as input to EXU
|
||||
csr_ren_qual_d := i0_dp.csr_read & i0_legal_decode_d.asBool //csr_ren_qual_d assigned as csr_read above
|
||||
|
||||
val i0_csr_write = i0_dp.csr_write & !io.dec_debug_fence_d
|
||||
val csr_clr_d = i0_dp.csr_clr & i0_legal_decode_d.asBool
|
||||
|
@ -524,19 +424,18 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
val csr_write_d = i0_csr_write & i0_legal_decode_d.asBool
|
||||
|
||||
i0_csr_write_only_d := i0_csr_write & !i0_dp.csr_read
|
||||
io.dec_csr_wen_unq_d := (i0_dp.csr_clr | i0_dp.csr_set | i0_csr_write) & io.dec_ib0_valid_d // for csr legal, can't write read-only csr
|
||||
//dec_csr_wen_unq_d ed as csr_write above
|
||||
val any_csr_d = i0_dp.csr_read | i0_csr_write
|
||||
io.dec_csr_any_unq_d := any_csr_d & io.dec_ib0_valid_d
|
||||
io.dec_csr_rdaddr_d := Fill(12,io.dec_csr_any_unq_d) & i0(31,20)
|
||||
io.dec_csr_wraddr_r := Fill(12,(r_d.bits.csrwen & r_d.valid)) & r_d.bits.csrwaddr //r_d is a dest_pkt
|
||||
io.dec_csr_wen_unq_d := (i0_dp.csr_clr | i0_dp.csr_set | i0_csr_write) // for csr legal, can't write read-only csr
|
||||
//dec_csr_wen_unq_d assigned as csr_write above
|
||||
|
||||
io.dec_csr_rdaddr_d := i0(31,20)
|
||||
io.dec_csr_wraddr_r := r_d.bits.csrwaddr //r_d is a dest_pkt
|
||||
|
||||
// make sure csr doesn't write same cycle as dec_tlu_flush_lower_wb
|
||||
// also use valid so it's flushable
|
||||
io.dec_csr_wen_r := r_d.bits.csrwen & r_d.valid & !io.dec_tlu_i0_kill_writeb_r
|
||||
io.dec_csr_wen_r := r_d.bits.csrwen & r_d.valid & !io.dec_tlu_i0_kill_writeb_r;
|
||||
|
||||
// If we are writing MIE or MSTATUS, hold off the external interrupt for a cycle on the write.
|
||||
io.dec_csr_stall_int_ff := ((r_d.bits.csrwaddr === "h300".U) | (r_d.bits.csrwaddr === "h304".U)) & r_d.bits.csrwen & r_d.valid & !io.dec_tlu_i0_kill_writeb_wb
|
||||
io.dec_csr_stall_int_ff := ((r_d.bits.csrwaddr === "h300".U) | (r_d.bits.csrwaddr === "h304".U)) & r_d.bits.csrwen & r_d.valid & !io.dec_tlu_i0_kill_writeb_wb;
|
||||
|
||||
val csr_read_x = withClock(io.active_clk){RegNext(csr_ren_qual_d,init=0.B)}
|
||||
val csr_clr_x = withClock(io.active_clk){RegNext(csr_clr_d, init=0.B)}
|
||||
|
@ -545,8 +444,8 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
val csr_imm_x = withClock(io.active_clk){RegNext(i0_dp.csr_imm, init=0.U)}
|
||||
|
||||
// perform the update operation if any
|
||||
val csrimm_x = rvdffe(i0(19,15),i0_x_data_en & any_csr_d.asBool,clock,io.scan_mode)
|
||||
val csr_rddata_x = rvdffe(io.dec_csr_rddata_d,i0_x_data_en & any_csr_d.asBool,clock,io.scan_mode)
|
||||
val csrimm_x = rvdffe(i0(19,15),i0_x_data_en.asBool,clock,io.scan_mode)
|
||||
val csr_rddata_x = rvdffe(io.dec_csr_rddata_d,i0_x_data_en.asBool,clock,io.scan_mode)
|
||||
|
||||
val csr_mask_x = Mux1H(Seq(
|
||||
csr_imm_x.asBool -> Cat(repl(27,0.U),csrimm_x(4,0)),
|
||||
|
@ -559,7 +458,10 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
// pause instruction
|
||||
val clear_pause = (io.dec_tlu_flush_lower_r & !io.dec_tlu_flush_pause_r) | (pause_state & (write_csr_data === Cat(Fill(31,0.U),write_csr_data(0)))) // if 0 or 1 then exit pause state - 1 cycle pause
|
||||
pause_state_in := (io.dec_tlu_wr_pause_r | pause_state) & !clear_pause
|
||||
pause_state := withClock(data_gate_clk){RegNext(pause_state_in, 0.U)}
|
||||
io.dec_pause_state := pause_state
|
||||
tlu_wr_pause_r1 := withClock(data_gate_clk){RegNext(io.dec_tlu_wr_pause_r, 0.U)}
|
||||
tlu_wr_pause_r2 := withClock(data_gate_clk){RegNext(tlu_wr_pause_r1, 0.U)}
|
||||
//pause for clock gating
|
||||
io.dec_pause_state_cg := (pause_state & (!tlu_wr_pause_r1 && !tlu_wr_pause_r2))
|
||||
// end pause
|
||||
|
@ -567,15 +469,15 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
val write_csr_data_in = Mux(pause_state,(write_csr_data - 1.U(32.W)),
|
||||
Mux(io.dec_tlu_wr_pause_r,io.dec_csr_wrdata_r,write_csr_data_x))
|
||||
val csr_data_wen = ((csr_clr_x | csr_set_x | csr_write_x) & csr_read_x) | io.dec_tlu_wr_pause_r | pause_state
|
||||
write_csr_data := rvdffe(write_csr_data_in,csr_data_wen,io.free_l2clk,io.scan_mode)
|
||||
write_csr_data := rvdffe(write_csr_data_in,csr_data_wen,clock,io.scan_mode)
|
||||
|
||||
// will hold until write-back at which time the CSR will be updated while GPR is possibly written with prior CSR
|
||||
val pause_stall = pause_state
|
||||
|
||||
// for csr write only data is produced by the alu
|
||||
io.dec_csr_wrdata_r := Mux((r_d.bits.csrwonly & r_d.valid).asBool,i0_result_corr_r,write_csr_data)
|
||||
io.dec_csr_wrdata_r := Mux(r_d.bits.csrwonly.asBool,i0_result_corr_r,write_csr_data)
|
||||
|
||||
val prior_csr_write = x_d.bits.csrwonly | r_d.bits.csrwonly | wbd.bits.csrwonly
|
||||
val prior_csr_write = x_d.bits.csrwonly | r_d.bits.csrwonly | wbd.bits.csrwonly;
|
||||
|
||||
val debug_fence_i = io.dec_debug_fence_d & io.dbg_dctl.dbg_cmd_wrdata(0)
|
||||
val debug_fence_raw = io.dec_debug_fence_d & io.dbg_dctl.dbg_cmd_wrdata(1)
|
||||
|
@ -586,15 +488,18 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
|
||||
// some CSR writes need to be postsync'd
|
||||
val i0_postsync = i0_dp.postsync | io.dec_tlu_postsync_d | debug_fence_i | (i0_csr_write_only_d & (i0(31,20) === "h7c2".U))
|
||||
val bitmanip_legal = WireInit(Bool(),0.B)
|
||||
val i0_legal = i0_dp.legal & (!any_csr_d | io.dec_csr_legal_d) & bitmanip_legal
|
||||
|
||||
val any_csr_d = i0_dp.csr_read | i0_csr_write
|
||||
io.dec_csr_any_unq_d := any_csr_d
|
||||
val i0_legal = i0_dp.legal & (!any_csr_d | io.dec_csr_legal_d)
|
||||
val i0_inst_d = Mux(io.dec_i0_pc4_d,i0,Cat(repl(16,0.U), io.dec_aln.ifu_i0_cinst))
|
||||
// illegal inst handling
|
||||
|
||||
val shift_illegal = io.dec_i0_decode_d & !i0_legal//lm: valid but not legal
|
||||
val shift_illegal = io.dec_aln.dec_i0_decode_d & !i0_legal//lm: valid but not legal
|
||||
val illegal_inst_en = shift_illegal & !illegal_lockout
|
||||
io.dec_illegal_inst := rvdffe(i0_inst_d,illegal_inst_en,clock,io.scan_mode)
|
||||
illegal_lockout_in := (shift_illegal | illegal_lockout) & !flush_final_r
|
||||
illegal_lockout := withClock(data_gate_clk){RegNext(illegal_lockout_in, 0.U)}
|
||||
val i0_div_prior_div_stall = i0_dp.div & io.dec_div_active
|
||||
//stalls signals
|
||||
val i0_block_raw_d = (i0_dp.csr_read & prior_csr_write) | io.decode_exu.dec_extint_stall | pause_stall |
|
||||
|
@ -608,15 +513,15 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
val i0_exublock_d = i0_block_raw_d
|
||||
|
||||
//decode valid
|
||||
io.dec_i0_decode_d := io.dec_ib0_valid_d & !i0_block_d & !io.dec_tlu_flush_lower_r & !flush_final_r
|
||||
io.dec_aln.dec_i0_decode_d := io.dec_ib0_valid_d & !i0_block_d & !io.dec_tlu_flush_lower_r & !flush_final_r
|
||||
val i0_exudecode_d = io.dec_ib0_valid_d & !i0_exublock_d & !io.dec_tlu_flush_lower_r & !flush_final_r
|
||||
val i0_exulegal_decode_d = i0_exudecode_d & i0_legal
|
||||
|
||||
// performance monitor signals
|
||||
io.dec_pmu_instr_decoded := io.dec_i0_decode_d
|
||||
io.dec_pmu_decode_stall := io.dec_ib0_valid_d & !io.dec_i0_decode_d
|
||||
io.dec_pmu_postsync_stall := postsync_stall.asBool & io.dec_ib0_valid_d
|
||||
io.dec_pmu_presync_stall := presync_stall.asBool & io.dec_ib0_valid_d
|
||||
io.dec_pmu_instr_decoded := io.dec_aln.dec_i0_decode_d
|
||||
io.dec_pmu_decode_stall := io.dec_ib0_valid_d & !io.dec_aln.dec_i0_decode_d
|
||||
io.dec_pmu_postsync_stall := postsync_stall.asBool
|
||||
io.dec_pmu_presync_stall := presync_stall.asBool
|
||||
|
||||
val prior_inflight_x = x_d.valid
|
||||
val prior_inflight_wb = r_d.valid
|
||||
|
@ -624,22 +529,22 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
val prior_inflight_eff = Mux(i0_dp.div,prior_inflight_x,prior_inflight)
|
||||
|
||||
presync_stall := (i0_presync & prior_inflight_eff)
|
||||
postsync_stall := withClock(data_gate_clk){RegNext(ps_stall_in, 0.U)}
|
||||
// illegals will postsync
|
||||
ps_stall_in := (io.dec_i0_decode_d & (i0_postsync | !i0_legal) ) | ( postsync_stall & prior_inflight_x)
|
||||
ps_stall_in := (io.dec_aln.dec_i0_decode_d & (i0_postsync | !i0_legal) ) | ( postsync_stall & prior_inflight_x)
|
||||
|
||||
io.dec_alu.dec_i0_alu_decode_d := i0_exulegal_decode_d & i0_dp.alu
|
||||
io.decode_exu.dec_i0_branch_d := i0_dp.condbr | i0_dp.jal | i0_br_error_all
|
||||
|
||||
lsu_decode_d := i0_legal_decode_d & i0_dp.lsu
|
||||
mul_decode_d := i0_exulegal_decode_d & i0_dp.mul
|
||||
div_decode_d := i0_exulegal_decode_d & i0_dp.div
|
||||
io.decode_exu.dec_qual_lsu_d := i0_dp.lsu
|
||||
|
||||
io.dec_tlu_i0_valid_r := r_d.valid & !io.dec_tlu_flush_lower_wb
|
||||
|
||||
//traps for TLU (tlu stuff)
|
||||
d_t.legal := i0_legal_decode_d
|
||||
d_t.icaf := i0_icaf_d & i0_legal_decode_d // dbecc is icaf exception
|
||||
d_t.icaf_second := io.dec_i0_icaf_second_d & i0_legal_decode_d // this includes icaf and dbecc
|
||||
d_t.icaf_f1 := io.dec_i0_icaf_f1_d & i0_legal_decode_d // this includes icaf and dbecc
|
||||
d_t.icaf_type := io.dec_i0_icaf_type_d
|
||||
|
||||
d_t.fence_i := (i0_dp.fence_i | debug_fence_i) & i0_legal_decode_d
|
||||
|
@ -649,15 +554,17 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
d_t.pmu_divide := 0.U(1.W)
|
||||
d_t.pmu_lsu_misaligned := 0.U(1.W)
|
||||
|
||||
d_t.i0trigger := io.dec_i0_trigger_match_d & repl(4,io.dec_i0_decode_d)
|
||||
d_t.i0trigger := io.dec_i0_trigger_match_d & repl(4,io.dec_aln.dec_i0_decode_d)
|
||||
|
||||
|
||||
x_t := rvdfflie(d_t,clock,reset.asAsyncReset,i0_x_ctl_en.asBool,io.scan_mode, elements = 3)
|
||||
x_t := rvdffe(d_t,i0_x_ctl_en.asBool,clock,io.scan_mode)
|
||||
|
||||
x_t_in := x_t
|
||||
x_t_in.i0trigger := x_t.i0trigger & ~(repl(4,io.dec_tlu_flush_lower_wb))
|
||||
|
||||
r_t := rvdfflie(x_t_in,clock,reset.asAsyncReset,i0_x_ctl_en.asBool,io.scan_mode, elements = 3)
|
||||
r_t := rvdffe(x_t_in,i0_x_ctl_en.asBool,clock,io.scan_mode)
|
||||
val lsu_trigger_match_r = RegNext(io.lsu_trigger_match_m, 0.U)
|
||||
val lsu_pmu_misaligned_r = RegNext(io.lsu_pmu_misaligned_m, 0.U)
|
||||
|
||||
r_t_in := r_t
|
||||
|
||||
|
@ -670,10 +577,11 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
io.dec_tlu_packet_r.pmu_divide := r_d.bits.i0div & r_d.valid
|
||||
// end tlu stuff
|
||||
|
||||
flush_final_r := withClock(data_gate_clk){RegNext(io.exu_flush_final, 0.U)}
|
||||
|
||||
io.dec_i0_decode_d := io.dec_ib0_valid_d & !i0_block_d & !io.dec_tlu_flush_lower_r & !flush_final_r
|
||||
io.dec_aln.dec_i0_decode_d := io.dec_ib0_valid_d & !i0_block_d & !io.dec_tlu_flush_lower_r & !flush_final_r
|
||||
|
||||
i0r.rs1 := i0(19,15) //H: ing reg packets the instructions bits
|
||||
i0r.rs1 := i0(19,15) //H: assigning reg packets the instructions bits
|
||||
i0r.rs2 := i0(24,20)
|
||||
i0r.rd := i0(11,7)
|
||||
|
||||
|
@ -686,74 +594,18 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
val i0_jalimm20 = i0_dp.jal & i0_dp.imm20 // H:jal (used at line 915)
|
||||
val i0_uiimm20 = !i0_dp.jal & i0_dp.imm20
|
||||
|
||||
// io.decode_exu.dec_i0_immed_d := Mux1H(Seq(
|
||||
// i0_dp.csr_read -> io.dec_csr_rddata_d,
|
||||
// !i0_dp.csr_read -> i0_immed_d))
|
||||
|
||||
io.decode_exu.dec_i0_immed_d := Mux1H(Seq(
|
||||
i0_dp.csr_read -> io.dec_csr_rddata_d,
|
||||
!i0_dp.csr_read -> i0_immed_d))
|
||||
|
||||
i0_immed_d := Mux1H(Seq(
|
||||
i0_dp.imm12 -> Cat(repl(20,i0(31)),i0(31,20)), // jalr
|
||||
i0_dp.shimm5 -> Cat(repl(27,0.U),i0(24,20)),
|
||||
i0_jalimm20 -> Cat(repl(12,i0(31)),i0(19,12),i0(20),i0(30,21),0.U),
|
||||
i0_uiimm20 -> Cat(i0(31,12),repl(12,0.U)),
|
||||
(i0_csr_write_only_d & i0_dp.csr_imm).asBool -> Cat(repl(27,0.U),i0(19,15)))) // for csr's that only write
|
||||
|
||||
val bitmanip_zbb_legal = WireInit(Bool(),0.B)
|
||||
val bitmanip_zbs_legal = WireInit(Bool(),0.B)
|
||||
val bitmanip_zbe_legal = WireInit(Bool(),0.B)
|
||||
val bitmanip_zbc_legal = WireInit(Bool(),0.B)
|
||||
val bitmanip_zbp_legal = WireInit(Bool(),0.B)
|
||||
val bitmanip_zbr_legal = WireInit(Bool(),0.B)
|
||||
val bitmanip_zbf_legal = WireInit(Bool(),0.B)
|
||||
val bitmanip_zba_legal = WireInit(Bool(),0.B)
|
||||
val bitmanip_zbb_zbp_legal = WireInit(Bool(),0.B)
|
||||
|
||||
if (BITMANIP_ZBB == 1)
|
||||
bitmanip_zbb_legal := 1.B
|
||||
else
|
||||
bitmanip_zbb_legal := !(i0_dp.zbb & !i0_dp.zbp)
|
||||
|
||||
if (BITMANIP_ZBS == 1)
|
||||
bitmanip_zbs_legal := 1.B
|
||||
else
|
||||
bitmanip_zbs_legal := !i0_dp.zbs
|
||||
|
||||
if (BITMANIP_ZBE == 1)
|
||||
bitmanip_zbe_legal := 1.B
|
||||
else
|
||||
bitmanip_zbe_legal := !i0_dp.zbe
|
||||
|
||||
if (BITMANIP_ZBC == 1)
|
||||
bitmanip_zbc_legal := 1.B
|
||||
else
|
||||
bitmanip_zbc_legal := !i0_dp.zbc
|
||||
|
||||
if (BITMANIP_ZBP == 1)
|
||||
bitmanip_zbp_legal := 1.B
|
||||
else
|
||||
bitmanip_zbp_legal := !(i0_dp.zbp & !i0_dp.zbb)
|
||||
|
||||
if (BITMANIP_ZBR == 1)
|
||||
bitmanip_zbr_legal := 1.B
|
||||
else
|
||||
bitmanip_zbr_legal := !i0_dp.zbr
|
||||
|
||||
if (BITMANIP_ZBF == 1)
|
||||
bitmanip_zbf_legal := 1.B
|
||||
else
|
||||
bitmanip_zbf_legal := !i0_dp.zbf
|
||||
|
||||
if (BITMANIP_ZBA == 1)
|
||||
bitmanip_zba_legal := 1.B
|
||||
else
|
||||
bitmanip_zba_legal := !i0_dp.zba
|
||||
|
||||
if ( (BITMANIP_ZBB == 1) | (BITMANIP_ZBP == 1) )
|
||||
bitmanip_zbb_zbp_legal := 1.B
|
||||
else
|
||||
bitmanip_zbb_zbp_legal := !(i0_dp.zbb & i0_dp.zbp)
|
||||
|
||||
bitmanip_legal := bitmanip_zbb_legal & bitmanip_zbs_legal & bitmanip_zbe_legal & bitmanip_zbc_legal & bitmanip_zbp_legal & bitmanip_zbr_legal & bitmanip_zbf_legal & bitmanip_zba_legal & bitmanip_zbb_zbp_legal
|
||||
i0_legal_decode_d := io.dec_i0_decode_d & i0_legal
|
||||
i0_legal_decode_d := io.dec_aln.dec_i0_decode_d & i0_legal
|
||||
|
||||
i0_d_c.mul := i0_dp.mul & i0_legal_decode_d
|
||||
i0_d_c.load := i0_dp.load & i0_legal_decode_d
|
||||
|
@ -761,7 +613,7 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
|
||||
val i0_x_c = withClock(io.active_clk){RegEnable(i0_d_c,0.U.asTypeOf(i0_d_c), i0_x_ctl_en.asBool)}
|
||||
val i0_r_c = withClock(io.active_clk){RegEnable(i0_x_c,0.U.asTypeOf(i0_x_c), i0_r_ctl_en.asBool)}
|
||||
i0_pipe_en := Cat(io.dec_i0_decode_d,withClock(io.active_clk){RegNext(i0_pipe_en(3,1), init=0.U)})
|
||||
i0_pipe_en := Cat(io.dec_aln.dec_i0_decode_d,withClock(io.active_clk){RegNext(i0_pipe_en(3,1), init=0.U)})
|
||||
|
||||
i0_x_ctl_en := (i0_pipe_en(3,2).orR | io.clk_override)
|
||||
i0_r_ctl_en := (i0_pipe_en(2,1).orR | io.clk_override)
|
||||
|
@ -769,29 +621,30 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
i0_x_data_en := ( i0_pipe_en(3) | io.clk_override)
|
||||
i0_r_data_en := ( i0_pipe_en(2) | io.clk_override)
|
||||
i0_wb_data_en := ( i0_pipe_en(1) | io.clk_override)
|
||||
i0_wb1_data_en := ( i0_pipe_en(0) | io.clk_override)
|
||||
|
||||
io.decode_exu.dec_data_en := Cat(i0_x_data_en, i0_r_data_en)
|
||||
io.decode_exu.dec_ctl_en := Cat(i0_x_ctl_en, i0_r_ctl_en)
|
||||
|
||||
d_d.bits.i0rd := i0r.rd
|
||||
d_d.bits.i0v := i0_rd_en_d & i0_legal_decode_d
|
||||
d_d.valid := io.dec_i0_decode_d // has flush_final_r
|
||||
d_d.valid := io.dec_aln.dec_i0_decode_d // has flush_final_r
|
||||
|
||||
d_d.bits.i0load := i0_dp.load & i0_legal_decode_d
|
||||
d_d.bits.i0store := i0_dp.store & i0_legal_decode_d
|
||||
d_d.bits.i0div := i0_dp.div & i0_legal_decode_d
|
||||
|
||||
d_d.bits.csrwen := io.dec_csr_wen_unq_d & i0_legal_decode_d
|
||||
d_d.bits.csrwonly := i0_csr_write_only_d & io.dec_i0_decode_d
|
||||
d_d.bits.csrwaddr := Mux(d_d.bits.csrwen, i0(31,20), 0.U)
|
||||
d_d.bits.csrwonly := i0_csr_write_only_d & io.dec_aln.dec_i0_decode_d
|
||||
d_d.bits.csrwaddr := i0(31,20)
|
||||
|
||||
x_d := rvdfflie(d_d,clock,reset.asAsyncReset(), i0_x_ctl_en.asBool,io.scan_mode,elements = 4)
|
||||
x_d := rvdffe(d_d, i0_x_ctl_en.asBool,clock,io.scan_mode)
|
||||
val x_d_in = Wire(Valid(new dest_pkt_t))
|
||||
x_d_in := x_d
|
||||
x_d_in.bits.i0v := x_d.bits.i0v & !io.dec_tlu_flush_lower_wb & !io.dec_tlu_flush_lower_r
|
||||
x_d_in.valid := x_d.valid & !io.dec_tlu_flush_lower_wb & !io.dec_tlu_flush_lower_r
|
||||
|
||||
r_d := rvdfflie(x_d_in,clock,reset.asAsyncReset(),i0_r_ctl_en.asBool,io.scan_mode, elements = 4)
|
||||
r_d := rvdffe(x_d_in,i0_r_ctl_en.asBool,clock,io.scan_mode)
|
||||
r_d_in := r_d
|
||||
r_d_in.bits.i0rd := r_d.bits.i0rd
|
||||
|
||||
|
@ -800,15 +653,14 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
r_d_in.bits.i0load := r_d.bits.i0load & !io.dec_tlu_flush_lower_wb
|
||||
r_d_in.bits.i0store := r_d.bits.i0store & !io.dec_tlu_flush_lower_wb
|
||||
|
||||
wbd := rvdfflie(r_d_in,clock,reset.asAsyncReset(),i0_wb_ctl_en.asBool,io.scan_mode, elements = 4)
|
||||
wbd := rvdffe(r_d_in,i0_wb_ctl_en.asBool,clock,io.scan_mode)
|
||||
|
||||
io.dec_i0_waddr_r := r_d_in.bits.i0rd
|
||||
i0_wen_r := r_d_in.bits.i0v & !io.dec_tlu_i0_kill_writeb_r
|
||||
io.dec_i0_wen_r := i0_wen_r & !r_d_in.bits.i0div & !i0_load_kill_wen_r // don't write a nonblock load 1st time down the pipe
|
||||
io.dec_i0_wdata_r := i0_result_corr_r
|
||||
|
||||
|
||||
val i0_result_r_raw = rvdffe(i0_result_x,(i0_r_data_en & (x_d.bits.i0v | x_d.bits.csrwen | debug_valid_x)) === 1.B,clock,io.scan_mode)
|
||||
val i0_result_r_raw = rvdffe(i0_result_x,i0_r_data_en.asBool,clock,io.scan_mode)
|
||||
if ( LOAD_TO_USE_PLUS1) {
|
||||
i0_result_x := io.decode_exu.exu_i0_result_x
|
||||
i0_result_r := Mux((r_d.bits.i0v & r_d.bits.i0load).asBool,io.lsu_result_m, i0_result_r_raw)
|
||||
|
@ -842,32 +694,31 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
io.dec_div.dec_div_cancel := nonblock_div_cancel.asBool
|
||||
val i0_div_decode_d = i0_legal_decode_d & i0_dp.div
|
||||
|
||||
div_active_in := i0_div_decode_d | (io.dec_div_active & !io.exu_div_wren & !nonblock_div_cancel)
|
||||
val div_active_in = i0_div_decode_d | (io.dec_div_active & !io.exu_div_wren & !nonblock_div_cancel)
|
||||
|
||||
// io.dec_div_active := withClock(io.free_l2clk){RegNext(div_active_in, 0.U)}
|
||||
io.dec_div_active := withClock(io.free_clk){RegNext(div_active_in, 0.U)}
|
||||
|
||||
// nonblocking div scheme
|
||||
i0_nonblock_div_stall := (io.decode_exu.dec_i0_rs1_en_d & io.dec_div_active & (io.div_waddr_wb === i0r.rs1)) |
|
||||
(io.decode_exu.dec_i0_rs2_en_d & io.dec_div_active & (io.div_waddr_wb === i0r.rs2))
|
||||
|
||||
|
||||
io.div_waddr_wb := RegEnable(i0r.rd,0.U,i0_div_decode_d.asBool)
|
||||
///div end
|
||||
|
||||
//for tracing instruction
|
||||
val i0_wb_en = i0_wb_data_en
|
||||
val trace_enable = ~io.dec_tlu_trace_disable
|
||||
val i0_wb1_en = i0_wb1_data_en
|
||||
|
||||
io.div_waddr_wb := rvdffe(i0r.rd,i0_div_decode_d.asBool(),clock,io.scan_mode)
|
||||
|
||||
val i0_inst_x = rvdffe(i0_inst_d,(i0_x_data_en & trace_enable),clock,io.scan_mode)
|
||||
val i0_inst_r = rvdffe(i0_inst_x,(i0_r_data_en & trace_enable),clock,io.scan_mode)
|
||||
val div_inst = rvdffe(i0_inst_d(24,7),i0_div_decode_d.asBool,clock,io.scan_mode)
|
||||
val i0_inst_x = rvdffe(i0_inst_d,i0_x_data_en.asBool,clock,io.scan_mode)
|
||||
val i0_inst_r = rvdffe(i0_inst_x,i0_r_data_en.asBool,clock,io.scan_mode)
|
||||
val i0_inst_wb_in = i0_inst_r
|
||||
val i0_inst_wb = rvdffe(i0_inst_wb_in,(i0_wb_en & trace_enable),clock,io.scan_mode)
|
||||
val i0_pc_wb = rvdffe(io.dec_tlu_i0_pc_r,(i0_wb_en & trace_enable),clock,io.scan_mode)
|
||||
val i0_inst_wb = rvdffe(i0_inst_wb_in,i0_wb_en.asBool,clock,io.scan_mode)
|
||||
io.dec_i0_inst_wb1 := rvdffe(i0_inst_wb,i0_wb1_en.asBool,clock,io.scan_mode)
|
||||
val i0_pc_wb = rvdffe(io.dec_tlu_i0_pc_r,i0_wb_en.asBool,clock,io.scan_mode)
|
||||
|
||||
io.dec_i0_inst_wb := i0_inst_wb
|
||||
io.dec_i0_pc_wb := i0_pc_wb
|
||||
val dec_i0_pc_r = rvdffpcie(io.dec_alu.exu_i0_pc_x,i0_r_data_en.asBool,reset.asAsyncReset(),clock,io.scan_mode)
|
||||
io.dec_i0_pc_wb1 := rvdffe(i0_pc_wb,i0_wb1_en.asBool,clock,io.scan_mode)
|
||||
val dec_i0_pc_r = rvdffe(io.dec_alu.exu_i0_pc_x,i0_r_data_en.asBool,clock,io.scan_mode)
|
||||
|
||||
io.dec_tlu_i0_pc_r := dec_i0_pc_r
|
||||
|
||||
|
@ -913,13 +764,22 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
|
|||
|
||||
i0_rs2bypass := Cat((i0_rs2_depth_d(0) & (i0_rs2_class_d.alu | i0_rs2_class_d.mul)),(i0_rs2_depth_d(0) & (i0_rs2_class_d.load)),(i0_rs2_depth_d(1) & (i0_rs2_class_d.alu | i0_rs2_class_d.mul | i0_rs2_class_d.load)))
|
||||
|
||||
io.decode_exu.dec_i0_rs1_bypass_en_d := Cat(!i0_rs1bypass(0) & !i0_rs1bypass(1) & !i0_rs1bypass(2) & i0_rs1_nonblock_load_bypass_en_d,i0_rs1bypass(2),i0_rs1bypass(1),i0_rs1bypass(0) )
|
||||
io.decode_exu.dec_i0_rs2_bypass_en_d := Cat(!i0_rs2bypass(0) & !i0_rs2bypass(1) & !i0_rs2bypass(2) & i0_rs2_nonblock_load_bypass_en_d,i0_rs2bypass(2),i0_rs2bypass(1),i0_rs2bypass(0) )
|
||||
io.decode_exu.dec_i0_rs1_bypass_en_d := Cat(i0_rs1bypass(2),(i0_rs1bypass(1) | i0_rs1bypass(0) | (!i0_rs1bypass(2) & i0_rs1_nonblock_load_bypass_en_d)))
|
||||
io.decode_exu.dec_i0_rs2_bypass_en_d := Cat(i0_rs2bypass(2),(i0_rs2bypass(1) | i0_rs2bypass(0) | (!i0_rs2bypass(2) & i0_rs2_nonblock_load_bypass_en_d)))
|
||||
|
||||
io.decode_exu.dec_i0_result_r := i0_result_r
|
||||
|
||||
io.decode_exu.dec_i0_rs1_bypass_data_d := Mux1H(Seq(
|
||||
i0_rs1bypass(1).asBool -> io.lsu_result_m,
|
||||
i0_rs1bypass(0).asBool -> i0_result_r,
|
||||
(!i0_rs1bypass(1) & !i0_rs1bypass(0) & i0_rs1_nonblock_load_bypass_en_d).asBool -> io.dctl_busbuff.lsu_nonblock_load_data,
|
||||
))
|
||||
io.decode_exu.dec_i0_rs2_bypass_data_d := Mux1H(Seq(
|
||||
i0_rs2bypass(1).asBool -> io.lsu_result_m,
|
||||
i0_rs2bypass(0).asBool -> i0_result_r,
|
||||
(!i0_rs2bypass(1) & !i0_rs2bypass(0) & i0_rs2_nonblock_load_bypass_en_d).asBool -> io.dctl_busbuff.lsu_nonblock_load_data,
|
||||
))
|
||||
io.dec_lsu_valid_raw_d := ((io.dec_ib0_valid_d & (i0_dp_raw.load | i0_dp_raw.store) & !io.dctl_dma.dma_dccm_stall_any & !i0_block_raw_d) | io.decode_exu.dec_extint_stall)
|
||||
io.dec_lsu_offset_d := Mux1H(Seq(
|
||||
(!io.decode_exu.dec_extint_stall & i0_dp.lsu & i0_dp.load).asBool -> i0(31,20),
|
||||
(!io.decode_exu.dec_extint_stall & i0_dp.lsu & i0_dp.store).asBool -> Cat(i0(31,25),i0(11,7))))
|
||||
}
|
||||
}
|
|
@ -47,20 +47,20 @@ class dec_gpr_ctl extends Module with lib with RequireAsyncReset{
|
|||
gpr_in(0):=0.U
|
||||
io.gpr_exu.gpr_i0_rs1_d:=0.U
|
||||
io.gpr_exu.gpr_i0_rs2_d:=0.U
|
||||
// GPR Write logic
|
||||
for (j <-1 until 32){
|
||||
w0v(j) := io.wen0 & (io.waddr0===j.asUInt)
|
||||
w1v(j) := io.wen1 & (io.waddr1===j.asUInt)
|
||||
w2v(j) := io.wen2 & (io.waddr2===j.asUInt)
|
||||
gpr_in(j) := (Fill(32,w0v(j)) & io.wd0) | (Fill(32,w1v(j)) & io.wd1) | (Fill(32,w2v(j)) & io.wd2)
|
||||
}
|
||||
// GPR Write logic
|
||||
for (j <-1 until 32){
|
||||
w0v(j) := io.wen0 & (io.waddr0===j.asUInt)
|
||||
w1v(j) := io.wen1 & (io.waddr1===j.asUInt)
|
||||
w2v(j) := io.wen2 & (io.waddr2===j.asUInt)
|
||||
gpr_in(j) := (Fill(32,w0v(j)) & io.wd0) | (Fill(32,w1v(j)) & io.wd1) | (Fill(32,w2v(j)) & io.wd2)
|
||||
}
|
||||
gpr_wr_en:= (w0v.reverse).reduceRight(Cat(_,_)) | (w1v.reverse).reduceRight(Cat(_,_)) | (w2v.reverse).reduceRight(Cat(_,_))
|
||||
|
||||
// GPR Write Enables for power savings
|
||||
for (j <-1 until 32){
|
||||
gpr_out(j):=rvdffe(gpr_in(j),gpr_wr_en(j),clock,io.scan_mode)
|
||||
}
|
||||
// GPR Read logic
|
||||
for (j <-1 until 32){
|
||||
gpr_out(j):=rvdffe(gpr_in(j),gpr_wr_en(j),clock,io.scan_mode)
|
||||
}
|
||||
// GPR Read logic
|
||||
io.gpr_exu.gpr_i0_rs1_d:=Mux1H((1 until 32).map(i => (io.raddr0===i.U).asBool -> gpr_out(i)))
|
||||
io.gpr_exu.gpr_i0_rs2_d:=Mux1H((1 until 32).map(i => (io.raddr1===i.U).asBool -> gpr_out(i)))
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@ class dec_ib_ctl_IO extends Bundle with param{
|
|||
val ifu_ib = Flipped(new aln_ib)
|
||||
val ib_exu = Flipped(new ib_exu)
|
||||
val dbg_ib = new dbg_ib
|
||||
val dec_debug_valid_d =Output(UInt(1.W))
|
||||
|
||||
val dec_ib0_valid_d =Output(UInt(1.W)) // ib0 valid
|
||||
val dec_i0_icaf_type_d =Output(UInt(2.W)) // i0 instruction access fault type
|
||||
val dec_i0_instr_d =Output(UInt(32.W)) // i0 inst at decode
|
||||
|
@ -20,18 +18,15 @@ class dec_ib_ctl_IO extends Bundle with param{
|
|||
val dec_i0_bp_index =Output(UInt(((BTB_ADDR_HI-BTB_ADDR_LO)+1).W)) // i0 branch index
|
||||
val dec_i0_bp_fghr =Output(UInt(BHT_GHR_SIZE.W)) // BP FGHR
|
||||
val dec_i0_bp_btag =Output(UInt(BTB_BTAG_SIZE.W)) // BP tag
|
||||
val ifu_i0_fa_index =Input(UInt(log2Ceil(BTB_SIZE).W))
|
||||
val dec_i0_bp_fa_index =Output(UInt(log2Ceil(BTB_SIZE).W))
|
||||
|
||||
val dec_i0_icaf_d =Output(UInt(1.W)) // i0 instruction access fault at decode
|
||||
val dec_i0_icaf_second_d =Output(UInt(1.W)) // i0 instruction access fault at decode for f1 fetch group
|
||||
val dec_i0_icaf_f1_d =Output(UInt(1.W)) // i0 instruction access fault at decode for f1 fetch group
|
||||
val dec_i0_dbecc_d =Output(UInt(1.W)) // i0 double-bit error at decode
|
||||
val dec_debug_fence_d =Output(UInt(1.W)) // debug fence inst
|
||||
}
|
||||
|
||||
class dec_ib_ctl extends Module with param{
|
||||
val io=IO(new dec_ib_ctl_IO)
|
||||
io.dec_i0_icaf_second_d :=io.ifu_ib.ifu_i0_icaf_second
|
||||
io.dec_i0_icaf_f1_d :=io.ifu_ib.ifu_i0_icaf_f1
|
||||
io.dec_i0_dbecc_d :=io.ifu_ib.ifu_i0_dbecc
|
||||
io.dec_i0_icaf_d :=io.ifu_ib.ifu_i0_icaf
|
||||
io.ib_exu.dec_i0_pc_d :=io.ifu_ib.ifu_i0_pc
|
||||
|
@ -41,7 +36,6 @@ class dec_ib_ctl extends Module with param{
|
|||
io.dec_i0_bp_index :=io.ifu_ib.ifu_i0_bp_index
|
||||
io.dec_i0_bp_fghr :=io.ifu_ib.ifu_i0_bp_fghr
|
||||
io.dec_i0_bp_btag :=io.ifu_ib.ifu_i0_bp_btag
|
||||
io.dec_i0_bp_fa_index := io.ifu_i0_fa_index
|
||||
|
||||
// GPR accesses
|
||||
// put reg to read on rs1
|
||||
|
@ -58,7 +52,7 @@ class dec_ib_ctl extends Module with param{
|
|||
val debug_valid =io.dbg_ib.dbg_cmd_valid & (io.dbg_ib.dbg_cmd_type =/= 2.U)
|
||||
val debug_read =debug_valid & !io.dbg_ib.dbg_cmd_write
|
||||
val debug_write =debug_valid & io.dbg_ib.dbg_cmd_write
|
||||
io.dec_debug_valid_d := debug_valid
|
||||
|
||||
val debug_read_gpr = debug_read & (io.dbg_ib.dbg_cmd_type===0.U)
|
||||
val debug_write_gpr = debug_write & (io.dbg_ib.dbg_cmd_type===0.U)
|
||||
val debug_read_csr = debug_read & (io.dbg_ib.dbg_cmd_type===1.U)
|
||||
|
@ -68,11 +62,11 @@ class dec_ib_ctl extends Module with param{
|
|||
val dcsr = io.dbg_ib.dbg_cmd_addr(11,0)
|
||||
|
||||
val ib0_debug_in =Mux1H(Seq(
|
||||
debug_read_gpr.asBool -> Cat(Fill(12,0.U(1.W)),dreg,"b110000000110011".U),
|
||||
debug_write_gpr.asBool -> Cat("b00000000000000000110".U(20.W),dreg,"b0110011".U(7.W)),
|
||||
debug_read_csr.asBool -> Cat(dcsr,"b00000010000001110011".U(20.W)),
|
||||
debug_write_csr.asBool -> Cat(dcsr,"b00000001000001110011".U(20.W))
|
||||
))
|
||||
debug_read_gpr.asBool -> Cat(Fill(12,0.U(1.W)),dreg,"b110000000110011".U),
|
||||
debug_write_gpr.asBool -> Cat("b00000000000000000110".U(20.W),dreg,"b0110011".U(7.W)),
|
||||
debug_read_csr.asBool -> Cat(dcsr,"b00000010000001110011".U(20.W)),
|
||||
debug_write_csr.asBool -> Cat(dcsr,"b00000001000001110011".U(20.W))
|
||||
))
|
||||
|
||||
// machine is in halted state, pipe empty, write will always happen next cycle
|
||||
io.ib_exu.dec_debug_wdata_rs1_d := debug_write_gpr | debug_write_csr
|
||||
|
@ -83,4 +77,5 @@ class dec_ib_ctl extends Module with param{
|
|||
io.dec_ib0_valid_d := io.ifu_ib.ifu_i0_valid | debug_valid
|
||||
io.dec_i0_instr_d := Mux(debug_valid.asBool,ib0_debug_in,io.ifu_ib.ifu_i0_instr)
|
||||
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,7 @@
|
|||
import chisel3._
|
||||
import chisel3.util._
|
||||
import include._
|
||||
//import dbg._
|
||||
import dbg._
|
||||
import scala.collection._
|
||||
import lib._
|
||||
|
||||
|
@ -12,89 +12,127 @@ class dma_ctrl extends Module with lib with RequireAsyncReset {
|
|||
val dma_bus_clk_en = Input(Bool()) // slave bus clock enable
|
||||
val clk_override = Input(Bool())
|
||||
val scan_mode = Input(Bool())
|
||||
val dbg_cmd_size = Input(UInt(2.W))
|
||||
|
||||
val dbg_cmd_size = Input(UInt(2.W)) // size of the abstract mem access debug command
|
||||
val dma_dbg_rddata = Output(UInt(32.W))
|
||||
val dma_dbg_cmd_done = Output(Bool())
|
||||
val dma_dbg_cmd_fail = Output(Bool())
|
||||
val dma_dbg_rddata = Output(UInt(32.W))
|
||||
val iccm_dma_rvalid = Input(Bool())
|
||||
val iccm_dma_ecc_error = Input(Bool())
|
||||
val iccm_dma_rtag = Input(UInt(3.W))
|
||||
val iccm_dma_rdata = Input(UInt(64.W))
|
||||
val dma_active = Output(Bool())
|
||||
val iccm_ready = Input(Bool())
|
||||
|
||||
val dbg_dec_dma = new dec_dbg()
|
||||
val dbg_dma = new dbg_dma()
|
||||
val dec_dma = Flipped(new dec_dma())
|
||||
val iccm_dma_rvalid = Input(Bool()) // iccm data valid for DMA read
|
||||
val iccm_dma_ecc_error = Input(Bool()) // ECC error on DMA read
|
||||
val iccm_dma_rtag = Input(UInt(3.W)) // Tag of the DMA req
|
||||
val iccm_dma_rdata = Input(UInt(64.W)) // iccm data for DMA read
|
||||
val iccm_ready = Input(Bool()) // iccm ready to accept DMA request
|
||||
// AXI Write Channels
|
||||
val dma_axi = Flipped(new axi_channels(DMA_BUS_TAG))
|
||||
val lsu_dma = Flipped(new lsu_dma)
|
||||
val ifu_dma = Flipped(new ifu_dma)// AXI Write Channel
|
||||
val dma_axi = Flipped(new axi_channels(DMA_BUS_TAG))
|
||||
|
||||
|
||||
val ifu_dma = Flipped(new ifu_dma)
|
||||
})
|
||||
|
||||
val DEPTH = DMA_BUF_DEPTH
|
||||
|
||||
val DEPTH_PTR = log2Ceil(DEPTH)
|
||||
val DEPTH_PTR = log2Ceil(DMA_BUF_DEPTH)
|
||||
|
||||
val NACK_COUNT = 7
|
||||
val fifo_error = Wire(Vec(DMA_BUF_DEPTH, UInt(2.W)))
|
||||
|
||||
val fifo_error_bus = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
|
||||
|
||||
val fifo_done = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
|
||||
|
||||
val fifo_addr = Wire(Vec(DMA_BUF_DEPTH, UInt(32.W)))
|
||||
|
||||
val fifo_sz = Wire(Vec(DMA_BUF_DEPTH,UInt(3.W)))
|
||||
|
||||
val fifo_byteen = Wire(Vec(DMA_BUF_DEPTH,UInt(8.W)))
|
||||
|
||||
val fifo_data = Wire(Vec(DMA_BUF_DEPTH,UInt(64.W)))
|
||||
|
||||
val fifo_tag = Wire(Vec(DMA_BUF_DEPTH,UInt(DMA_BUS_TAG.W)))
|
||||
|
||||
val fifo_mid = Wire(Vec(DMA_BUF_DEPTH,UInt((DMA_BUS_ID:Int).W)))
|
||||
|
||||
val fifo_prty = Wire(Vec(DMA_BUF_DEPTH,UInt(DMA_BUS_PRTY.W)))
|
||||
|
||||
val fifo_error_en = WireInit(UInt(DMA_BUF_DEPTH.W),0.U)
|
||||
|
||||
val fifo_error_in = Wire(Vec(DMA_BUF_DEPTH, UInt(2.W)))
|
||||
|
||||
val fifo_data_in = Wire(Vec(DMA_BUF_DEPTH,UInt(64.W)))
|
||||
|
||||
val RspPtr = WireInit(UInt((log2Ceil(DMA_BUF_DEPTH)).W), 0.U)
|
||||
|
||||
val WrPtr = WireInit(UInt((log2Ceil(DMA_BUF_DEPTH)).W), 0.U)
|
||||
|
||||
val RdPtr = WireInit(UInt((log2Ceil(DMA_BUF_DEPTH)).W), 0.U)
|
||||
|
||||
val NxtRspPtr = WireInit(UInt((log2Ceil(DMA_BUF_DEPTH)).W), 0.U)
|
||||
|
||||
val NxtWrPtr = WireInit(UInt((log2Ceil(DMA_BUF_DEPTH)).W), 0.U)
|
||||
|
||||
val NxtRdPtr = WireInit(UInt((log2Ceil(DMA_BUF_DEPTH)).W), 0.U)
|
||||
|
||||
val dma_dbg_cmd_error = WireInit(UInt(1.W),0.U)
|
||||
|
||||
val dma_dbg_cmd_done_q = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val fifo_empty = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val dma_address_error = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val dma_alignment_error = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val num_fifo_vld = WireInit(UInt(4.W),0.U)
|
||||
|
||||
val dma_mem_req = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val dma_mem_addr_int = WireInit(UInt(32.W), 0.U)
|
||||
|
||||
val dma_mem_sz_int = WireInit(UInt(3.W), 0.U)
|
||||
|
||||
val dma_mem_byteen = WireInit(UInt(8.W), 0.U)
|
||||
|
||||
val dma_nack_count = WireInit(UInt(3.W), 0.U)
|
||||
|
||||
val dma_nack_count_csr = WireInit(UInt(3.W), 0.U)
|
||||
|
||||
val bus_rsp_valid = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val bus_rsp_sent = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val bus_cmd_valid = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val bus_cmd_sent = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val bus_cmd_write = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val bus_cmd_posted_write = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val dma_dbg_mem_wrdata = WireInit(UInt(32.W), 0.U)
|
||||
val bus_cmd_addr = WireInit(UInt(32.W), 0.U)
|
||||
val bus_cmd_byteen = WireInit(UInt(8.W), 0.U)
|
||||
|
||||
val bus_cmd_sz = WireInit(UInt(3.W), 0.U)
|
||||
val bus_cmd_write = WireInit(Bool(), false.B)
|
||||
val bus_cmd_posted_write = WireInit(Bool(), false.B)
|
||||
// Clock Gating logic
|
||||
val bus_cmd_valid = WireInit(Bool(),0.B)
|
||||
val bus_rsp_valid = WireInit(Bool(),0.B)
|
||||
val dma_dbg_cmd_done_q = WireInit(Bool(),0.B)
|
||||
val fifo_valid = WireInit(UInt(DEPTH.W),0.U)
|
||||
val dma_buffer_c1_clken = (bus_cmd_valid & io.dma_bus_clk_en) | io.dbg_dec_dma.dbg_ib.dbg_cmd_valid | io.clk_override
|
||||
val dma_free_clken = (bus_cmd_valid | bus_rsp_valid | io.dbg_dec_dma.dbg_ib.dbg_cmd_valid | io.dma_dbg_cmd_done | dma_dbg_cmd_done_q | (fifo_valid.orR) | io.clk_override)
|
||||
|
||||
val dma_buffer_c1_clk = rvoclkhdr(clock,dma_buffer_c1_clken,io.scan_mode)
|
||||
val dma_free_clk = rvoclkhdr(clock,dma_free_clken,io.scan_mode)
|
||||
val bus_cmd_addr = WireInit(UInt(32.W), 0.U)
|
||||
|
||||
val fifo_addr_in = Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid, io.dbg_dec_dma.dbg_ib.dbg_cmd_addr, bus_cmd_addr)
|
||||
val fifo_byteen_in = Fill(8,!io.dbg_dec_dma.dbg_ib.dbg_cmd_valid) & bus_cmd_byteen // Byte enable is used only for bus requests//Mux(io.dbg_cmd_valid, 0.U, bus_cmd_byteen)
|
||||
val fifo_sz_in = Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid, Cat(0.U,io.dbg_cmd_size), bus_cmd_sz)
|
||||
val fifo_write_in = Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid, io.dbg_dec_dma.dbg_ib.dbg_cmd_write, bus_cmd_write)
|
||||
val fifo_posted_write_in = !io.dbg_dec_dma.dbg_ib.dbg_cmd_valid & bus_cmd_posted_write
|
||||
val fifo_dbg_in = io.dbg_dec_dma.dbg_ib.dbg_cmd_valid
|
||||
val bus_cmd_sent = WireInit(Bool(), false.B)
|
||||
val WrPtr = WireInit(UInt(DEPTH_PTR.W), 0.U)
|
||||
val RdPtr = WireInit(UInt(DEPTH_PTR.W), 0.U)
|
||||
val dma_address_error = WireInit(Bool(), false.B)
|
||||
val dma_alignment_error = WireInit(Bool(), false.B)
|
||||
val bus_cmd_wdata = WireInit(UInt(64.W), 0.U)
|
||||
|
||||
val bus_cmd_tag = WireInit(UInt(DMA_BUS_TAG.W), 0.U)
|
||||
|
||||
val bus_cmd_mid = WireInit(UInt((DMA_BUS_ID:Int).W), 0.U)
|
||||
|
||||
val bus_cmd_prty = WireInit(UInt(DMA_BUS_PRTY.W), 0.U)
|
||||
|
||||
val bus_posted_write_done = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val fifo_full_spec_bus = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val dbg_dma_bubble_bus = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val axi_mstr_priority = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val axi_mstr_sel = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val axi_rsp_sent = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
// val fifo_cmd_en = (0 until DEPTH).map(i=>((bus_cmd_sent & io.dma_bus_clk_en) | (io.dbg_cmd_valid & io.dbg_cmd_type(1))) & (WrPtr === i.U).asUInt()).reverse.reduce(Cat(_,_))
|
||||
//
|
||||
// val fifo_data_en = (0 until DEPTH).map(i => ((((bus_cmd_sent & fifo_write_in & io.dma_bus_clk_en) | (io.dbg_cmd_valid & io.dbg_cmd_type(1) & io.dbg_cmd_write)) &
|
||||
// (i.U === WrPtr)) | ((dma_address_error | dma_alignment_error) & (i.U === RdPtr)) |
|
||||
// (io.dccm_dma_rvalid & (i.U === io.dccm_dma_rtag)) |
|
||||
// (io.iccm_dma_rvalid & (i.U === io.iccm_dma_rtag))).asUInt).reverse.reduce(Cat(_,_))
|
||||
//
|
||||
// val fifo_pend_en = (0 until DEPTH).map(i => ((io.dma_dccm_req | io.dma_iccm_req) & !io.dma_mem_write & (i.U === RdPtr)).asUInt).reverse.reduce(Cat(_,_))
|
||||
//
|
||||
// val dma_dbg_cmd_error = WireInit(Bool(), false.B)
|
||||
//
|
||||
// val fifo_error_en = (0 until DEPTH).map(i => (((dma_address_error.asBool | dma_alignment_error.asBool | dma_dbg_cmd_error) &
|
||||
// (i.U === RdPtr)) | ((io.dccm_dma_rvalid & io.dccm_dma_ecc_error) & (i.U === io.dccm_dma_rtag)) |
|
||||
// ((io.iccm_dma_rvalid & io.iccm_dma_ecc_error) & (i.U === io.iccm_dma_rtag))).asUInt).reverse.reduce(Cat(_,_))
|
||||
// val fifo_error_in = Wire(Vec(DEPTH, UInt(2.W)))
|
||||
// val fifo_error = Wire(Vec(DEPTH, UInt(2.W)))
|
||||
// val fifo_error_bus_en = (0 until DMA_BUF_DEPTH).map(i=>(((fifo_error_in(i).orR & fifo_error_en(i)) | fifo_error(i).orR) & io.dma_bus_clk_en).asUInt).reverse.reduce(Cat(_,_))
|
||||
// val fifo_done_en = (0 until DMA_BUF_DEPTH).map(i=>(((fifo_error(i).orR | fifo_error_en(i) | ((io.dma_dccm_req | io.dma_iccm_req) & io.dma_mem_write)) & (i.U === RdPtr)) |
|
||||
// (io.dccm_dma_rvalid & (i.U === io.dccm_dma_rtag)) | (io.iccm_dma_rvalid & (i.U === io.iccm_dma_rtag))).asUInt).reverse.reduce(Cat(_,_))
|
||||
// val fifo_done = WireInit(UInt(DEPTH.W), 0.U)
|
||||
// val fifo_done_bus_en = (0 until DMA_BUF_DEPTH).map(i => ((fifo_done_en(i) | fifo_done(i)) & io.dma_bus_clk_en).asUInt).reverse.reduce(Cat(_,_))
|
||||
// val bus_rsp_sent = WireInit(Bool(), false.B)
|
||||
// val bus_posted_write_done = WireInit(Bool(), false.B)
|
||||
// val RspPtr = WireInit(UInt(DEPTH_PTR.W), 0.U)
|
||||
// val fifo_reset = (0 until DMA_BUF_DEPTH).map(i=>((((bus_rsp_sent | bus_posted_write_done) & io.dma_bus_clk_en) | io.dma_dbg_cmd_done) & (i.U === RspPtr)).asUInt()).reverse.reduce(Cat(_,_))
|
||||
// fifo_error_in := (0 until DMA_BUF_DEPTH).map(i=>Mux(io.dccm_dma_rvalid & (io.dccm_dma_rtag===i.U), Cat(0.U(1.W),io.dccm_dma_ecc_error), Mux(io.iccm_dma_rvalid & (io.iccm_dma_rtag===i.U), Cat(0.U(1.W),io.iccm_dma_ecc_error), Cat(dma_address_error | dma_alignment_error | dma_dbg_cmd_error, dma_alignment_error))))
|
||||
val fifo_cmd_en = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
|
||||
|
||||
val fifo_data_en = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
|
||||
|
@ -109,17 +147,65 @@ class dma_ctrl extends Module with lib with RequireAsyncReset {
|
|||
|
||||
val fifo_reset = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
|
||||
|
||||
val fifo_error_en = WireInit(UInt(DMA_BUF_DEPTH.W),0.U)
|
||||
val dma_dbg_cmd_error = WireInit(UInt(1.W),0.U)
|
||||
val fifo_error_in = Wire(Vec(DMA_BUF_DEPTH, UInt(2.W)))
|
||||
val RspPtr = WireInit(UInt((log2Ceil(DMA_BUF_DEPTH)).W), 0.U)
|
||||
val bus_posted_write_done = WireInit(UInt(1.W), 0.U)
|
||||
val bus_rsp_sent = WireInit(UInt(1.W), 0.U)
|
||||
val fifo_error = Wire(Vec(DMA_BUF_DEPTH, UInt(2.W)))
|
||||
val fifo_done = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
|
||||
val fifo_valid = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
|
||||
|
||||
val fifo_rpend = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
|
||||
|
||||
val fifo_done_bus = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
|
||||
|
||||
val fifo_write = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
|
||||
|
||||
val fifo_posted_write = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
|
||||
|
||||
val fifo_dbg = WireInit(UInt(DMA_BUF_DEPTH.W), 0.U)
|
||||
|
||||
val wrbuf_vld = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val wrbuf_data_vld = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val rdbuf_vld = WireInit(UInt(1.W), 0.U)
|
||||
|
||||
val dma_free_clk = Wire(Clock())
|
||||
|
||||
val dma_bus_clk = Wire(Clock())
|
||||
|
||||
val dma_buffer_c1_clk = Wire(Clock())
|
||||
|
||||
val fifo_byteen_in = WireInit(UInt(8.W), 0.U)
|
||||
|
||||
//------------------------LOGIC STARTS HERE---------------------------------
|
||||
|
||||
|
||||
// DCCM Address check
|
||||
|
||||
val (dma_mem_addr_in_dccm,dma_mem_addr_in_dccm_region_nc) = rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(DCCM_SADR).U,DCCM_SIZE)
|
||||
|
||||
// PIC memory address check
|
||||
|
||||
val (dma_mem_addr_in_pic,dma_mem_addr_in_pic_region_nc) = rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(PIC_BASE_ADDR).U,PIC_SIZE)
|
||||
|
||||
// ICCM Address check
|
||||
|
||||
val (dma_mem_addr_in_iccm,dma_mem_addr_in_iccm_region_nc) = if(ICCM_ENABLE) rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(ICCM_SADR).U,ICCM_SIZE) else (0.U,0.U)
|
||||
|
||||
// FIFO inputs
|
||||
|
||||
val fifo_addr_in = Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid.asBool, io.dbg_dec_dma.dbg_ib.dbg_cmd_addr(31,0), bus_cmd_addr(31,0))
|
||||
|
||||
fifo_byteen_in := Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid.asBool, "h0f".U << (4.U * io.dbg_dec_dma.dbg_ib.dbg_cmd_addr(2)), bus_cmd_byteen(7,0))
|
||||
|
||||
val fifo_sz_in = Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid.asBool, Cat(0.U, io.dbg_cmd_size(1,0)), bus_cmd_sz(2,0))
|
||||
|
||||
val fifo_write_in = Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid.asBool, io.dbg_dec_dma.dbg_ib.dbg_cmd_write, bus_cmd_write)
|
||||
|
||||
val fifo_posted_write_in = !io.dbg_dec_dma.dbg_ib.dbg_cmd_valid & bus_cmd_posted_write
|
||||
|
||||
val fifo_dbg_in = io.dbg_dec_dma.dbg_ib.dbg_cmd_valid
|
||||
|
||||
|
||||
fifo_cmd_en := (0 until DMA_BUF_DEPTH).map(i => (((bus_cmd_sent.asBool & io.dma_bus_clk_en) | (io.dbg_dec_dma.dbg_ib.dbg_cmd_valid & io.dbg_dec_dma.dbg_ib.dbg_cmd_type(1).asBool)) & (i.U === WrPtr)).asUInt).reverse.reduce(Cat(_,_))
|
||||
|
||||
fifo_data_en := (0 until DMA_BUF_DEPTH).map(i => (((bus_cmd_sent & fifo_write_in & io.dma_bus_clk_en) | (io.dbg_dec_dma.dbg_ib.dbg_cmd_valid & io.dbg_dec_dma.dbg_ib.dbg_cmd_type(1) & io.dbg_dec_dma.dbg_ib.dbg_cmd_write)) & (i.U === WrPtr).asUInt()) | ((dma_address_error | dma_alignment_error) & (i.U === RdPtr).asUInt()) | (io.lsu_dma.dma_dccm_ctl.dccm_dma_rvalid & (i.U === io.lsu_dma.dma_dccm_ctl.dccm_dma_rtag).asUInt()) | (io.iccm_dma_rvalid & (i.U === io.iccm_dma_rtag).asUInt())).reverse.reduce(Cat(_,_))
|
||||
fifo_data_en := (0 until DMA_BUF_DEPTH).map(i => (((bus_cmd_sent & fifo_write_in & io.dma_bus_clk_en) | (io.dbg_dec_dma.dbg_ib.dbg_cmd_valid & io.dbg_dec_dma.dbg_ib.dbg_cmd_type(1) & io.dbg_dec_dma.dbg_ib.dbg_cmd_write)) & (i.U === WrPtr)) | ((dma_address_error | dma_alignment_error) & (i.U === RdPtr)) | (io.lsu_dma.dma_dccm_ctl.dccm_dma_rvalid & (i.U === io.lsu_dma.dma_dccm_ctl.dccm_dma_rtag)) | (io.iccm_dma_rvalid & (i.U === io.iccm_dma_rtag))).reverse.reduce(Cat(_,_))
|
||||
|
||||
fifo_pend_en := (0 until DMA_BUF_DEPTH).map(i => ((io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req) & !io.lsu_dma.dma_lsc_ctl.dma_mem_write & (i.U === RdPtr)).asUInt).reverse.reduce(Cat(_,_))
|
||||
|
||||
|
@ -135,69 +221,87 @@ class dma_ctrl extends Module with lib with RequireAsyncReset {
|
|||
|
||||
(0 until DMA_BUF_DEPTH).map(i => fifo_error_in(i) := (Mux(io.lsu_dma.dma_dccm_ctl.dccm_dma_rvalid & (i.U === io.lsu_dma.dma_dccm_ctl.dccm_dma_rtag), Cat(0.U, io.lsu_dma.dma_dccm_ctl.dccm_dma_ecc_error), Mux(io.iccm_dma_rvalid & (i.U === io.iccm_dma_rtag), (Cat(0.U, io.iccm_dma_ecc_error)), (Cat((dma_address_error | dma_alignment_error | dma_dbg_cmd_error), dma_alignment_error))))))
|
||||
|
||||
val fifo_addr = Wire(Vec(DEPTH,UInt(32.W)))
|
||||
val bus_cmd_wdata = WireInit(UInt(64.W), 0.U)
|
||||
val fifo_data_in = VecInit.tabulate(DMA_BUF_DEPTH)(i =>(Mux(fifo_error_en(i) & (fifo_error_in(i).orR), Cat(Fill(32, 0.U), fifo_addr(i)), Mux(io.lsu_dma.dma_dccm_ctl.dccm_dma_rvalid & (i.U === io.lsu_dma.dma_dccm_ctl.dccm_dma_rtag), io.lsu_dma.dma_dccm_ctl.dccm_dma_rdata, Mux(io.iccm_dma_rvalid & (i.U === io.iccm_dma_rtag), io.iccm_dma_rdata, Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid, Fill(2, dma_dbg_mem_wrdata), bus_cmd_wdata(63,0)))))))
|
||||
(0 until DMA_BUF_DEPTH).map(i => fifo_data_in(i) := (Mux(fifo_error_en(i) & (fifo_error_in(i).orR), Cat(Fill(32, 0.U), fifo_addr(i)), Mux(io.lsu_dma.dma_dccm_ctl.dccm_dma_rvalid & (i.U === io.lsu_dma.dma_dccm_ctl.dccm_dma_rtag), io.lsu_dma.dma_dccm_ctl.dccm_dma_rdata, Mux(io.iccm_dma_rvalid & (i.U === io.iccm_dma_rtag), io.iccm_dma_rdata, Mux(io.dbg_dec_dma.dbg_ib.dbg_cmd_valid, Fill(2, io.dbg_dec_dma.dbg_dctl.dbg_cmd_wrdata), bus_cmd_wdata(63,0)))))))
|
||||
|
||||
fifo_valid := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_cmd_en(i), 1.U, fifo_valid(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
|
||||
(0 until DMA_BUF_DEPTH).map(i => fifo_error(i) := withClock(dma_free_clk) {RegNext(Mux(fifo_error_en(i).asBool(),fifo_error_in(i) , fifo_error(i)) & Fill(fifo_error_in(i).getWidth , !fifo_reset(i)), 0.U)})
|
||||
val fifo_error_bus = WireInit(UInt(DEPTH.W), 0.U)
|
||||
val fifo_rpend = WireInit(UInt(DEPTH.W), 0.U)
|
||||
fifo_error_bus := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_error_bus_en(i), 1.U, fifo_error_bus(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
|
||||
fifo_rpend := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_pend_en(i), 1.U, fifo_rpend(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
|
||||
fifo_done := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_done_en(i), 1.U, fifo_done(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
|
||||
val fifo_done_bus = WireInit(UInt(DEPTH.W), 0.U)
|
||||
fifo_done_bus := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_done_bus_en(i), 1.U, fifo_done_bus(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
|
||||
(0 until DMA_BUF_DEPTH).map(i => fifo_addr(i) := rvdffe(fifo_addr_in, fifo_cmd_en(i), clock, io.scan_mode))
|
||||
val fifo_sz = VecInit.tabulate(DMA_BUF_DEPTH)(i => withClock(dma_buffer_c1_clk) {RegEnable(fifo_sz_in(2,0), 0.U, fifo_cmd_en(i))})
|
||||
val fifo_byteen = VecInit.tabulate(DMA_BUF_DEPTH)(i =>withClock(dma_buffer_c1_clk) {RegEnable(fifo_byteen_in(7,0), 0.U, fifo_cmd_en(i).asBool())})
|
||||
val fifo_write = (0 until DMA_BUF_DEPTH).map(i => (withClock(dma_buffer_c1_clk) {RegEnable(fifo_write_in, 0.U, fifo_cmd_en(i))})).reverse.reduce(Cat(_,_))
|
||||
val fifo_posted_write = (0 until DMA_BUF_DEPTH).map(i => (withClock(dma_buffer_c1_clk) {RegEnable(fifo_posted_write_in, 0.U, fifo_cmd_en(i))})).reverse.reduce(Cat(_,_))
|
||||
val fifo_dbg = (0 until DMA_BUF_DEPTH).map(i => withClock(dma_buffer_c1_clk) {RegEnable(fifo_dbg_in, 0.U, fifo_cmd_en(i))}).reverse.reduce(Cat(_,_))
|
||||
|
||||
val fifo_data = Wire(Vec(DMA_BUF_DEPTH,UInt(64.W)))//VecInit.tabulate(DMA_BUF_DEPTH)(i =>rvdffe(fifo_data_in(i), fifo_data_en(i), clock, io.scan_mode))
|
||||
(0 until DMA_BUF_DEPTH).map(i => fifo_error(i) := withClock(dma_free_clk) {RegNext(Mux(fifo_error_en(i).asBool(),fifo_error_in(i) , fifo_error(i)) & Fill(fifo_error_in(i).getWidth , !fifo_reset(i)), 0.U)})
|
||||
|
||||
fifo_error_bus := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_error_bus_en(i), 1.U, fifo_error_bus(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
|
||||
|
||||
fifo_rpend := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_pend_en(i), 1.U, fifo_rpend(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
|
||||
|
||||
fifo_done := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_done_en(i), 1.U, fifo_done(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
|
||||
|
||||
fifo_done_bus := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_free_clk) {RegNext(Mux(fifo_done_bus_en(i), 1.U, fifo_done_bus(i)) & !fifo_reset(i), 0.U)}).reverse.reduce(Cat(_,_))
|
||||
|
||||
(0 until DMA_BUF_DEPTH).map(i => fifo_addr(i) := rvdffe(fifo_addr_in, fifo_cmd_en(i), clock, io.scan_mode))
|
||||
|
||||
(0 until DMA_BUF_DEPTH).map(i => fifo_sz(i) := withClock(dma_buffer_c1_clk) {RegEnable(fifo_sz_in(2,0), 0.U, fifo_cmd_en(i))})
|
||||
|
||||
(0 until DMA_BUF_DEPTH).map(i => fifo_byteen(i) := withClock(dma_buffer_c1_clk) {RegEnable(fifo_byteen_in(7,0), 0.U, fifo_cmd_en(i).asBool())})
|
||||
|
||||
fifo_write := (0 until DMA_BUF_DEPTH).map(i => (withClock(dma_buffer_c1_clk) {RegEnable(fifo_write_in, 0.U, fifo_cmd_en(i))})).reverse.reduce(Cat(_,_))
|
||||
|
||||
fifo_posted_write := (0 until DMA_BUF_DEPTH).map(i => (withClock(dma_buffer_c1_clk) {RegEnable(fifo_posted_write_in, 0.U, fifo_cmd_en(i))})).reverse.reduce(Cat(_,_))
|
||||
|
||||
fifo_dbg := (0 until DMA_BUF_DEPTH).map(i => withClock(dma_buffer_c1_clk) {RegEnable(fifo_dbg_in, 0.U, fifo_cmd_en(i))}).reverse.reduce(Cat(_,_))
|
||||
|
||||
(0 until DMA_BUF_DEPTH).map(i => fifo_data(i) := rvdffe(fifo_data_in(i), fifo_data_en(i), clock, io.scan_mode))
|
||||
val bus_cmd_tag = WireInit(UInt(DMA_BUS_TAG.W),0.U)
|
||||
val bus_cmd_mid = WireInit(UInt(DMA_BUS_ID.W),0.U)
|
||||
val bus_cmd_prty = WireInit(UInt(DMA_BUS_PRTY.W),0.U)
|
||||
val fifo_tag = VecInit.tabulate(DMA_BUF_DEPTH)(i =>withClock(dma_buffer_c1_clk) {RegEnable(bus_cmd_tag, 0.U, fifo_cmd_en(i))})
|
||||
val fifo_mid = VecInit.tabulate(DMA_BUF_DEPTH)(i =>withClock(dma_buffer_c1_clk) {RegEnable(bus_cmd_mid, 0.U, fifo_cmd_en(i))})
|
||||
val fifo_prty = VecInit.tabulate(DMA_BUF_DEPTH)(i =>withClock(dma_buffer_c1_clk) {RegEnable(bus_cmd_prty, 0.U, fifo_cmd_en(i))})
|
||||
|
||||
(0 until DMA_BUF_DEPTH).map(i => fifo_tag(i) := withClock(dma_buffer_c1_clk) {RegEnable(bus_cmd_tag, 0.U, fifo_cmd_en(i))})
|
||||
|
||||
(0 until DMA_BUF_DEPTH).map(i => fifo_mid(i) := withClock(dma_buffer_c1_clk) {RegEnable(bus_cmd_mid, 0.U, fifo_cmd_en(i))})
|
||||
|
||||
(0 until DMA_BUF_DEPTH).map(i => fifo_prty(i) := withClock(dma_buffer_c1_clk) {RegEnable(bus_cmd_prty, 0.U, fifo_cmd_en(i))})
|
||||
|
||||
// Pointer logic
|
||||
|
||||
val NxtWrPtr = Mux((WrPtr === (DEPTH-1).U), 0.U, WrPtr+ 1.U)
|
||||
val NxtRdPtr = Mux((RdPtr === (DEPTH-1).U), 0.U, RdPtr+ 1.U)
|
||||
val NxtRspPtr = Mux((RspPtr === (DEPTH-1).U), 0.U, RspPtr + 1.U)
|
||||
NxtWrPtr := Mux((WrPtr === (DMA_BUF_DEPTH - 1).U).asBool, 0.U, WrPtr + 1.U)
|
||||
|
||||
NxtRdPtr := Mux((RdPtr === (DMA_BUF_DEPTH - 1).U).asBool, 0.U, RdPtr + 1.U)
|
||||
|
||||
NxtRspPtr := Mux((RspPtr === (DMA_BUF_DEPTH - 1).U).asBool, 0.U, RspPtr + 1.U)
|
||||
|
||||
val WrPtrEn = fifo_cmd_en.orR
|
||||
|
||||
val RdPtrEn = (io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req | (dma_address_error.asBool | dma_alignment_error.asBool | dma_dbg_cmd_error))
|
||||
|
||||
val WrPtrEn = fifo_cmd_en.orR
|
||||
val RdPtrEn = io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req | (dma_address_error | dma_alignment_error | dma_dbg_cmd_error)
|
||||
val RspPtrEn = (io.dma_dbg_cmd_done | (bus_rsp_sent | bus_posted_write_done) & io.dma_bus_clk_en)
|
||||
|
||||
WrPtr := withClock(dma_free_clk) {
|
||||
RegEnable(NxtWrPtr, 0.U, WrPtrEn)
|
||||
}
|
||||
|
||||
WrPtr := withClock(dma_free_clk) { RegEnable(NxtWrPtr, 0.U, WrPtrEn) }
|
||||
RdPtr := withClock(dma_free_clk) { RegEnable(NxtRdPtr, 0.U, RdPtrEn.asBool) }
|
||||
RspPtr := withClock(dma_free_clk) { RegEnable(NxtRspPtr, 0.U, RspPtrEn.asBool) }
|
||||
// Miscellaneous signals
|
||||
val fifo_full_spec_bus = WireInit(Bool(),0.B)
|
||||
val fifo_full = fifo_full_spec_bus
|
||||
RdPtr := withClock(dma_free_clk) {
|
||||
RegEnable(NxtRdPtr, 0.U, RdPtrEn.asBool)
|
||||
}
|
||||
|
||||
val num_fifo_vld = Wire(Vec(DEPTH+1,UInt(4.W)))
|
||||
val dbg_dma_bubble_bus = WireInit(Bool(),0.B)
|
||||
num_fifo_vld(0) := Cat(0.U(3.W),bus_cmd_sent) - Cat(0.U(3.W),bus_rsp_sent)
|
||||
for (i <- 1 to DEPTH) { num_fifo_vld(i):= num_fifo_vld(i-1) + Cat(0.U(3.W),fifo_valid(i-1))}
|
||||
val fifo_full_spec = (num_fifo_vld(DEPTH) >= DEPTH.U)
|
||||
val dma_fifo_ready = ~(fifo_full | dbg_dma_bubble_bus)
|
||||
RspPtr := withClock(dma_free_clk) {
|
||||
RegEnable(NxtRspPtr, 0.U, RspPtrEn.asBool)
|
||||
}
|
||||
|
||||
// Miscellaneous signal
|
||||
|
||||
val fifo_full = fifo_full_spec_bus;
|
||||
|
||||
val num_fifo_vld_tmp = WireInit(UInt(4.W),0.U)
|
||||
val num_fifo_vld_tmp2 = WireInit(UInt(4.W),0.U)
|
||||
|
||||
num_fifo_vld_tmp := (Cat(Fill(3, 0.U), bus_cmd_sent)) - (Cat(Fill(3, 0.U), bus_rsp_sent))
|
||||
|
||||
num_fifo_vld_tmp2 := (0 until DMA_BUF_DEPTH).map(i => Cat(Fill(3,0.U), fifo_valid(i))).reduce(_+_)
|
||||
|
||||
num_fifo_vld := num_fifo_vld_tmp + num_fifo_vld_tmp2
|
||||
|
||||
val fifo_full_spec = (num_fifo_vld >= DMA_BUF_DEPTH.asUInt())
|
||||
|
||||
val dma_fifo_ready = ~(fifo_full | dbg_dma_bubble_bus)
|
||||
|
||||
// Error logic
|
||||
val dma_mem_addr_in_dccm = WireInit(Bool(),0.B)
|
||||
val dma_mem_addr_in_iccm = WireInit(Bool(),0.B)
|
||||
val dma_mem_sz_int = WireInit(UInt(3.W),0.U)
|
||||
val dma_mem_addr_int = WireInit(UInt(32.W),0.U)
|
||||
val dma_mem_byteen = WireInit(UInt(8.W),0.U)
|
||||
dma_address_error := fifo_valid(RdPtr) & ~fifo_done(RdPtr) & ~fifo_dbg(RdPtr) & (~(dma_mem_addr_in_dccm | dma_mem_addr_in_iccm)) // request not for ICCM or DCCM
|
||||
|
||||
dma_alignment_error := fifo_valid(RdPtr) & !fifo_done(RdPtr) & !fifo_dbg(RdPtr) & !dma_address_error &
|
||||
dma_address_error := fifo_valid(RdPtr) & !fifo_done(RdPtr) & !fifo_dbg(RdPtr) & (~(dma_mem_addr_in_dccm | dma_mem_addr_in_iccm)).asUInt // request not for ICCM or DCCM
|
||||
dma_alignment_error := fifo_valid(RdPtr) & !fifo_done(RdPtr) & !dma_address_error &
|
||||
(((dma_mem_sz_int(2,0) === 1.U) & dma_mem_addr_int(0)) | // HW size but unaligned
|
||||
((dma_mem_sz_int(2,0) === 2.U) & (dma_mem_addr_int(1, 0).orR)) | // W size but unaligned
|
||||
((dma_mem_sz_int(2,0) === 3.U) & (dma_mem_addr_int(2, 0).orR)) | // DW size but unaligned
|
||||
|
@ -212,184 +316,185 @@ class dma_ctrl extends Module with lib with RequireAsyncReset {
|
|||
(dma_mem_addr_int(2,0) === 6.U) -> (dma_mem_byteen(7,6)),
|
||||
(dma_mem_addr_int(2,0) === 7.U) -> (dma_mem_byteen(7)))) =/= "hf".U)) | // Write byte enables not aligned for word store
|
||||
(io.lsu_dma.dma_lsc_ctl.dma_mem_write & (dma_mem_sz_int(2, 0) === 3.U) & !((dma_mem_byteen(7,0) === "h0f".U) | (dma_mem_byteen(7,0) === "hf0".U) | (dma_mem_byteen(7,0) === "hff".U)))) // Write byte enables not aligned for dword store
|
||||
// Used to indicate ready to debug
|
||||
val fifo_empty = ~(fifo_valid.orR | bus_cmd_sent)
|
||||
|
||||
|
||||
//Dbg outputs
|
||||
io.dbg_dma.dma_dbg_ready := fifo_empty & io.dbg_dma.dbg_dma_bubble
|
||||
io.dma_dbg_cmd_done := (fifo_valid(RspPtr) & fifo_dbg(RspPtr) & fifo_done(RspPtr))
|
||||
io.dma_dbg_cmd_fail := fifo_error(RspPtr).orR
|
||||
|
||||
val dma_dbg_sz = fifo_sz(RspPtr)(1,0)
|
||||
val dma_dbg_addr = fifo_addr(RspPtr)(1,0)
|
||||
val dma_dbg_mem_rddata = Mux(fifo_addr(RspPtr)(2), fifo_data(RspPtr)(63,32) , fifo_data(RspPtr)(31,0))
|
||||
io.dma_dbg_rddata := Mux1H(Seq(
|
||||
(dma_dbg_sz(1,0) === "h0".U(2.W)) -> ((dma_dbg_mem_rddata >> ((8.U)*dma_dbg_addr(1,0))) & "hff".U) ,
|
||||
(dma_dbg_sz(1,0) === "h1".U(2.W)) -> ((dma_dbg_mem_rddata >> ((16.U)*dma_dbg_addr(1))) & "hffff".U) ,
|
||||
(dma_dbg_sz(1,0) === "h2".U(2.W)) -> dma_dbg_mem_rddata))
|
||||
io.dbg_dma.dma_dbg_ready := fifo_empty & dbg_dma_bubble_bus
|
||||
io.dma_dbg_cmd_done := (fifo_valid(RspPtr) & fifo_dbg(RspPtr) & fifo_done(RspPtr))
|
||||
io.dma_dbg_rddata := Mux(fifo_addr(RspPtr)(2), fifo_data(RspPtr)(63, 32), fifo_data(RspPtr)(31,0))
|
||||
io.dma_dbg_cmd_fail := fifo_error(RspPtr).orR
|
||||
|
||||
// PIC memory address check
|
||||
|
||||
val dma_mem_addr_in_pic = rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(PIC_BASE_ADDR).U,PIC_SIZE)._1
|
||||
val dma_mem_addr_in_pic_region_nc = rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(PIC_BASE_ADDR).U,PIC_SIZE)._2
|
||||
|
||||
dma_dbg_cmd_error := fifo_valid(RdPtr) & ~fifo_done(RdPtr) & fifo_dbg(RdPtr) &
|
||||
((~(dma_mem_addr_in_dccm | dma_mem_addr_in_iccm | dma_mem_addr_in_pic)) | // Address outside of ICCM/DCCM/PIC
|
||||
((dma_mem_addr_in_iccm | dma_mem_addr_in_pic) & (dma_mem_sz_int(1,0) =/= 2.U))) // Only word accesses allowed for ICCM/PIC
|
||||
|
||||
dma_dbg_mem_wrdata := Mux1H(Seq(
|
||||
(io.dbg_cmd_size(1,0) === "h0".U(2.W)) -> Fill(4,io.dbg_dec_dma.dbg_dctl.dbg_cmd_wrdata(7,0)) ,
|
||||
(io.dbg_cmd_size(1,0) === "h1".U(2.W)) -> Fill(2,io.dbg_dec_dma.dbg_dctl.dbg_cmd_wrdata(15,0)),
|
||||
(io.dbg_cmd_size(1,0) === "h2".U(2.W)) -> io.dbg_dec_dma.dbg_dctl.dbg_cmd_wrdata ))
|
||||
dma_dbg_cmd_error := fifo_valid(RdPtr) & !fifo_done(RdPtr) & fifo_dbg(RdPtr) & ((~(dma_mem_addr_in_dccm | dma_mem_addr_in_iccm | dma_mem_addr_in_pic)).asBool() | (dma_mem_sz_int(1, 0) =/= 2.U)) // Only word accesses allowed
|
||||
|
||||
// Block the decode if fifo full
|
||||
val dma_mem_req = WireInit(Bool(),0.B)
|
||||
val dma_nack_count = WireInit(UInt(3.W),0.U)
|
||||
val dma_nack_count_csr = WireInit(UInt(3.W),0.U)
|
||||
val dma_nack_count_d = WireInit(UInt(3.W),0.U)
|
||||
io.dec_dma.dctl_dma.dma_dccm_stall_any := dma_mem_req & (dma_mem_addr_in_dccm | dma_mem_addr_in_pic) & (dma_nack_count >= dma_nack_count_csr)
|
||||
io.dec_dma.tlu_dma.dma_dccm_stall_any := io.dec_dma.dctl_dma.dma_dccm_stall_any
|
||||
io.dec_dma.tlu_dma.dma_iccm_stall_any := dma_mem_req & dma_mem_addr_in_iccm & (dma_nack_count >= dma_nack_count_csr)
|
||||
io.ifu_dma.dma_ifc.dma_iccm_stall_any := io.dec_dma.tlu_dma.dma_iccm_stall_any
|
||||
// Nack counter, stall the lsu pipe if 7 nacks
|
||||
dma_nack_count_csr := io.dec_dma.tlu_dma.dec_tlu_dma_qos_prty
|
||||
dma_nack_count_d := Mux((dma_nack_count >= dma_nack_count_csr), (Fill(3,(!(io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req))) & dma_nack_count),
|
||||
Mux((dma_mem_req & ~(io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req)), (dma_nack_count + 1.U), 0.U(3.W)))
|
||||
dma_nack_count := withClock(dma_free_clk){RegEnable(dma_nack_count_d,0.U,dma_mem_req)}
|
||||
|
||||
io.dec_dma.tlu_dma.dma_dccm_stall_any := dma_mem_req & (dma_mem_addr_in_dccm | dma_mem_addr_in_pic) & (dma_nack_count >= dma_nack_count_csr)
|
||||
io.ifu_dma.dma_ifc.dma_iccm_stall_any := dma_mem_req & dma_mem_addr_in_iccm & (dma_nack_count >= dma_nack_count_csr);
|
||||
io.dec_dma.tlu_dma.dma_iccm_stall_any := io.ifu_dma.dma_ifc.dma_iccm_stall_any
|
||||
io.dec_dma.dctl_dma.dma_dccm_stall_any := io.dec_dma.tlu_dma.dma_dccm_stall_any
|
||||
// Used to indicate ready to debug
|
||||
|
||||
fifo_empty := ~(fifo_valid.orR)
|
||||
|
||||
// Nack counter, stall the lsu pipe if 7 nacks
|
||||
|
||||
dma_nack_count_csr := io.dec_dma.tlu_dma.dec_tlu_dma_qos_prty
|
||||
val dma_nack_count_d = Mux(dma_nack_count >= dma_nack_count_csr, (Fill(3, !(io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req)) & dma_nack_count(2,0)), Mux((dma_mem_req.asBool & !(io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req)), dma_nack_count(2,0) + 1.U, 0.U))
|
||||
|
||||
dma_nack_count := withClock(dma_free_clk) {
|
||||
RegEnable(dma_nack_count_d(2,0), 0.U, dma_mem_req.asBool)
|
||||
}
|
||||
|
||||
// Core outputs
|
||||
dma_mem_req := fifo_valid(RdPtr) & ~fifo_rpend(RdPtr) & ~fifo_done(RdPtr) & ~(dma_address_error | dma_alignment_error | dma_dbg_cmd_error)
|
||||
io.lsu_dma.dma_lsc_ctl.dma_dccm_req := dma_mem_req & (dma_mem_addr_in_dccm | dma_mem_addr_in_pic) & io.lsu_dma.dccm_ready
|
||||
io.ifu_dma.dma_mem_ctl.dma_iccm_req := dma_mem_req & dma_mem_addr_in_iccm & io.iccm_ready
|
||||
io.lsu_dma.dma_mem_tag := RdPtr
|
||||
io.ifu_dma.dma_mem_ctl.dma_mem_tag := io.lsu_dma.dma_mem_tag
|
||||
dma_mem_addr_int := fifo_addr(RdPtr)
|
||||
dma_mem_sz_int := fifo_sz(RdPtr)
|
||||
io.lsu_dma.dma_dccm_ctl.dma_mem_addr := Mux((io.lsu_dma.dma_lsc_ctl.dma_mem_write & ~fifo_dbg(RdPtr) & (dma_mem_byteen === "hf0".U(8.W))), Cat(dma_mem_addr_int(31,3),1.U,dma_mem_addr_int(1,0)), dma_mem_addr_int)
|
||||
io.lsu_dma.dma_lsc_ctl.dma_mem_addr := io.lsu_dma.dma_dccm_ctl.dma_mem_addr
|
||||
io.ifu_dma.dma_mem_ctl.dma_mem_addr := io.lsu_dma.dma_dccm_ctl.dma_mem_addr
|
||||
io.lsu_dma.dma_lsc_ctl.dma_mem_sz := Mux(io.lsu_dma.dma_lsc_ctl.dma_mem_write & ~fifo_dbg(RdPtr) & ((dma_mem_byteen === "h0f".U(8.W)) | (dma_mem_byteen === "hf0".U(8.W))), 2.U(3.W), dma_mem_sz_int)
|
||||
io.ifu_dma.dma_mem_ctl.dma_mem_sz := io.lsu_dma.dma_lsc_ctl.dma_mem_sz
|
||||
dma_mem_byteen := fifo_byteen(RdPtr)
|
||||
io.lsu_dma.dma_lsc_ctl.dma_mem_write := fifo_write(RdPtr)
|
||||
io.ifu_dma.dma_mem_ctl.dma_mem_write := io.lsu_dma.dma_lsc_ctl.dma_mem_write
|
||||
io.lsu_dma.dma_dccm_ctl.dma_mem_wdata := fifo_data(RdPtr)
|
||||
io.lsu_dma.dma_lsc_ctl.dma_mem_wdata := io.lsu_dma.dma_dccm_ctl.dma_mem_wdata
|
||||
io.ifu_dma.dma_mem_ctl.dma_mem_wdata := io.lsu_dma.dma_dccm_ctl.dma_mem_wdata
|
||||
|
||||
dma_mem_req := fifo_valid(RdPtr) & !fifo_rpend(RdPtr) & !fifo_done(RdPtr) & !(dma_address_error | dma_alignment_error | dma_dbg_cmd_error)
|
||||
io.lsu_dma.dma_lsc_ctl.dma_dccm_req := dma_mem_req & (dma_mem_addr_in_dccm | dma_mem_addr_in_pic) & io.lsu_dma.dccm_ready
|
||||
io.ifu_dma.dma_mem_ctl.dma_iccm_req := dma_mem_req & dma_mem_addr_in_iccm & io.iccm_ready;
|
||||
io.lsu_dma.dma_mem_tag := RdPtr
|
||||
dma_mem_addr_int := fifo_addr(RdPtr)
|
||||
dma_mem_sz_int := fifo_sz(RdPtr)
|
||||
io.lsu_dma.dma_lsc_ctl.dma_mem_addr := Mux(io.lsu_dma.dma_lsc_ctl.dma_mem_write & (dma_mem_byteen(7,0) === "hf0".U), Cat(dma_mem_addr_int(31, 3), 1.U, dma_mem_addr_int(1, 0)), dma_mem_addr_int(31,0))
|
||||
io.lsu_dma.dma_lsc_ctl.dma_mem_sz := Mux(io.lsu_dma.dma_lsc_ctl.dma_mem_write & ((dma_mem_byteen(7,0) === "h0f".U) | (dma_mem_byteen(7,0) === "hf0".U)), 2.U, dma_mem_sz_int(2,0))
|
||||
dma_mem_byteen := fifo_byteen(RdPtr)
|
||||
io.lsu_dma.dma_lsc_ctl.dma_mem_write := fifo_write(RdPtr)
|
||||
io.lsu_dma.dma_lsc_ctl.dma_mem_wdata := fifo_data(RdPtr)
|
||||
|
||||
// PMU outputs
|
||||
io.dec_dma.tlu_dma.dma_pmu_dccm_read := io.lsu_dma.dma_lsc_ctl.dma_dccm_req & ~io.lsu_dma.dma_lsc_ctl.dma_mem_write
|
||||
|
||||
io.dec_dma.tlu_dma.dma_pmu_dccm_read := io.lsu_dma.dma_lsc_ctl.dma_dccm_req & !io.lsu_dma.dma_lsc_ctl.dma_mem_write
|
||||
io.dec_dma.tlu_dma.dma_pmu_dccm_write := io.lsu_dma.dma_lsc_ctl.dma_dccm_req & io.lsu_dma.dma_lsc_ctl.dma_mem_write
|
||||
io.dec_dma.tlu_dma.dma_pmu_any_read := (io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req) & ~io.lsu_dma.dma_lsc_ctl.dma_mem_write
|
||||
io.dec_dma.tlu_dma.dma_pmu_any_read := (io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req) & !io.lsu_dma.dma_lsc_ctl.dma_mem_write
|
||||
io.dec_dma.tlu_dma.dma_pmu_any_write := (io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req) & io.lsu_dma.dma_lsc_ctl.dma_mem_write
|
||||
|
||||
// Address check dccm
|
||||
val dma_mem_addr_in_dccm_region_nc = WireInit(Bool(),0.B)
|
||||
if (DCCM_ENABLE){
|
||||
dma_mem_addr_in_dccm := rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(DCCM_SADR).U,DCCM_SIZE)._1
|
||||
dma_mem_addr_in_dccm_region_nc := rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(DCCM_SADR).U,DCCM_SIZE)._2
|
||||
} else{
|
||||
dma_mem_addr_in_dccm := 0.U
|
||||
dma_mem_addr_in_dccm_region_nc := 0.U
|
||||
}
|
||||
|
||||
|
||||
// Address check iccm
|
||||
val dma_mem_addr_in_iccm_region_nc = WireInit(Bool(),0.B)
|
||||
if (ICCM_ENABLE) {
|
||||
dma_mem_addr_in_iccm := rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(ICCM_SADR).U,ICCM_SIZE)._1
|
||||
dma_mem_addr_in_iccm_region_nc := rvrangecheck_ch(dma_mem_addr_int(31,0),aslong(ICCM_SADR).U,ICCM_SIZE)._2
|
||||
|
||||
}else {
|
||||
dma_mem_addr_in_iccm := 0.U
|
||||
dma_mem_addr_in_iccm_region_nc := 0.U
|
||||
}
|
||||
|
||||
|
||||
val dma_bus_clk = Wire(Clock())
|
||||
if(RV_FPGA_OPTIMIZE) dma_bus_clk := 0.B.asClock()
|
||||
else dma_bus_clk := rvclkhdr(clock,io.dma_bus_clk_en,io.scan_mode)// dma_bus_cgc (.en(dma_bus_clk_en), .l1clk(dma_bus_clk), .*)
|
||||
|
||||
// Inputs
|
||||
fifo_full_spec_bus := rvdff_fpga(fifo_full_spec,dma_bus_clk,io.dma_bus_clk_en,clock)
|
||||
dbg_dma_bubble_bus := rvdff_fpga(io.dbg_dma.dbg_dma_bubble,dma_bus_clk,io.dma_bus_clk_en,clock)
|
||||
dma_dbg_cmd_done_q := withClock(io.free_clk){ RegNext(io.dma_dbg_cmd_done,0.U)}
|
||||
|
||||
fifo_full_spec_bus := withClock(dma_bus_clk) {
|
||||
RegNext(fifo_full_spec, 0.U)
|
||||
}
|
||||
|
||||
dbg_dma_bubble_bus := withClock(dma_bus_clk) {
|
||||
RegNext(io.dbg_dma.dbg_dma_bubble, 0.U)
|
||||
}
|
||||
|
||||
dma_dbg_cmd_done_q := withClock(io.free_clk) {
|
||||
RegNext(io.dma_dbg_cmd_done, 0.U)
|
||||
}
|
||||
|
||||
// Clock Gating logic
|
||||
|
||||
val dma_buffer_c1_clken = (bus_cmd_valid & io.dma_bus_clk_en) | io.dbg_dec_dma.dbg_ib.dbg_cmd_valid | io.clk_override
|
||||
val dma_free_clken = (bus_cmd_valid | bus_rsp_valid | io.dbg_dec_dma.dbg_ib.dbg_cmd_valid | io.dma_dbg_cmd_done | dma_dbg_cmd_done_q | (fifo_valid.orR) | io.clk_override)
|
||||
|
||||
dma_buffer_c1_clk := rvclkhdr(clock,dma_buffer_c1_clken.asBool,io.scan_mode)
|
||||
dma_free_clk := rvclkhdr(clock,dma_free_clken.asBool(),io.scan_mode)
|
||||
dma_bus_clk := rvclkhdr(clock,io.dma_bus_clk_en,io.scan_mode)
|
||||
|
||||
|
||||
// Write channel buffer
|
||||
val wrbuf_en = io.dma_axi.aw.valid & io.dma_axi.aw.ready
|
||||
val wrbuf_data_en = io.dma_axi.w.valid & io.dma_axi.w.ready
|
||||
val wrbuf_cmd_sent = bus_cmd_sent & bus_cmd_write
|
||||
val wrbuf_rst = wrbuf_cmd_sent & ~wrbuf_en
|
||||
val wrbuf_data_rst = wrbuf_cmd_sent & ~wrbuf_data_en
|
||||
|
||||
val wrbuf_vld = rvdffsc_fpga(1.B,wrbuf_en,wrbuf_rst,dma_bus_clk,io.dma_bus_clk_en,clock)
|
||||
val wrbuf_data_vld = rvdffsc_fpga(1.B,wrbuf_data_en,wrbuf_data_rst,dma_bus_clk,io.dma_bus_clk_en,clock)
|
||||
val wrbuf_tag = rvdffs_fpga(io.dma_axi.aw.bits.id,wrbuf_en,dma_bus_clk,io.dma_bus_clk_en,clock)
|
||||
val wrbuf_sz = rvdffs_fpga(io.dma_axi.aw.bits.size,wrbuf_en,dma_bus_clk,io.dma_bus_clk_en,clock)
|
||||
val wrbuf_addr = rvdffe(io.dma_axi.aw.bits.addr,wrbuf_en & io.dma_bus_clk_en,clock,io.scan_mode)
|
||||
val wrbuf_data = rvdffe(io.dma_axi.w.bits.data,wrbuf_data_en & io.dma_bus_clk_en,clock,io.scan_mode)
|
||||
val wrbuf_byteen = rvdffs_fpga(io.dma_axi.w.bits.strb,wrbuf_data_en,dma_bus_clk,io.dma_bus_clk_en,clock)
|
||||
val wrbuf_en = io.dma_axi.aw.valid & io.dma_axi.aw.ready
|
||||
val wrbuf_data_en = io.dma_axi.w.valid & io.dma_axi.w.ready
|
||||
val wrbuf_cmd_sent = bus_cmd_sent & bus_cmd_write
|
||||
val wrbuf_rst = wrbuf_cmd_sent.asBool & !wrbuf_en
|
||||
val wrbuf_data_rst = wrbuf_cmd_sent.asBool & !wrbuf_data_en
|
||||
|
||||
wrbuf_vld := withClock(dma_bus_clk) {RegNext(Mux(wrbuf_en, 1.U, wrbuf_vld) & !wrbuf_rst, 0.U)}
|
||||
|
||||
wrbuf_data_vld := withClock(dma_bus_clk) {RegNext(Mux(wrbuf_data_en, 1.U, wrbuf_data_vld) & !wrbuf_data_rst, 0.U)}
|
||||
|
||||
val wrbuf_tag = withClock(dma_bus_clk) {
|
||||
RegEnable(io.dma_axi.aw.bits.id, 0.U, wrbuf_en)
|
||||
}
|
||||
|
||||
val wrbuf_sz = withClock(dma_bus_clk) {
|
||||
RegEnable(io.dma_axi.aw.bits.size, 0.U, wrbuf_en)
|
||||
}
|
||||
|
||||
val wrbuf_addr = rvdffe(io.dma_axi.aw.bits.addr, wrbuf_en & io.dma_bus_clk_en, clock, io.scan_mode)
|
||||
|
||||
val wrbuf_data = rvdffe(io.dma_axi.w.bits.data, wrbuf_data_en & io.dma_bus_clk_en, clock, io.scan_mode)
|
||||
|
||||
val wrbuf_byteen = withClock(dma_bus_clk) {
|
||||
RegEnable(io.dma_axi.w.bits.strb, 0.U, wrbuf_data_en)
|
||||
}
|
||||
|
||||
// Read channel buffer
|
||||
val rdbuf_en = io.dma_axi.ar.valid & io.dma_axi.ar.ready
|
||||
val rdbuf_cmd_sent = bus_cmd_sent & ~bus_cmd_write
|
||||
val rdbuf_rst = rdbuf_cmd_sent & ~rdbuf_en
|
||||
|
||||
val rdbuf_vld = rvdffsc_fpga(1.B,rdbuf_en,rdbuf_rst,dma_bus_clk,io.dma_bus_clk_en,clock)
|
||||
val rdbuf_tag = rvdffs_fpga(io.dma_axi.ar.bits.id,rdbuf_en,dma_bus_clk,io.dma_bus_clk_en,clock)
|
||||
val rdbuf_sz = rvdffs_fpga(io.dma_axi.ar.bits.size,rdbuf_en,dma_bus_clk,io.dma_bus_clk_en,clock)
|
||||
val rdbuf_addr = rvdffe(io.dma_axi.ar.bits.addr,rdbuf_en & io.dma_bus_clk_en,clock,io.scan_mode)
|
||||
val rdbuf_en = io.dma_axi.ar.valid & io.dma_axi.ar.ready
|
||||
val rdbuf_cmd_sent = bus_cmd_sent & !bus_cmd_write
|
||||
val rdbuf_rst = rdbuf_cmd_sent.asBool & !rdbuf_en
|
||||
|
||||
io.dma_axi.aw.ready := ~(wrbuf_vld & ~wrbuf_cmd_sent)
|
||||
io.dma_axi.w.ready := ~(wrbuf_data_vld & ~wrbuf_cmd_sent)
|
||||
io.dma_axi.ar.ready := ~(rdbuf_vld & ~rdbuf_cmd_sent)
|
||||
rdbuf_vld := withClock(dma_bus_clk) {RegNext(Mux(rdbuf_en, 1.U, rdbuf_vld) & !rdbuf_rst, 0.U)}
|
||||
|
||||
val rdbuf_tag = withClock(dma_bus_clk) {
|
||||
RegEnable(io.dma_axi.ar.bits.id, 0.U, rdbuf_en)
|
||||
}
|
||||
|
||||
val rdbuf_sz = withClock(dma_bus_clk) {
|
||||
RegEnable(io.dma_axi.ar.bits.size, 0.U, rdbuf_en)
|
||||
}
|
||||
|
||||
val rdbuf_addr = rvdffe(io.dma_axi.ar.bits.addr, rdbuf_en & io.dma_bus_clk_en, clock, io.scan_mode)
|
||||
|
||||
io.dma_axi.aw.ready := ~(wrbuf_vld & !wrbuf_cmd_sent)
|
||||
io.dma_axi.w.ready := ~(wrbuf_data_vld & !wrbuf_cmd_sent)
|
||||
io.dma_axi.ar.ready := ~(rdbuf_vld & !rdbuf_cmd_sent)
|
||||
|
||||
//Generate a single request from read/write channel
|
||||
val axi_mstr_sel = WireInit(Bool(),0.B)
|
||||
bus_cmd_valid := (wrbuf_vld & wrbuf_data_vld) | rdbuf_vld
|
||||
bus_cmd_sent := bus_cmd_valid & dma_fifo_ready
|
||||
bus_cmd_write := axi_mstr_sel
|
||||
bus_cmd_posted_write := 0.U
|
||||
bus_cmd_addr := Mux(axi_mstr_sel, wrbuf_addr, rdbuf_addr)
|
||||
bus_cmd_sz := Mux(axi_mstr_sel, wrbuf_sz, rdbuf_sz)
|
||||
bus_cmd_wdata := wrbuf_data
|
||||
bus_cmd_byteen := wrbuf_byteen
|
||||
bus_cmd_tag := Mux(axi_mstr_sel, wrbuf_tag, rdbuf_tag)
|
||||
bus_cmd_mid := 0.U
|
||||
bus_cmd_prty := 0.U
|
||||
|
||||
bus_cmd_valid := (wrbuf_vld & wrbuf_data_vld) | rdbuf_vld
|
||||
bus_cmd_sent := bus_cmd_valid & dma_fifo_ready.asUInt
|
||||
bus_cmd_write := axi_mstr_sel
|
||||
bus_cmd_posted_write := 0.U;
|
||||
bus_cmd_addr := Mux(axi_mstr_sel.asBool, wrbuf_addr, rdbuf_addr)
|
||||
bus_cmd_sz := Mux(axi_mstr_sel.asBool, wrbuf_sz, rdbuf_sz)
|
||||
bus_cmd_wdata := wrbuf_data
|
||||
bus_cmd_byteen := wrbuf_byteen
|
||||
bus_cmd_tag := Mux(axi_mstr_sel.asBool, wrbuf_tag, rdbuf_tag)
|
||||
bus_cmd_mid := 0.U
|
||||
bus_cmd_prty := 0.U
|
||||
|
||||
// Sel=1 -> write has higher priority
|
||||
val axi_mstr_priority = WireInit(Bool(),0.B)
|
||||
axi_mstr_sel := Mux(((wrbuf_vld & wrbuf_data_vld & rdbuf_vld)===1.U).asBool(), axi_mstr_priority, (wrbuf_vld & wrbuf_data_vld) )
|
||||
val axi_mstr_prty_in = ~axi_mstr_priority
|
||||
val axi_mstr_prty_en = bus_cmd_sent
|
||||
axi_mstr_priority := rvdffs_fpga(axi_mstr_prty_in.asUInt(),axi_mstr_prty_en,dma_bus_clk,io.dma_bus_clk_en,clock)
|
||||
|
||||
val axi_rsp_valid = fifo_valid(RspPtr) & ~fifo_dbg(RspPtr) & fifo_done_bus(RspPtr)
|
||||
val axi_rsp_rdata = fifo_data(RspPtr)
|
||||
val axi_rsp_write = fifo_write(RspPtr)
|
||||
val axi_rsp_error = Mux(fifo_error(RspPtr)(0), 2.U,Mux(fifo_error(RspPtr)(1), 3.U, 0.U))
|
||||
val axi_rsp_tag = fifo_tag(RspPtr)
|
||||
axi_mstr_sel := Mux((wrbuf_vld & wrbuf_data_vld & rdbuf_vld) === 1.U, axi_mstr_priority, wrbuf_vld & wrbuf_data_vld)
|
||||
val axi_mstr_prty_in = ~axi_mstr_priority
|
||||
val axi_mstr_prty_en = bus_cmd_sent
|
||||
|
||||
axi_mstr_priority := withClock(dma_bus_clk) {
|
||||
RegEnable(axi_mstr_prty_in, 0.U, axi_mstr_prty_en.asBool)
|
||||
}
|
||||
|
||||
val axi_rsp_valid = fifo_valid(RspPtr) & !fifo_dbg(RspPtr) & fifo_done_bus(RspPtr)
|
||||
val axi_rsp_rdata = fifo_data(RspPtr)
|
||||
val axi_rsp_write = fifo_write(RspPtr)
|
||||
val axi_rsp_error = Mux(fifo_error(RspPtr)(0), 2.U, Mux(fifo_error(RspPtr)(1), 3.U, 0.U));
|
||||
|
||||
val axi_rsp_tag = fifo_tag(RspPtr)
|
||||
|
||||
// AXI response channel signals
|
||||
io.dma_axi.b.valid := axi_rsp_valid & axi_rsp_write
|
||||
io.dma_axi.b.bits.resp := axi_rsp_error
|
||||
io.dma_axi.b.bits.id := axi_rsp_tag
|
||||
|
||||
io.dma_axi.r.valid := axi_rsp_valid & ~axi_rsp_write
|
||||
io.dma_axi.r.bits.resp := axi_rsp_error
|
||||
io.dma_axi.r.bits.data := axi_rsp_rdata
|
||||
io.dma_axi.r.bits.last := 1.U
|
||||
io.dma_axi.r.bits.id := axi_rsp_tag
|
||||
io.dma_axi.b.valid := axi_rsp_valid & axi_rsp_write
|
||||
io.dma_axi.b.bits.resp := axi_rsp_error(1,0)
|
||||
io.dma_axi.b.bits.id := axi_rsp_tag
|
||||
|
||||
io.dma_axi.r.valid := axi_rsp_valid & !axi_rsp_write
|
||||
io.dma_axi.r.bits.resp := axi_rsp_error
|
||||
io.dma_axi.r.bits.data := axi_rsp_rdata(63,0)
|
||||
io.dma_axi.r.bits.last := 1.U
|
||||
io.dma_axi.r.bits.id := axi_rsp_tag
|
||||
|
||||
bus_posted_write_done := 0.U
|
||||
bus_rsp_valid := (io.dma_axi.b.valid | io.dma_axi.r.valid)
|
||||
bus_rsp_sent := (io.dma_axi.b.valid & io.dma_axi.b.ready) | (io.dma_axi.r.valid & io.dma_axi.r.ready)
|
||||
|
||||
io.dma_active := wrbuf_vld | rdbuf_vld | (fifo_valid.orR)
|
||||
|
||||
}
|
||||
object DMA extends App {
|
||||
println((new chisel3.stage.ChiselStage).emitVerilog(new dma_ctrl))
|
||||
bus_rsp_valid := (io.dma_axi.b.valid | io.dma_axi.r.valid)
|
||||
bus_rsp_sent := ((io.dma_axi.b.valid & io.dma_axi.b.ready) | (io.dma_axi.r.valid & io.dma_axi.r.ready))
|
||||
io.lsu_dma.dma_dccm_ctl.dma_mem_addr := io.lsu_dma.dma_lsc_ctl.dma_mem_addr
|
||||
io.lsu_dma.dma_dccm_ctl.dma_mem_wdata := io.lsu_dma.dma_lsc_ctl.dma_mem_wdata
|
||||
io.ifu_dma.dma_mem_ctl.dma_mem_sz := io.lsu_dma.dma_lsc_ctl.dma_mem_sz
|
||||
io.ifu_dma.dma_mem_ctl.dma_mem_addr := io.lsu_dma.dma_lsc_ctl.dma_mem_addr
|
||||
io.ifu_dma.dma_mem_ctl.dma_mem_wdata := io.lsu_dma.dma_lsc_ctl.dma_mem_wdata
|
||||
io.ifu_dma.dma_mem_ctl.dma_mem_write := io.lsu_dma.dma_lsc_ctl.dma_mem_write
|
||||
io.ifu_dma.dma_mem_ctl.dma_mem_tag := io.lsu_dma.dma_mem_tag
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -21,12 +21,11 @@ class exu extends Module with lib with RequireAsyncReset{
|
|||
val exu_div_wren = Output(UInt(1.W)) // Divide write enable to GPR
|
||||
//debug
|
||||
val dbg_cmd_wrdata = Input(UInt(32.W)) // Debug data to primary I0 RS1
|
||||
val dec_csr_rddata_d = Input(UInt(32.W))
|
||||
val lsu_nonblock_load_data = Input(UInt(32.W))
|
||||
//lsu
|
||||
val lsu_exu = Flipped(new lsu_exu())
|
||||
//ifu_ifc
|
||||
val exu_flush_path_final = Output(UInt(31.W)) // Target for the oldest flush source
|
||||
|
||||
})
|
||||
|
||||
val PREDPIPESIZE = BTB_ADDR_HI - BTB_ADDR_LO + BHT_GHR_SIZE + BTB_BTAG_SIZE +1
|
||||
|
@ -36,7 +35,9 @@ class exu extends Module with lib with RequireAsyncReset{
|
|||
val i0_taken_d = Wire(UInt(1.W))
|
||||
val mul_valid_x = Wire(UInt(1.W))
|
||||
val i0_valid_d = Wire(UInt(1.W))
|
||||
val i0_branch_x = Wire(UInt(1.W))
|
||||
val flush_lower_ff = Wire(UInt(1.W))
|
||||
val data_gate_en = Wire(UInt(1.W))
|
||||
val csr_rs1_in_d = Wire(UInt(32.W))
|
||||
val i0_predict_newp_d = Wire(Valid(new predict_pkt_t()))
|
||||
val i0_flush_path_d = Wire(UInt(31.W))
|
||||
val i0_predict_p_d = Wire(Valid(new predict_pkt_t()))
|
||||
|
@ -53,119 +54,130 @@ class exu extends Module with lib with RequireAsyncReset{
|
|||
i0_pp_r.bits.toffset := 0.U
|
||||
|
||||
val x_data_en = io.dec_exu.decode_exu.dec_data_en(1)
|
||||
val x_data_en_q1 = io.dec_exu.decode_exu.dec_data_en(1) & io.dec_exu.dec_alu.dec_csr_ren_d
|
||||
val x_data_en_q2 = io.dec_exu.decode_exu.dec_data_en(1) & io.dec_exu.decode_exu.dec_i0_branch_d
|
||||
val r_data_en = io.dec_exu.decode_exu.dec_data_en(0)
|
||||
val r_data_en_q2 = io.dec_exu.decode_exu.dec_data_en(0) & i0_branch_x
|
||||
val x_ctl_en = io.dec_exu.decode_exu.dec_ctl_en(1)
|
||||
val r_ctl_en = io.dec_exu.decode_exu.dec_ctl_en(0)
|
||||
val predpipe_d = Cat(io.dec_exu.decode_exu.i0_predict_fghr_d, io.dec_exu.decode_exu.i0_predict_index_d, io.dec_exu.decode_exu.i0_predict_btag_d)
|
||||
|
||||
val i0_flush_path_x =rvdffpcie(i0_flush_path_d,x_data_en.asBool,reset.asAsyncReset,clock,io.scan_mode)
|
||||
i0_predict_p_x :=rvdffppe(i0_predict_p_d,clock,reset.asAsyncReset,x_data_en.asBool,io.scan_mode,elements= 13,io.exu_bp.exu_mp_pkt.bits.pret)
|
||||
val predpipe_x =rvdffe(predpipe_d,x_data_en_q2.asBool,clock,io.scan_mode)
|
||||
val predpipe_r =rvdffe(predpipe_x ,r_data_en_q2.asBool,clock,io.scan_mode)
|
||||
val ghr_x =rvdffe(ghr_x_ns ,x_ctl_en.asBool,clock,io.scan_mode)
|
||||
val i0_pred_correct_upper_x =rvdffe(i0_pred_correct_upper_d ,x_ctl_en.asBool,clock,io.scan_mode)
|
||||
val i0_flush_upper_x =rvdffe(i0_flush_upper_d ,x_ctl_en.asBool,clock,io.scan_mode)
|
||||
val i0_taken_x =rvdffe(i0_taken_d ,x_ctl_en.asBool,clock,io.scan_mode)
|
||||
val i0_valid_x =rvdffe(i0_valid_d ,x_ctl_en.asBool,clock,io.scan_mode)
|
||||
i0_pp_r :=rvdffppe(i0_predict_p_x,clock,reset.asAsyncReset(),r_ctl_en.asBool,io.scan_mode,elements = 13,io.exu_bp.exu_mp_pkt.bits.pret)
|
||||
val pred_temp1 =rvdffpcie(io.dec_exu.decode_exu.pred_correct_npc_x(5,0) ,r_data_en.asBool,reset.asAsyncReset(),clock,io.scan_mode)
|
||||
val i0_pred_correct_upper_r =rvdffppe_UInt(i0_pred_correct_upper_x ,clock,reset.asAsyncReset(),r_ctl_en.asBool,io.scan_mode,WIDTH=1)
|
||||
val i0_flush_path_upper_r =rvdffpcie(i0_flush_path_x ,r_data_en.asBool,reset.asAsyncReset(),clock,io.scan_mode)
|
||||
val pred_temp2 =rvdffpcie(io.dec_exu.decode_exu.pred_correct_npc_x(30,6) ,r_data_en.asBool,reset.asAsyncReset(),clock,io.scan_mode)
|
||||
pred_correct_npc_r :=Cat(pred_temp2,pred_temp1)
|
||||
ghr_d :=rvdffie(ghr_d_ns,clock,reset.asAsyncReset(),io.scan_mode)
|
||||
mul_valid_x :=rvdffie(io.dec_exu.decode_exu.mul_p.valid,clock,reset.asAsyncReset(),io.scan_mode)
|
||||
i0_branch_x :=rvdffie(io.dec_exu.decode_exu.dec_i0_branch_d,clock,reset.asAsyncReset(),io.scan_mode)
|
||||
|
||||
val i0_rs1_bypass_en_d = io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(0) | io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(1) | io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(2) | io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(3)
|
||||
val i0_rs2_bypass_en_d = io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(0) | io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(1) | io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(2) | io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(3)
|
||||
val i0_flush_path_x =rvdffe(i0_flush_path_d,x_data_en.asBool,clock,io.scan_mode)
|
||||
io.dec_exu.decode_exu.exu_csr_rs1_x :=rvdffe(csr_rs1_in_d,x_data_en.asBool,clock,io.scan_mode)
|
||||
i0_predict_p_x :=rvdffe(i0_predict_p_d,x_data_en.asBool,clock,io.scan_mode)
|
||||
val predpipe_x =rvdffe(predpipe_d,x_data_en.asBool,clock,io.scan_mode)
|
||||
val predpipe_r =rvdffe(predpipe_x ,r_data_en.asBool,clock,io.scan_mode)
|
||||
val ghr_x =rvdffe(ghr_x_ns ,x_ctl_en.asBool,clock,io.scan_mode)
|
||||
val i0_pred_correct_upper_x =rvdffe(i0_pred_correct_upper_d ,x_ctl_en.asBool,clock,io.scan_mode)
|
||||
val i0_flush_upper_x =rvdffe(i0_flush_upper_d ,x_ctl_en.asBool,clock,io.scan_mode)
|
||||
val i0_taken_x =rvdffe(i0_taken_d ,x_ctl_en.asBool,clock,io.scan_mode)
|
||||
val i0_valid_x =rvdffe(i0_valid_d ,x_ctl_en.asBool,clock,io.scan_mode)
|
||||
i0_pp_r :=rvdffe(i0_predict_p_x,r_ctl_en.asBool,clock,io.scan_mode)
|
||||
val pred_temp1 =rvdffe(io.dec_exu.decode_exu.pred_correct_npc_x(5,0) ,r_ctl_en.asBool,clock,io.scan_mode)
|
||||
val i0_pred_correct_upper_r =rvdffe(i0_pred_correct_upper_x ,r_ctl_en.asBool,clock,io.scan_mode)
|
||||
val i0_flush_path_upper_r =rvdffe(i0_flush_path_x ,r_data_en.asBool,clock,io.scan_mode)
|
||||
val pred_temp2 =rvdffe(io.dec_exu.decode_exu.pred_correct_npc_x(30,6) ,r_data_en.asBool,clock,io.scan_mode)
|
||||
pred_correct_npc_r :=Cat(pred_temp2,pred_temp1)
|
||||
|
||||
when (BHT_SIZE.asUInt===32.U || BHT_SIZE.asUInt===64.U){
|
||||
ghr_d :=RegEnable(ghr_d_ns,0.U,data_gate_en.asBool)
|
||||
mul_valid_x :=RegEnable(io.dec_exu.decode_exu.mul_p.valid,0.U,data_gate_en.asBool)
|
||||
flush_lower_ff :=RegEnable(io.dec_exu.tlu_exu.dec_tlu_flush_lower_r,0.U,data_gate_en.asBool)
|
||||
}.otherwise{
|
||||
ghr_d :=rvdffe(ghr_d_ns ,data_gate_en.asBool,clock,io.scan_mode)
|
||||
mul_valid_x :=rvdffe(io.dec_exu.decode_exu.mul_p.valid ,data_gate_en.asBool,clock,io.scan_mode)
|
||||
flush_lower_ff :=rvdffe(io.dec_exu.tlu_exu.dec_tlu_flush_lower_r ,data_gate_en.asBool,clock,io.scan_mode)
|
||||
}
|
||||
|
||||
|
||||
data_gate_en := (ghr_d_ns =/= ghr_d) | ( io.dec_exu.decode_exu.mul_p.valid =/= mul_valid_x) | ( io.dec_exu.tlu_exu.dec_tlu_flush_lower_r =/= flush_lower_ff)
|
||||
val i0_rs1_bypass_en_d = io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(0) | io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(1)
|
||||
val i0_rs2_bypass_en_d = io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(0) | io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(1)
|
||||
|
||||
val i0_rs1_bypass_data_d = Mux1H(Seq(
|
||||
io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(0).asBool -> io.dec_exu.decode_exu.dec_i0_result_r,
|
||||
io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(1).asBool -> io.lsu_exu.lsu_result_m,
|
||||
io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(2).asBool -> io.dec_exu.decode_exu.exu_i0_result_x,
|
||||
io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(3).asBool -> io.lsu_nonblock_load_data
|
||||
io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(0).asBool -> io.dec_exu.decode_exu.dec_i0_rs1_bypass_data_d,
|
||||
io.dec_exu.decode_exu.dec_i0_rs1_bypass_en_d(1).asBool -> io.dec_exu.decode_exu.exu_i0_result_x
|
||||
))
|
||||
|
||||
val i0_rs2_bypass_data_d = Mux1H(Seq(
|
||||
io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(0).asBool -> io.dec_exu.decode_exu.dec_i0_result_r,
|
||||
io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(1).asBool -> io.lsu_exu.lsu_result_m,
|
||||
io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(2).asBool -> io.dec_exu.decode_exu.exu_i0_result_x,
|
||||
io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(3).asBool -> io.lsu_nonblock_load_data
|
||||
io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(0).asBool -> io.dec_exu.decode_exu.dec_i0_rs2_bypass_data_d,
|
||||
io.dec_exu.decode_exu.dec_i0_rs2_bypass_en_d(1).asBool -> io.dec_exu.decode_exu.exu_i0_result_x
|
||||
))
|
||||
|
||||
val i0_rs1_d = Mux1H(Seq(
|
||||
i0_rs1_bypass_en_d.asBool -> i0_rs1_bypass_data_d,
|
||||
(!i0_rs1_bypass_en_d & io.dec_exu.decode_exu.dec_i0_select_pc_d).asBool -> Cat(io.dec_exu.ib_exu.dec_i0_pc_d,0.U(1.W)),
|
||||
(!i0_rs1_bypass_en_d & io.dec_exu.ib_exu.dec_debug_wdata_rs1_d).asBool -> io.dbg_cmd_wrdata,
|
||||
i0_rs1_bypass_en_d.asBool -> i0_rs1_bypass_data_d,
|
||||
(!i0_rs1_bypass_en_d & io.dec_exu.decode_exu.dec_i0_select_pc_d).asBool -> Cat(io.dec_exu.ib_exu.dec_i0_pc_d,0.U(1.W)),
|
||||
(!i0_rs1_bypass_en_d & io.dec_exu.ib_exu.dec_debug_wdata_rs1_d).asBool -> io.dbg_cmd_wrdata,
|
||||
(!i0_rs1_bypass_en_d & !io.dec_exu.ib_exu.dec_debug_wdata_rs1_d & io.dec_exu.decode_exu.dec_i0_rs1_en_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs1_d
|
||||
))
|
||||
io.dec_exu.decode_exu.exu_csr_rs1_x :=rvdffe(i0_rs1_d,x_data_en_q1.asBool,clock,io.scan_mode)
|
||||
|
||||
val i0_rs2_d = Mux1H(Seq(
|
||||
val i0_rs2_d = Mux1H(Seq(
|
||||
(!i0_rs2_bypass_en_d & io.dec_exu.decode_exu.dec_i0_rs2_en_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs2_d,
|
||||
(!i0_rs2_bypass_en_d).asBool -> io.dec_exu.decode_exu.dec_i0_immed_d,
|
||||
(i0_rs2_bypass_en_d).asBool -> i0_rs2_bypass_data_d
|
||||
(!i0_rs2_bypass_en_d).asBool -> io.dec_exu.decode_exu.dec_i0_immed_d,
|
||||
(i0_rs2_bypass_en_d).asBool -> i0_rs2_bypass_data_d
|
||||
))
|
||||
dontTouch(i0_rs2_d)
|
||||
|
||||
io.lsu_exu.exu_lsu_rs1_d:=Mux1H(Seq(
|
||||
(!i0_rs1_bypass_en_d & !io.dec_exu.decode_exu.dec_extint_stall & io.dec_exu.decode_exu.dec_i0_rs1_en_d & io.dec_exu.decode_exu.dec_qual_lsu_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs1_d,
|
||||
(i0_rs1_bypass_en_d & !io.dec_exu.decode_exu.dec_extint_stall & io.dec_exu.decode_exu.dec_qual_lsu_d).asBool -> i0_rs1_bypass_data_d,
|
||||
(io.dec_exu.decode_exu.dec_extint_stall & io.dec_exu.decode_exu.dec_qual_lsu_d).asBool -> Cat(io.dec_exu.tlu_exu.dec_tlu_meihap,0.U(2.W))
|
||||
(!i0_rs1_bypass_en_d & !io.dec_exu.decode_exu.dec_extint_stall & io.dec_exu.decode_exu.dec_i0_rs1_en_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs1_d,
|
||||
(i0_rs1_bypass_en_d & !io.dec_exu.decode_exu.dec_extint_stall).asBool -> i0_rs1_bypass_data_d,
|
||||
(io.dec_exu.decode_exu.dec_extint_stall).asBool -> Cat(io.dec_exu.tlu_exu.dec_tlu_meihap,0.U(2.W))
|
||||
))
|
||||
|
||||
io.lsu_exu.exu_lsu_rs2_d:=Mux1H(Seq(
|
||||
(!i0_rs2_bypass_en_d & !io.dec_exu.decode_exu.dec_extint_stall & io.dec_exu.decode_exu.dec_i0_rs2_en_d & io.dec_exu.decode_exu.dec_qual_lsu_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs2_d,
|
||||
(i0_rs2_bypass_en_d & !io.dec_exu.decode_exu.dec_extint_stall & io.dec_exu.decode_exu.dec_qual_lsu_d).asBool -> i0_rs2_bypass_data_d
|
||||
(!i0_rs2_bypass_en_d & !io.dec_exu.decode_exu.dec_extint_stall & io.dec_exu.decode_exu.dec_i0_rs2_en_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs2_d,
|
||||
(i0_rs2_bypass_en_d & !io.dec_exu.decode_exu.dec_extint_stall).asBool -> i0_rs2_bypass_data_d
|
||||
))
|
||||
|
||||
val muldiv_rs1_d=Mux1H(Seq(
|
||||
(!i0_rs1_bypass_en_d & io.dec_exu.decode_exu.dec_i0_rs1_en_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs1_d,
|
||||
(i0_rs1_bypass_en_d).asBool -> i0_rs1_bypass_data_d
|
||||
(i0_rs1_bypass_en_d).asBool -> i0_rs1_bypass_data_d
|
||||
))
|
||||
|
||||
val muldiv_rs2_d=Mux1H(Seq(
|
||||
(!i0_rs2_bypass_en_d & io.dec_exu.decode_exu.dec_i0_rs2_en_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs2_d,
|
||||
(!i0_rs2_bypass_en_d).asBool -> io.dec_exu.decode_exu.dec_i0_immed_d,
|
||||
(i0_rs2_bypass_en_d).asBool -> i0_rs2_bypass_data_d
|
||||
))
|
||||
|
||||
csr_rs1_in_d := Mux(io.dec_exu.dec_alu.dec_csr_ren_d.asBool, i0_rs1_d, io.dec_exu.decode_exu.exu_csr_rs1_x)
|
||||
|
||||
|
||||
val i_alu=Module(new exu_alu_ctl())
|
||||
i_alu.io.dec_alu <> io.dec_exu.dec_alu
|
||||
|
||||
i_alu.io.scan_mode :=io.scan_mode
|
||||
i_alu.io.enable :=x_data_en
|
||||
i_alu.io.pp_in :=i0_predict_newp_d
|
||||
i_alu.io.scan_mode :=io.scan_mode
|
||||
i_alu.io.enable :=x_ctl_en
|
||||
i_alu.io.pp_in :=i0_predict_newp_d
|
||||
i_alu.io.flush_upper_x :=i0_flush_upper_x
|
||||
i_alu.io.csr_rddata_in :=io.dec_csr_rddata_d
|
||||
i_alu.io.dec_tlu_flush_lower_r :=io.dec_exu.tlu_exu.dec_tlu_flush_lower_r
|
||||
i_alu.io.a_in :=i0_rs1_d.asSInt
|
||||
i_alu.io.b_in :=i0_rs2_d
|
||||
i_alu.io.dec_i0_pc_d :=io.dec_exu.ib_exu.dec_i0_pc_d
|
||||
i_alu.io.i0_ap :=io.dec_exu.decode_exu.i0_ap
|
||||
val alu_result_x =i_alu.io.result_ff
|
||||
i0_flush_upper_d :=i_alu.io.flush_upper_out
|
||||
i0_flush_path_d :=i_alu.io.flush_path_out
|
||||
io.exu_flush_final := i_alu.io.flush_final_out
|
||||
i0_predict_p_d :=i_alu.io.predict_p_out
|
||||
i_alu.io.a_in :=i0_rs1_d.asSInt
|
||||
i_alu.io.b_in :=i0_rs2_d
|
||||
i_alu.io.dec_i0_pc_d :=io.dec_exu.ib_exu.dec_i0_pc_d
|
||||
i_alu.io.i0_ap :=io.dec_exu.decode_exu.i0_ap
|
||||
val alu_result_x =i_alu.io.result_ff
|
||||
i0_flush_upper_d :=i_alu.io.flush_upper_out
|
||||
i0_flush_path_d :=i_alu.io.flush_path_out
|
||||
io.exu_flush_final := i_alu.io.flush_final_out
|
||||
i0_predict_p_d :=i_alu.io.predict_p_out
|
||||
i0_pred_correct_upper_d :=i_alu.io.pred_correct_out
|
||||
|
||||
val i_mul = Module(new exu_mul_ctl())
|
||||
i_mul.io.scan_mode := io.scan_mode
|
||||
i_mul.io.mul_p := io.dec_exu.decode_exu.mul_p
|
||||
//i_mul.io.mul_p := VecInit.tabulate(io.dec_exu.decode_exu.mul_p.getElements.size-1)(i=>io.dec_exu.decode_exu.mul_p.getElements(i).asUInt & Fill(io.dec_exu.decode_exu.mul_p.getElements.size,io.dec_exu.decode_exu.mul_p.valid)).asTypeOf(io.dec_exu.decode_exu.mul_p) //& io.dec_exu.decode_exu.mul_p.valid
|
||||
i_mul.io.rs1_in := muldiv_rs1_d & Fill(32,io.dec_exu.decode_exu.mul_p.valid)
|
||||
i_mul.io.rs2_in := i0_rs2_d & Fill(32,io.dec_exu.decode_exu.mul_p.valid)
|
||||
i_mul.io.mul_p := io.dec_exu.decode_exu.mul_p
|
||||
i_mul.io.rs1_in := muldiv_rs1_d
|
||||
i_mul.io.rs2_in := muldiv_rs2_d
|
||||
val mul_result_x = i_mul.io.result_x
|
||||
|
||||
val i_div = Module(new exu_div_ctl())
|
||||
i_div.io.dec_div <> io.dec_exu.dec_div
|
||||
i_div.io.scan_mode := io.scan_mode
|
||||
i_div.io.scan_mode := io.scan_mode
|
||||
|
||||
i_div.io.dividend := muldiv_rs1_d
|
||||
i_div.io.divisor := i0_rs2_d
|
||||
i_div.io.divisor := muldiv_rs2_d
|
||||
io.exu_div_wren := i_div.io.exu_div_wren
|
||||
io.exu_div_result := i_div.io.exu_div_result
|
||||
|
||||
io.dec_exu.decode_exu.exu_i0_result_x := Mux(mul_valid_x.asBool, mul_result_x, alu_result_x)
|
||||
i0_predict_newp_d := io.dec_exu.decode_exu.dec_i0_predict_p_d
|
||||
i0_predict_newp_d.bits.boffset := io.dec_exu.ib_exu.dec_i0_pc_d(0) // from the start of inst
|
||||
io.dec_exu.decode_exu.exu_i0_result_x := Mux(mul_valid_x.asBool, mul_result_x, alu_result_x)
|
||||
i0_predict_newp_d := io.dec_exu.decode_exu.dec_i0_predict_p_d
|
||||
i0_predict_newp_d.bits.boffset := io.dec_exu.ib_exu.dec_i0_pc_d(0) // from the start of inst
|
||||
|
||||
io.dec_exu.tlu_exu.exu_pmu_i0_br_misp := i0_pp_r.bits.misp
|
||||
io.dec_exu.tlu_exu.exu_pmu_i0_br_ataken := i0_pp_r.bits.ataken
|
||||
|
@ -176,73 +188,48 @@ class exu extends Module with lib with RequireAsyncReset{
|
|||
i0_taken_d := (i0_predict_p_d.bits.ataken & io.dec_exu.dec_alu.dec_i0_alu_decode_d)
|
||||
|
||||
|
||||
if(BTB_ENABLE) {
|
||||
// maintain GHR at D
|
||||
ghr_d_ns := Mux1H(Seq(
|
||||
(!io.dec_exu.tlu_exu.dec_tlu_flush_lower_r & i0_valid_d).asBool -> Cat(ghr_d(BHT_GHR_SIZE - 2, 0), i0_taken_d),
|
||||
(!io.dec_exu.tlu_exu.dec_tlu_flush_lower_r & !i0_valid_d).asBool -> ghr_d,
|
||||
(io.dec_exu.tlu_exu.dec_tlu_flush_lower_r).asBool -> ghr_x
|
||||
))
|
||||
|
||||
// maintain GHR at X
|
||||
ghr_x_ns := Mux(i0_valid_x === 1.U, Cat(ghr_x(BHT_GHR_SIZE - 2, 0), i0_taken_x), ghr_x)
|
||||
// maintain GHR at D
|
||||
ghr_d_ns:=Mux1H(Seq(
|
||||
(!io.dec_exu.tlu_exu.dec_tlu_flush_lower_r & i0_valid_d).asBool -> Cat(ghr_d(BHT_GHR_SIZE-2,0),i0_taken_d),
|
||||
(!io.dec_exu.tlu_exu.dec_tlu_flush_lower_r & !i0_valid_d).asBool -> ghr_d,
|
||||
(io.dec_exu.tlu_exu.dec_tlu_flush_lower_r).asBool -> ghr_x
|
||||
))
|
||||
|
||||
io.dec_exu.tlu_exu.exu_i0_br_valid_r := i0_pp_r.valid
|
||||
io.dec_exu.tlu_exu.exu_i0_br_mp_r := i0_pp_r.bits.misp
|
||||
io.exu_bp.exu_i0_br_way_r := i0_pp_r.bits.way
|
||||
io.dec_exu.tlu_exu.exu_i0_br_hist_r := Fill(2, i0_pp_r.valid) & i0_pp_r.bits.hist
|
||||
io.dec_exu.tlu_exu.exu_i0_br_error_r := i0_pp_r.bits.br_error
|
||||
io.dec_exu.tlu_exu.exu_i0_br_middle_r := i0_pp_r.bits.pc4 ^ i0_pp_r.bits.boffset
|
||||
io.dec_exu.tlu_exu.exu_i0_br_start_error_r := i0_pp_r.bits.br_start_error
|
||||
io.exu_bp.exu_i0_br_fghr_r := predpipe_r(PREDPIPESIZE - 1, BTB_ADDR_HI + BTB_BTAG_SIZE - BTB_ADDR_LO + 1)
|
||||
io.dec_exu.tlu_exu.exu_i0_br_index_r := predpipe_r(BTB_ADDR_HI + BTB_BTAG_SIZE - BTB_ADDR_LO, BTB_BTAG_SIZE)
|
||||
io.exu_bp.exu_i0_br_index_r := io.dec_exu.tlu_exu.exu_i0_br_index_r
|
||||
final_predict_mp := Mux(i0_flush_upper_x === 1.U, i0_predict_p_x, 0.U.asTypeOf(i0_predict_p_x))
|
||||
val final_predpipe_mp = Mux(i0_flush_upper_x === 1.U, predpipe_x, 0.U)
|
||||
// maintain GHR at X
|
||||
ghr_x_ns:=Mux(i0_valid_x===1.U, Cat(ghr_x(BHT_GHR_SIZE-2,0),i0_taken_x), ghr_x )
|
||||
|
||||
val after_flush_eghr = Mux((i0_flush_upper_x === 1.U & !(io.dec_exu.tlu_exu.dec_tlu_flush_lower_r === 1.U)), ghr_d, ghr_x)
|
||||
io.dec_exu.tlu_exu.exu_i0_br_valid_r := i0_pp_r.valid
|
||||
io.dec_exu.tlu_exu.exu_i0_br_mp_r := i0_pp_r.bits.misp
|
||||
io.exu_bp.exu_i0_br_way_r := i0_pp_r.bits.way
|
||||
io.dec_exu.tlu_exu.exu_i0_br_hist_r := i0_pp_r.bits.hist
|
||||
io.dec_exu.tlu_exu.exu_i0_br_error_r := i0_pp_r.bits.br_error
|
||||
io.dec_exu.tlu_exu.exu_i0_br_middle_r := i0_pp_r.bits.pc4 ^ i0_pp_r.bits.boffset
|
||||
io.dec_exu.tlu_exu.exu_i0_br_start_error_r := i0_pp_r.bits.br_start_error
|
||||
io.exu_bp.exu_i0_br_fghr_r := predpipe_r(PREDPIPESIZE-1,BTB_ADDR_HI+BTB_BTAG_SIZE-BTB_ADDR_LO+1)
|
||||
io.dec_exu.tlu_exu.exu_i0_br_index_r := predpipe_r(BTB_ADDR_HI+BTB_BTAG_SIZE-BTB_ADDR_LO,BTB_BTAG_SIZE)
|
||||
io.exu_bp.exu_i0_br_index_r := io.dec_exu.tlu_exu.exu_i0_br_index_r
|
||||
final_predict_mp := Mux(i0_flush_upper_x===1.U,i0_predict_p_x,0.U.asTypeOf(i0_predict_p_x))
|
||||
val final_predpipe_mp = Mux(i0_flush_upper_x===1.U,predpipe_x,0.U)
|
||||
|
||||
io.exu_bp.exu_mp_pkt.valid := final_predict_mp.valid
|
||||
io.exu_bp.exu_mp_pkt.bits.way := final_predict_mp.bits.way
|
||||
io.exu_bp.exu_mp_pkt.bits.misp := final_predict_mp.bits.misp
|
||||
io.exu_bp.exu_mp_pkt.bits.pcall := final_predict_mp.bits.pcall
|
||||
io.exu_bp.exu_mp_pkt.bits.pja := final_predict_mp.bits.pja
|
||||
io.exu_bp.exu_mp_pkt.bits.pret := final_predict_mp.bits.pret
|
||||
io.exu_bp.exu_mp_pkt.bits.ataken := final_predict_mp.bits.ataken
|
||||
io.exu_bp.exu_mp_pkt.bits.boffset := final_predict_mp.bits.boffset
|
||||
io.exu_bp.exu_mp_pkt.bits.pc4 := final_predict_mp.bits.pc4
|
||||
io.exu_bp.exu_mp_pkt.bits.hist := final_predict_mp.bits.hist(1, 0)
|
||||
io.exu_bp.exu_mp_pkt.bits.toffset := final_predict_mp.bits.toffset(11, 0)
|
||||
io.exu_bp.exu_mp_fghr := after_flush_eghr
|
||||
io.exu_bp.exu_mp_index := final_predpipe_mp(PREDPIPESIZE - BHT_GHR_SIZE - 1, BTB_BTAG_SIZE)
|
||||
io.exu_bp.exu_mp_btag := final_predpipe_mp(BTB_BTAG_SIZE - 1, 0)
|
||||
io.exu_bp.exu_mp_eghr := final_predpipe_mp(PREDPIPESIZE - 1, BTB_ADDR_HI - BTB_ADDR_LO + BTB_BTAG_SIZE + 1) // mp ghr for bht write
|
||||
}
|
||||
else {
|
||||
val after_flush_eghr = Mux((i0_flush_upper_x===1.U & !(io.dec_exu.tlu_exu.dec_tlu_flush_lower_r===1.U)), ghr_d, ghr_x)
|
||||
|
||||
ghr_d_ns := 0.U
|
||||
ghr_x_ns := 0.U
|
||||
io.exu_bp.exu_mp_pkt := 0.U
|
||||
io.exu_bp.exu_mp_eghr := 0.U
|
||||
io.exu_bp.exu_mp_fghr := 0.U
|
||||
io.exu_bp.exu_mp_index := 0.U
|
||||
io.exu_bp.exu_mp_btag := 0.U
|
||||
io.dec_exu.tlu_exu.exu_i0_br_hist_r := 0.U
|
||||
io.dec_exu.tlu_exu.exu_i0_br_error_r := 0.U
|
||||
io.dec_exu.tlu_exu.exu_i0_br_start_error_r := 0.U
|
||||
io.dec_exu.tlu_exu.exu_i0_br_index_r := 0.U
|
||||
io.dec_exu.tlu_exu.exu_i0_br_valid_r := 0.U
|
||||
io.dec_exu.tlu_exu.exu_i0_br_mp_r := 0.U
|
||||
io.dec_exu.tlu_exu.exu_i0_br_middle_r := 0.U
|
||||
io.exu_bp.exu_i0_br_fghr_r := 0.U
|
||||
io.exu_bp.exu_i0_br_way_r := 0.U
|
||||
}
|
||||
io.exu_flush_path_final := Mux1H(Seq(
|
||||
io.dec_exu.tlu_exu.dec_tlu_flush_lower_r.asBool -> io.dec_exu.tlu_exu.dec_tlu_flush_path_r,
|
||||
(~io.dec_exu.tlu_exu.dec_tlu_flush_lower_r & i0_flush_upper_d).asBool -> i0_flush_path_d))
|
||||
|
||||
io.exu_bp.exu_mp_pkt.bits.way := final_predict_mp.bits.way
|
||||
io.exu_bp.exu_mp_pkt.bits.misp := final_predict_mp.bits.misp
|
||||
io.exu_bp.exu_mp_pkt.bits.pcall := final_predict_mp.bits.pcall
|
||||
io.exu_bp.exu_mp_pkt.bits.pja := final_predict_mp.bits.pja
|
||||
io.exu_bp.exu_mp_pkt.bits.pret := final_predict_mp.bits.pret
|
||||
io.exu_bp.exu_mp_pkt.bits.ataken := final_predict_mp.bits.ataken
|
||||
io.exu_bp.exu_mp_pkt.bits.boffset := final_predict_mp.bits.boffset
|
||||
io.exu_bp.exu_mp_pkt.bits.pc4 := final_predict_mp.bits.pc4
|
||||
io.exu_bp.exu_mp_pkt.bits.hist := final_predict_mp.bits.hist(1,0)
|
||||
io.exu_bp.exu_mp_pkt.bits.toffset := final_predict_mp.bits.toffset(11,0)
|
||||
io.exu_bp.exu_mp_fghr := after_flush_eghr
|
||||
io.exu_bp.exu_mp_index := final_predpipe_mp(PREDPIPESIZE-BHT_GHR_SIZE-1,BTB_BTAG_SIZE)
|
||||
io.exu_bp.exu_mp_btag := final_predpipe_mp(BTB_BTAG_SIZE-1,0)
|
||||
io.exu_bp.exu_mp_eghr := final_predpipe_mp(PREDPIPESIZE-1,BTB_ADDR_HI-BTB_ADDR_LO+BTB_BTAG_SIZE+1) // mp ghr for bht write
|
||||
io.exu_flush_path_final := Mux(io.dec_exu.tlu_exu.dec_tlu_flush_lower_r.asBool, io.dec_exu.tlu_exu.dec_tlu_flush_path_r, i0_flush_path_d)
|
||||
io.dec_exu.tlu_exu.exu_npc_r := Mux(i0_pred_correct_upper_r===1.U, pred_correct_npc_r, i0_flush_path_upper_r)
|
||||
}
|
||||
object exu_main extends App {
|
||||
println((new chisel3.stage.ChiselStage).emitVerilog(new exu()))
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ class exu_alu_ctl extends Module with lib with RequireAsyncReset{
|
|||
val io = IO(new Bundle{
|
||||
val dec_alu = new dec_alu()
|
||||
|
||||
val csr_rddata_in = Input(UInt(32.W)) // CSR data
|
||||
val dec_i0_pc_d = Input(UInt(31.W)) // for pc=pc+2,4 calculations
|
||||
val scan_mode = Input(UInt(1.W)) // Scan control
|
||||
val flush_upper_x = Input(UInt(1.W)) // Branch flush from previous cycle
|
||||
|
@ -27,123 +26,15 @@ class exu_alu_ctl extends Module with lib with RequireAsyncReset{
|
|||
val pred_correct_out = Output(UInt(1.W)) // NPC control
|
||||
val predict_p_out = Valid(new predict_pkt_t) // Predicted branch structure
|
||||
})
|
||||
//zbb
|
||||
val ap_clz = WireInit(Bool(),0.B)
|
||||
val ap_ctz = WireInit(Bool(),0.B)
|
||||
val ap_pcnt = WireInit(Bool(),0.B)
|
||||
val ap_sext_b = WireInit(Bool(),0.B)
|
||||
val ap_sext_h = WireInit(Bool(),0.B)
|
||||
val ap_min = WireInit(Bool(),0.B)
|
||||
val ap_max = WireInit(Bool(),0.B)
|
||||
val ap_pack = WireInit(Bool(),0.B)
|
||||
val ap_packu = WireInit(Bool(),0.B)
|
||||
val ap_packh = WireInit(Bool(),0.B)
|
||||
val ap_rol = WireInit(Bool(),0.B)
|
||||
val ap_ror = WireInit(Bool(),0.B)
|
||||
val ap_rev = WireInit(Bool(),0.B)
|
||||
val ap_rev8 = WireInit(Bool(),0.B)
|
||||
val ap_orc_b = WireInit(Bool(),0.B)
|
||||
val ap_orc16 = WireInit(Bool(),0.B)
|
||||
val ap_zbb = WireInit(Bool(),0.B)
|
||||
// Zbs
|
||||
val ap_sbset = WireInit(Bool(),0.B)
|
||||
val ap_sbclr = WireInit(Bool(),0.B)
|
||||
val ap_sbinv = WireInit(Bool(),0.B)
|
||||
val ap_sbext = WireInit(Bool(),0.B)
|
||||
|
||||
// Zbr
|
||||
val ap_slo = WireInit(Bool(),0.B)
|
||||
val ap_sro = WireInit(Bool(),0.B)
|
||||
|
||||
// Zba
|
||||
val ap_sh1add = WireInit(Bool(),0.B)
|
||||
val ap_sh2add = WireInit(Bool(),0.B)
|
||||
val ap_sh3add = WireInit(Bool(),0.B)
|
||||
val ap_zba = WireInit(Bool(),0.B)
|
||||
|
||||
if (BITMANIP_ZBB) {
|
||||
ap_clz := io.i0_ap.clz
|
||||
ap_ctz := io.i0_ap.ctz
|
||||
ap_pcnt := io.i0_ap.pcnt
|
||||
ap_sext_b := io.i0_ap.sext_b
|
||||
ap_sext_h := io.i0_ap.sext_h
|
||||
ap_min := io.i0_ap.min
|
||||
ap_max := io.i0_ap.max
|
||||
} else{
|
||||
ap_clz := 0.U
|
||||
ap_ctz := 0.U
|
||||
ap_pcnt := 0.U
|
||||
ap_sext_b := 0.U
|
||||
ap_sext_h := 0.U
|
||||
ap_min := 0.U
|
||||
ap_max := 0.U
|
||||
}
|
||||
if ( (BITMANIP_ZBB) | (BITMANIP_ZBP) ) {
|
||||
ap_pack := io.i0_ap.pack
|
||||
ap_packu := io.i0_ap.packu
|
||||
ap_packh := io.i0_ap.packh
|
||||
ap_rol := io.i0_ap.rol
|
||||
ap_ror := io.i0_ap.ror
|
||||
ap_rev := io.i0_ap.grev & (io.b_in(4,0) === "b11111".U)
|
||||
ap_rev8 := io.i0_ap.grev & (io.b_in(4,0) === "b11000".U)
|
||||
ap_orc_b := io.i0_ap.gorc & (io.b_in(4,0) === "b00111".U)
|
||||
ap_orc16 := io.i0_ap.gorc & (io.b_in(4,0) === "b10000".U)
|
||||
ap_zbb := io.i0_ap.zbb
|
||||
} else{
|
||||
ap_pack := 0.U
|
||||
ap_packu := 0.U
|
||||
ap_packh := 0.U
|
||||
ap_rol := 0.U
|
||||
ap_ror := 0.U
|
||||
ap_rev := 0.U
|
||||
ap_rev8 := 0.U
|
||||
ap_orc_b := 0.U
|
||||
ap_orc16 := 0.U
|
||||
ap_zbb := 0.U
|
||||
}
|
||||
if (BITMANIP_ZBS) {
|
||||
ap_sbset := io.i0_ap.sbset
|
||||
ap_sbclr := io.i0_ap.sbclr
|
||||
ap_sbinv := io.i0_ap.sbinv
|
||||
ap_sbext := io.i0_ap.sbext
|
||||
}else {
|
||||
ap_sbset := 0.U
|
||||
ap_sbclr := 0.U
|
||||
ap_sbinv := 0.U
|
||||
ap_sbext := 0.U
|
||||
}
|
||||
if (BITMANIP_ZBP) {
|
||||
ap_slo := io.i0_ap.slo
|
||||
ap_sro := io.i0_ap.sro
|
||||
} else {
|
||||
ap_slo := 0.U
|
||||
ap_sro := 0.U
|
||||
}
|
||||
if (BITMANIP_ZBA) {
|
||||
ap_sh1add := io.i0_ap.sh1add
|
||||
ap_sh2add := io.i0_ap.sh2add
|
||||
ap_sh3add := io.i0_ap.sh3add
|
||||
ap_zba := io.i0_ap.zba
|
||||
} else {
|
||||
ap_sh1add := 0.U
|
||||
ap_sh2add := 0.U
|
||||
ap_sh3add := 0.U
|
||||
ap_zba := 0.U
|
||||
}
|
||||
io.dec_alu.exu_i0_pc_x := rvdffpcie(io.dec_i0_pc_d,io.enable,reset.asAsyncReset(),clock,io.scan_mode.asBool) // any PC is run through here - doesn't have to be alu
|
||||
io.dec_alu.exu_i0_pc_x := rvdffe(io.dec_i0_pc_d,io.enable,clock,io.scan_mode.asBool) // any PC is run through here - doesn't have to be alu
|
||||
val result = WireInit(UInt(32.W),0.U)
|
||||
io.result_ff := rvdffe(result,io.enable & io.dec_alu.dec_i0_alu_decode_d,clock,io.scan_mode.asBool)
|
||||
|
||||
val zba_a_in = Mux1H(Seq(
|
||||
ap_sh1add -> Cat(io.a_in(30,0),0.U(1.W)).asSInt ,
|
||||
ap_sh2add -> Cat(io.a_in(29,0),0.U(2.W)).asSInt ,
|
||||
ap_sh3add -> Cat(io.a_in(28,0),0.U(3.W)).asSInt ,
|
||||
~ap_zba -> io.a_in ))
|
||||
io.result_ff := rvdffe(result,io.enable,clock,io.scan_mode.asBool)
|
||||
|
||||
val bm = Mux( io.i0_ap.sub.asBool, ~io.b_in, io.b_in) //H:b modified
|
||||
|
||||
val aout = WireInit(UInt(33.W),0.U)
|
||||
aout := Mux(io.i0_ap.sub.asBool,(Cat(0.U(1.W),zba_a_in) + Cat(0.U(1.W),~io.b_in) + Cat(0.U(32.W),io.i0_ap.sub)), (Cat(0.U(1.W),io.a_in) + Cat(0.U(1.W), io.b_in) + Cat(0.U(32.W),io.i0_ap.sub)))
|
||||
aout := Mux(io.i0_ap.sub.asBool,(Cat(0.U(1.W),io.a_in) + Cat(0.U(1.W),~io.b_in) + Cat(0.U(32.W),io.i0_ap.sub)), (Cat(0.U(1.W),io.a_in) + Cat(0.U(1.W), io.b_in) + Cat(0.U(32.W),io.i0_ap.sub)))
|
||||
val cout = aout(32)
|
||||
|
||||
val ov = (!io.a_in(31) & !bm(31) & aout(31)) | ( io.a_in(31) & bm(31) & !aout(31) ) //overflow check from last bits
|
||||
|
@ -155,143 +46,31 @@ class exu_alu_ctl extends Module with lib with RequireAsyncReset{
|
|||
val ge = !lt // if not less then
|
||||
|
||||
|
||||
val lout = Mux1H(Seq(
|
||||
io.dec_alu.dec_csr_ren_d -> io.csr_rddata_in.asSInt ,
|
||||
(io.i0_ap.land & !ap_zbb).asBool -> (Cat(0.U(1.W),io.a_in).asSInt & io.b_in.asSInt) ,
|
||||
(io.i0_ap.lor & !ap_zbb).asBool -> (Cat(0.U(1.W),io.a_in).asSInt | io.b_in.asSInt) ,
|
||||
(io.i0_ap.lxor & !ap_zbb).asBool -> (Cat(0.U(1.W),io.a_in).asSInt ^ io.b_in.asSInt) ,
|
||||
(io.i0_ap.land & ap_zbb).asBool -> (Cat(0.U(1.W),io.a_in).asSInt & ~io.b_in.asSInt) ,
|
||||
(io.i0_ap.lor & ap_zbb).asBool -> (Cat(0.U(1.W),io.a_in).asSInt | ~io.b_in.asSInt) ,
|
||||
(io.i0_ap.lxor & ap_zbb).asBool -> (Cat(0.U(1.W),io.a_in).asSInt ^ ~io.b_in.asSInt) ))
|
||||
|
||||
|
||||
// val lout = Mux1H(Seq(
|
||||
// io.dec_alu.dec_csr_ren_d.asBool -> io.b_in.asSInt, //read enable read rs2
|
||||
// io.i0_ap.land.asBool -> (io.a_in & io.b_in.asSInt), //and rs1 and 2
|
||||
// io.i0_ap.lor.asBool -> (io.a_in | io.b_in.asSInt),
|
||||
// io.i0_ap.lxor.asBool -> (io.a_in ^ io.b_in.asSInt)))
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : SLO,SRO * * * * * * * * * * * * * * * * * *
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : ROL,ROR * * * * * * * * * * * * * * * * * *
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : ZBEXT * * * * * * * * * * * * * * * * * *
|
||||
val lout = Mux1H(Seq(
|
||||
io.dec_alu.dec_csr_ren_d.asBool -> io.b_in.asSInt, //read enable read rs2
|
||||
io.i0_ap.land.asBool -> (io.a_in & io.b_in.asSInt), //and rs1 and 2
|
||||
io.i0_ap.lor.asBool -> (io.a_in | io.b_in.asSInt),
|
||||
io.i0_ap.lxor.asBool -> (io.a_in ^ io.b_in.asSInt)))
|
||||
|
||||
val shift_amount = Mux1H(Seq (
|
||||
io.i0_ap.sll.asBool -> (32.U(6.W) - Cat(0.U(1.W),io.b_in(4,0))), // [5] unused
|
||||
io.i0_ap.srl.asBool -> Cat(0.U(1.W),io.b_in(4,0)) ,
|
||||
io.i0_ap.sra.asBool -> Cat(0.U(1.W),io.b_in(4,0)) ,
|
||||
ap_rol -> (32.U(6.W) - Cat(0.U(1.W),io.b_in(4,0)) ) ,
|
||||
ap_ror -> Cat(0.U(1.W),io.b_in(4,0)) ,
|
||||
ap_slo -> (32.U(6.W) - Cat(0.U(1.W),io.b_in(4,0)) ) ,
|
||||
ap_sro -> Cat(0.U(1.W),io.b_in(4,0)) ,
|
||||
ap_sbext -> Cat(0.U(1.W),io.b_in(4,0)) ))
|
||||
io.i0_ap.sra.asBool -> Cat(0.U(1.W),io.b_in(4,0)) ))
|
||||
|
||||
val shift_mask = WireInit(UInt(32.W),0.U)
|
||||
shift_mask := ( "hffffffff".U(32.W) << (repl(5,io.i0_ap.sll | ap_slo) & io.b_in(4,0)) )
|
||||
shift_mask := ( "hffffffff".U(32.W) << (repl(5,io.i0_ap.sll) & io.b_in(4,0)) )
|
||||
|
||||
val shift_extend = WireInit(UInt(63.W),0.U)
|
||||
shift_extend := Cat((repl(31,io.i0_ap.sra) & repl(31,io.a_in(31))) | (repl(31,io.i0_ap.sll) & io.a_in(30,0)), io.a_in)
|
||||
|
||||
shift_extend := Cat( Mux1H(Seq(io.i0_ap.sra.asBool() -> Fill(31,io.a_in(31)) ,
|
||||
io.i0_ap.sll.asBool() -> io.a_in(30,0) ,
|
||||
ap_rol -> io.a_in(30,0) ,
|
||||
ap_ror -> io.a_in(30,0) ,
|
||||
ap_slo -> io.a_in(30,0) ,
|
||||
ap_sro -> Fill(31,1.U) )),io.a_in)
|
||||
shift_extend := Cat((repl(31,io.i0_ap.sra) & repl(31,io.a_in(31))) | (repl(31,io.i0_ap.sll) & io.a_in(30,0)),io.a_in)
|
||||
|
||||
val shift_long = WireInit(UInt(63.W),0.U)
|
||||
shift_long := ( shift_extend >> shift_amount(4,0) ) // 62-32 unused
|
||||
shift_long := ( shift_extend >> shift_amount(4,0) ); // 62-32 unused
|
||||
|
||||
val sout = ( shift_long(31,0) & shift_mask(31,0) ) | ( Fill(32,ap_slo) & ~shift_mask(31,0) ) //incase of sra shift_mask is 1
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : CLZ,CTZ * * * * * * * * * * * * * * * * * *
|
||||
|
||||
val bitmanip_a_reverse_ff = (0 until io.a_in.getWidth).map(i=> io.a_in(i).asUInt).reduce(Cat(_,_))
|
||||
// {a_in[0], a_in[1], a_in[2], a_in[3], a_in[4], a_in[5], a_in[6], a_in[7],
|
||||
// a_in[8], a_in[9], a_in[10], a_in[11], a_in[12], a_in[13], a_in[14], a_in[15],
|
||||
// a_in[16], a_in[17], a_in[18], a_in[19], a_in[20], a_in[21], a_in[22], a_in[23],
|
||||
// a_in[24], a_in[25], a_in[26], a_in[27], a_in[28], a_in[29], a_in[30], a_in[31]};
|
||||
|
||||
val bitmanip_lzd_in = Mux1H(Seq(ap_clz -> io.a_in, ap_ctz -> bitmanip_a_reverse_ff.asSInt))
|
||||
/////////////////////
|
||||
val bitmanip_lzd_os = bitmanip_lzd_in
|
||||
val bitmanip_dw_lzd_enc = WireInit(UInt(6.W),0.U)
|
||||
|
||||
bitmanip_dw_lzd_enc := MuxCase(0.U,(0 until 32).map(i=> (bitmanip_lzd_os(31,i)===0.U)->(32-i).U))//return leading zeros
|
||||
|
||||
val bitmanip_clz_ctz_result = Cat(Fill(6, ap_clz | ap_ctz) & bitmanip_dw_lzd_enc(5), Fill(5,!bitmanip_dw_lzd_enc(5)) & bitmanip_dw_lzd_enc(4,0) )
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : PCNT * * * * * * * * * * * * * * * * * *
|
||||
|
||||
val bitmanip_pcnt_result = Fill(6,ap_pcnt) & PopCount(io.a_in)
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : SEXT_B,SEXT_H * * * * * * * * * * * * * * * * *
|
||||
val sout = ( shift_long(31,0) & shift_mask(31,0) ); //incase of sra shift_mask is 1
|
||||
|
||||
|
||||
val bitmanip_sext_result = Mux1H(Seq(ap_sext_b -> Cat( Fill(24,io.a_in(7)) ,io.a_in(7,0)),
|
||||
ap_sext_h -> Cat( Fill(16,io.a_in(15)),io.a_in(15,0))) )
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : MIN,MAX,MINU,MAXU * * * * * * * * * * * * * * *
|
||||
|
||||
val bitmanip_minmax_sel = ap_min | ap_max;
|
||||
|
||||
val bitmanip_minmax_sel_a = ge ^ ap_min;
|
||||
|
||||
val bitmanip_minmax_result = Mux1H(Seq(
|
||||
(bitmanip_minmax_sel & bitmanip_minmax_sel_a) -> io.a_in,
|
||||
(bitmanip_minmax_sel & !bitmanip_minmax_sel_a) -> io.b_in.asSInt ))
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : PACK, PACKU, PACKH * * * * * * * * * * * * * * *
|
||||
|
||||
|
||||
val bitmanip_pack_result = Fill(32,ap_pack) & Cat(io.b_in(15,0), io.a_in(15,0))
|
||||
val bitmanip_packu_result = Fill(32,ap_packu) & Cat(io.b_in(31,16),io.a_in(31,16))
|
||||
val bitmanip_packh_result = Fill(32,ap_packh) & Cat(0.U(16.W),io.b_in(7,0),io.a_in(7,0))
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : REV, REV8, ORC_B * * * * * * * * * * * * * * * *
|
||||
|
||||
val bitmanip_rev_result = Fill(32,ap_rev) & (0 until io.a_in.getWidth).map(i=> io.a_in(i).asUInt).reduce(Cat(_,_))
|
||||
|
||||
val bitmanip_rev8_result = Fill(32,ap_rev8) & (0 until io.a_in.getWidth/8).map(i=> io.a_in(7+i*8,0+i*8).asUInt).reduce(Cat(_,_)) //{a_in[7:0],a_in[15:8],a_in[23:16],a_in[31:24]};
|
||||
|
||||
|
||||
// uint32_t gorc32(uint32_t rs1, uint32_t rs2)
|
||||
// {
|
||||
// uint32_t x = rs1;
|
||||
// int shamt = rs2 & 31; ORC.B ORC16
|
||||
// if (shamt & 1) x |= ((x & 0x55555555) << 1) | ((x & 0xAAAAAAAA) >> 1); 1 0
|
||||
// if (shamt & 2) x |= ((x & 0x33333333) << 2) | ((x & 0xCCCCCCCC) >> 2); 1 0
|
||||
// if (shamt & 4) x |= ((x & 0x0F0F0F0F) << 4) | ((x & 0xF0F0F0F0) >> 4); 1 0
|
||||
// if (shamt & 8) x |= ((x & 0x00FF00FF) << 8) | ((x & 0xFF00FF00) >> 8); 0 0
|
||||
// if (shamt & 16) x |= ((x & 0x0000FFFF) << 16) | ((x & 0xFFFF0000) >> 16); 0 1
|
||||
// return x;
|
||||
// }
|
||||
|
||||
|
||||
// BEFORE 31 , 30 , 29 , 28 , 27 , 26, 25, 24
|
||||
// shamt[0] b = a31|a30,a31|a30,a29|a28,a29|a28, a27|a26,a27|a26,a25|a24,a25|a24
|
||||
// shamt[1] c = b31|b29,b30|b28,b31|b29,b30|b28, b27|b25,b26|b24,b27|b25,b26|b24
|
||||
// shamt[2] d = c31|c27,c30|c26,c29|c25,c28|c24, c31|c27,c30|c26,c29|c25,c28|c24
|
||||
//
|
||||
// Expand d31 = c31 | c27;
|
||||
// = b31 | b29 | b27 | b25;
|
||||
// = a31|a30 | a29|a28 | a27|a26 | a25|a24
|
||||
|
||||
val bitmanip_orc_b_result = Fill(32,ap_orc_b) & (0 until io.a_in.getWidth/8).map(i=> Fill(8,io.a_in(7+i*8,0+i*8).orR).asUInt).reverse.reduce(Cat(_,_)) //{ {8{| a_in[31:24]}}, {8{| a_in[23:16]}}, {8{| a_in[15:8]}}, {8{| a_in[7:0]}} };
|
||||
|
||||
val bitmanip_orc16_result = Fill(32,ap_orc16) & Cat(io.a_in(31,16) | io.a_in(15,0), io.a_in(31,16) | io.a_in(15,0))
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : ZBSET, ZBCLR, ZBINV * * * * * * * * * * * * * *
|
||||
|
||||
val bitmanip_sb_1hot = "h00000001".U(32.W) << io.b_in(4,0)
|
||||
|
||||
val bitmanip_sb_data = Mux1H(Seq(
|
||||
ap_sbset -> ( io.a_in | bitmanip_sb_1hot(31,0).asSInt),
|
||||
ap_sbclr -> ( io.a_in & ~bitmanip_sb_1hot(31,0).asSInt),
|
||||
ap_sbinv -> ( io.a_in ^ bitmanip_sb_1hot(31,0).asSInt) ))
|
||||
|
||||
|
||||
val sel_shift = io.i0_ap.sll | io.i0_ap.srl | io.i0_ap.sra | ap_slo | ap_sro | ap_rol | ap_ror
|
||||
val sel_adder = (io.i0_ap.add | io.i0_ap.sub | ap_zba) & !io.i0_ap.slt & !ap_min & !ap_max
|
||||
val sel_shift = io.i0_ap.sll | io.i0_ap.srl | io.i0_ap.sra
|
||||
val sel_adder = (io.i0_ap.add | io.i0_ap.sub) & !io.i0_ap.slt
|
||||
val sel_pc = io.i0_ap.jal | io.pp_in.bits.pcall | io.pp_in.bits.pja | io.pp_in.bits.pret
|
||||
val csr_write_data = Mux(io.i0_ap.csr_imm.asBool, io.b_in.asSInt, io.a_in)
|
||||
|
||||
|
@ -301,29 +80,11 @@ class exu_alu_ctl extends Module with lib with RequireAsyncReset{
|
|||
// for jal or pcall, it will be the link address pc+2 or pc+4
|
||||
val pcout = rvbradder(Cat(io.dec_i0_pc_d,0.U),Cat(io.dec_alu.dec_i0_br_immed_d,0.U))
|
||||
|
||||
result := lout(31,0) | (Fill(32,sel_shift) & sout(31,0)) |
|
||||
(Fill(32,sel_adder) & aout(31,0)) |
|
||||
(Fill(32,sel_pc) & pcout ) |
|
||||
(Fill(32,io.i0_ap.csr_write) & csr_write_data(31,0)) |
|
||||
Cat(0.U(31.W), slt_one) |
|
||||
(Fill(32,ap_sbext) & Cat(0.U(31.W), sout(0))) |
|
||||
(Cat(0.U(26.W), bitmanip_clz_ctz_result(5,0))) |
|
||||
(Cat(0.U(26.W), bitmanip_pcnt_result(5,0)) ) |
|
||||
bitmanip_sext_result(31,0) |
|
||||
bitmanip_minmax_result(31,0) |
|
||||
bitmanip_pack_result(31,0) |
|
||||
bitmanip_packu_result(31,0) |
|
||||
bitmanip_packh_result(31,0) |
|
||||
bitmanip_rev_result(31,0) |
|
||||
bitmanip_rev8_result(31,0) |
|
||||
bitmanip_orc_b_result(31,0) |
|
||||
bitmanip_orc16_result(31,0) |
|
||||
bitmanip_sb_data(31,0)
|
||||
// lout(31,0) | Cat(0.U(31.W),slt_one) | (Mux1H(Seq(
|
||||
// sel_shift.asBool -> sout(31,0),
|
||||
// sel_adder.asBool -> aout(31,0),
|
||||
// sel_pc.asBool -> pcout,
|
||||
// io.i0_ap.csr_write.asBool -> csr_write_data(31,0))))
|
||||
result := lout(31,0) | Cat(0.U(31.W),slt_one) | (Mux1H(Seq(
|
||||
sel_shift.asBool -> sout(31,0),
|
||||
sel_adder.asBool -> aout(31,0),
|
||||
sel_pc.asBool -> pcout,
|
||||
io.i0_ap.csr_write.asBool -> csr_write_data(31,0))))
|
||||
|
||||
// *** branch handling ***
|
||||
|
||||
|
@ -360,3 +121,5 @@ class exu_alu_ctl extends Module with lib with RequireAsyncReset{
|
|||
io.predict_p_out.bits.ataken := actual_taken; // send a control signal telling it branch taken or not
|
||||
io.predict_p_out.bits.hist := newhist
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package exu
|
||||
|
||||
import chisel3.{util, _}
|
||||
import chisel3._
|
||||
import chisel3.experimental.chiselName
|
||||
import chisel3.util._
|
||||
import include._
|
||||
|
@ -8,93 +8,13 @@ import lib._
|
|||
|
||||
@chiselName
|
||||
class exu_div_ctl extends Module with RequireAsyncReset with lib {
|
||||
val io = IO(new Bundle {
|
||||
val scan_mode = Input(Bool())
|
||||
val dividend = Input(UInt(32.W))
|
||||
val divisor = Input(UInt(32.W))
|
||||
val exu_div_result = Output(UInt(32.W))
|
||||
val exu_div_wren = Output(UInt(1.W))
|
||||
val dec_div = new dec_div()
|
||||
})
|
||||
|
||||
val out_raw =WireInit(0.U(32.W))
|
||||
io.exu_div_result := Fill(32,io.exu_div_wren) & out_raw
|
||||
if(!DIV_NEW) {
|
||||
val divider_old = Module(new exu_div_existing_1bit_cheapshortq())
|
||||
divider_old.io.scan_mode := io.scan_mode
|
||||
divider_old.io.cancel := io.dec_div.dec_div_cancel
|
||||
divider_old.io.valid_in := io.dec_div.div_p.valid
|
||||
divider_old.io.signed_in := ~io.dec_div.div_p.bits.unsign
|
||||
divider_old.io.rem_in := io.dec_div.div_p.bits.rem
|
||||
divider_old.io.dividend_in := io.dividend
|
||||
divider_old.io.divisor_in := io.divisor
|
||||
out_raw := divider_old.io.data_out
|
||||
io.exu_div_wren := divider_old.io.valid_out
|
||||
}
|
||||
if(DIV_NEW & DIV_BIT==1) {
|
||||
val divider_new1 = Module(new exu_div_new_1bit_fullshortq())
|
||||
divider_new1.io.scan_mode := io.scan_mode
|
||||
divider_new1.io.cancel := io.dec_div.dec_div_cancel
|
||||
divider_new1.io.valid_in := io.dec_div.div_p.valid
|
||||
divider_new1.io.signed_in := ~io.dec_div.div_p.bits.unsign
|
||||
divider_new1.io.rem_in := io.dec_div.div_p.bits.rem
|
||||
divider_new1.io.dividend_in := io.dividend
|
||||
divider_new1.io.divisor_in := io.divisor
|
||||
out_raw := divider_new1.io.data_out
|
||||
io.exu_div_wren := divider_new1.io.valid_out
|
||||
}
|
||||
if(DIV_NEW & DIV_BIT==2) {
|
||||
val divider_new2 = Module(new exu_div_new_2bit_fullshortq())
|
||||
divider_new2.io.scan_mode := io.scan_mode
|
||||
divider_new2.io.cancel := io.dec_div.dec_div_cancel
|
||||
divider_new2.io.valid_in := io.dec_div.div_p.valid
|
||||
divider_new2.io.signed_in := ~io.dec_div.div_p.bits.unsign
|
||||
divider_new2.io.rem_in := io.dec_div.div_p.bits.rem
|
||||
divider_new2.io.dividend_in := io.dividend
|
||||
divider_new2.io.divisor_in := io.divisor
|
||||
out_raw := divider_new2.io.data_out
|
||||
io.exu_div_wren := divider_new2.io.valid_out
|
||||
}
|
||||
if(DIV_NEW & DIV_BIT==3) {
|
||||
val divider_new3 = Module(new exu_div_new_3bit_fullshortq())
|
||||
divider_new3.io.scan_mode := io.scan_mode
|
||||
divider_new3.io.cancel := io.dec_div.dec_div_cancel
|
||||
divider_new3.io.valid_in := io.dec_div.div_p.valid
|
||||
divider_new3.io.signed_in := ~io.dec_div.div_p.bits.unsign
|
||||
divider_new3.io.rem_in := io.dec_div.div_p.bits.rem
|
||||
divider_new3.io.dividend_in := io.dividend
|
||||
divider_new3.io.divisor_in := io.divisor
|
||||
out_raw := divider_new3.io.data_out
|
||||
io.exu_div_wren := divider_new3.io.valid_out
|
||||
}
|
||||
if(DIV_NEW & DIV_BIT==4) {
|
||||
val divider_new4 = Module(new exu_div_new_4bit_fullshortq())
|
||||
divider_new4.io.scan_mode := io.scan_mode
|
||||
divider_new4.io.cancel := io.dec_div.dec_div_cancel
|
||||
divider_new4.io.valid_in := io.dec_div.div_p.valid
|
||||
divider_new4.io.signed_in := ~io.dec_div.div_p.bits.unsign
|
||||
divider_new4.io.rem_in := io.dec_div.div_p.bits.rem
|
||||
divider_new4.io.dividend_in := io.dividend
|
||||
divider_new4.io.divisor_in := io.divisor
|
||||
out_raw := divider_new4.io.data_out
|
||||
io.exu_div_wren := divider_new4.io.valid_out
|
||||
}
|
||||
}
|
||||
object div_main extends App {
|
||||
println((new chisel3.stage.ChiselStage).emitVerilog(new exu_div_ctl()))
|
||||
}
|
||||
////////////////////////////////////////// OLD DIVIDER /////////////////////////////////////
|
||||
class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset with lib {
|
||||
val io = IO(new Bundle{
|
||||
val scan_mode = Input(Bool())
|
||||
val cancel = Input(Bool())
|
||||
val valid_in = Input(Bool())
|
||||
val signed_in = Input(Bool())
|
||||
val rem_in = Input(Bool())
|
||||
val dividend_in = Input(UInt(32.W))
|
||||
val divisor_in = Input(UInt(32.W))
|
||||
val data_out = Output(UInt(32.W))
|
||||
val valid_out = Output(UInt(1.W))
|
||||
val scan_mode = Input(Bool())
|
||||
val dividend = Input(UInt(32.W))
|
||||
val divisor = Input(UInt(32.W))
|
||||
val exu_div_result = Output(UInt(32.W))
|
||||
val exu_div_wren = Output(UInt(1.W))
|
||||
val dec_div = new dec_div()
|
||||
})
|
||||
val run_state = WireInit(0.U(1.W))
|
||||
val count = WireInit(0.U(6.W))
|
||||
|
@ -113,7 +33,7 @@ class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset wi
|
|||
val rem_ff = WireInit(0.U(1.W))
|
||||
val add = WireInit(0.U(1.W))
|
||||
val a_eff = WireInit(0.U(33.W))
|
||||
val a_eff_shift = WireInit(0.U(65.W))
|
||||
val a_eff_shift = WireInit(0.U(56.W))
|
||||
val rem_correct = WireInit(0.U(1.W))
|
||||
val valid_ff_x = WireInit(0.U(1.W))
|
||||
val finish_ff = WireInit(0.U(1.W))
|
||||
|
@ -123,8 +43,7 @@ class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset wi
|
|||
val count_in = WireInit(0.U(6.W))
|
||||
val dividend_eff = WireInit(0.U(32.W))
|
||||
val a_shift = WireInit(0.U(33.W))
|
||||
val shortq = WireInit(0.U(6.W))
|
||||
val valid_x = valid_ff_x & !io.cancel
|
||||
val valid_x = valid_ff_x & !io.dec_div.dec_div_cancel
|
||||
|
||||
// START - short circuit logic for small numbers {{
|
||||
// small number divides - any 4b / 4b is done in 1 cycle (divisor != 0)
|
||||
|
@ -134,9 +53,9 @@ class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset wi
|
|||
((q_ff(31,0) === 0.U) & (m_ff(31,0) =/= 0.U) & !rem_ff & valid_x)
|
||||
|
||||
def pat(x : List[Int], y : List[Int]) = {
|
||||
val pat_a = (0 until x.size).map(i=> if(x(i)>=0) q_ff(x(i)) else !q_ff(x(i).abs)).reduce(_&_)
|
||||
val pat_b = (0 until y.size).map(i=> if(y(i)>=0) m_ff(y(i)) else !m_ff(y(i).abs)).reduce(_&_)
|
||||
pat_a & pat_b
|
||||
val pat1 = (0 until x.size).map(i=> if(x(i)>=0) q_ff(x(i)) else !q_ff(x(i).abs)).reduce(_&_)
|
||||
val pat2 = (0 until y.size).map(i=> if(y(i)>=0) m_ff(y(i)) else !m_ff(y(i).abs)).reduce(_&_)
|
||||
pat1 & pat2
|
||||
}
|
||||
|
||||
val smallnum = Cat(
|
||||
|
@ -168,32 +87,32 @@ class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset wi
|
|||
short_dividend := Cat (sign_ff & q_ff(31),q_ff(31,0))
|
||||
|
||||
|
||||
val a_cls = Cat(0.U(2.W),
|
||||
val a_cls = Cat(
|
||||
Mux1H(Seq (
|
||||
!short_dividend(32).asBool -> (short_dividend(31,24) =/= Fill(8,0.U)),
|
||||
short_dividend(32).asBool -> (short_dividend(31,23) =/= Fill(9,1.U))
|
||||
short_dividend(32).asBool -> (short_dividend(31,23) =/= Fill(9,1.U))
|
||||
)),
|
||||
Mux1H(Seq (
|
||||
!short_dividend(32).asBool -> (short_dividend(23,16) =/= Fill(8,0.U)),
|
||||
short_dividend(32).asBool -> (short_dividend(22,15) =/= Fill(8,1.U))
|
||||
short_dividend(32).asBool -> (short_dividend(22,15) =/= Fill(8,1.U))
|
||||
)),
|
||||
Mux1H(Seq (
|
||||
!short_dividend(32).asBool -> (short_dividend(15,8) =/= Fill(8,0.U)),
|
||||
short_dividend(32).asBool -> (short_dividend(14,7) =/= Fill(8,1.U))
|
||||
short_dividend(32).asBool -> (short_dividend(14,7) =/= Fill(8,1.U))
|
||||
))
|
||||
)
|
||||
val b_cls = Cat(0.U(2.W),
|
||||
val b_cls = Cat(
|
||||
Mux1H(Seq (
|
||||
!m_ff(32).asBool -> (m_ff(31,24) =/= Fill(8,0.U)),
|
||||
m_ff(32).asBool -> (m_ff(31,24) =/= Fill(8,1.U))
|
||||
m_ff(32).asBool -> (m_ff(31,24) =/= Fill(8,1.U))
|
||||
)),
|
||||
Mux1H(Seq (
|
||||
!m_ff(32).asBool -> (m_ff(23,16) =/= Fill(8,0.U)),
|
||||
m_ff(32).asBool -> (m_ff(23,16) =/= Fill(8,1.U))
|
||||
m_ff(32).asBool -> (m_ff(23,16) =/= Fill(8,1.U))
|
||||
)),
|
||||
Mux1H(Seq (
|
||||
!m_ff(32).asBool -> (m_ff(15,8) =/= Fill(8,0.U)),
|
||||
m_ff(32).asBool -> (m_ff(15,8) =/= Fill(8,1.U))
|
||||
m_ff(32).asBool -> (m_ff(15,8) =/= Fill(8,1.U))
|
||||
))
|
||||
)
|
||||
val shortq_raw = Cat(
|
||||
|
@ -209,7 +128,7 @@ class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset wi
|
|||
( (a_cls(2,0) === "b001".U ) & (b_cls(2,0) === "b001".U ) ) |
|
||||
( (a_cls(2,0) === "b000".U ) & (b_cls(2,0) === "b000".U ) ) ,
|
||||
|
||||
( (a_cls(2) === "b1".U ) & (b_cls(2,1) === "b01".U ) ) | // Shift by 16
|
||||
( (a_cls(2) === "b1".U ) & (b_cls(2,1) === "b01".U ) ) | // Shift by 16
|
||||
( (a_cls(2,1) === "b01".U ) & (b_cls(2,0) === "b001".U ) ) |
|
||||
( (a_cls(2,0) === "b001".U ) & (b_cls(2,0) === "b000".U ) ) ,
|
||||
|
||||
|
@ -218,37 +137,43 @@ class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset wi
|
|||
|
||||
)
|
||||
val shortq_enable = valid_ff_x & (m_ff(31,0) =/= 0.U(32.W)) & (shortq_raw =/= 0.U(4.W))
|
||||
val shortq_shift = Cat(0.U(2.W),Fill(4,shortq_enable) & shortq_raw)
|
||||
val shortq_shift_ff = Cat(0.U(1.W),Mux1H(Seq (
|
||||
val shortq_shift = Fill(4,shortq_enable) & shortq_raw
|
||||
|
||||
val shortq_shift_ff = Mux1H(Seq (
|
||||
shortq_shift_xx(3).asBool -> "b11111".U,
|
||||
shortq_shift_xx(2).asBool -> "b11000".U,
|
||||
shortq_shift_xx(1).asBool -> "b10000".U,
|
||||
shortq_shift_xx(0).asBool -> "b01000".U
|
||||
)))
|
||||
))
|
||||
// *** End Short *** }}
|
||||
|
||||
val finish = smallnum_case | Mux(!rem_ff ,count === 32.U(6.W) ,count === 33.U(6.W))
|
||||
val div_clken = io.valid_in | run_state | finish | finish_ff
|
||||
val run_in = (io.valid_in | run_state) & !finish & !io.cancel
|
||||
count_in := Fill(6,(run_state & !finish & !io.cancel & !shortq_enable)) & (count + Cat(0.U,shortq_shift_ff(4,0)) + (1.U)(6.W))
|
||||
io.valid_out := finish_ff & !io.cancel
|
||||
val sign_eff = io.signed_in & (io.divisor_in =/= 0.U(32.W))
|
||||
val div_clken = io.dec_div.div_p.valid | run_state | finish | finish_ff
|
||||
val run_in = (io.dec_div.div_p.valid | run_state) & !finish & !io.dec_div.dec_div_cancel
|
||||
count_in := Fill(6,(run_state & !finish & !io.dec_div.dec_div_cancel & !shortq_enable)) & (count + Cat(0.U,shortq_shift_ff) + (1.U)(6.W))
|
||||
//io.test := count_in
|
||||
|
||||
io.exu_div_wren := finish_ff & !io.dec_div.dec_div_cancel
|
||||
val sign_eff = !io.dec_div.div_p.bits.unsign & (io.divisor =/= 0.U(32.W))
|
||||
|
||||
|
||||
q_in := Mux1H(Seq(
|
||||
(!run_state).asBool -> Cat(0.U(1.W),io.dividend_in) ,
|
||||
(run_state & (valid_ff_x | shortq_enable_ff)).asBool -> (Cat(dividend_eff(31,0),!a_in(32)) << shortq_shift_ff(4,0)) ,
|
||||
(!run_state).asBool -> Cat(0.U(1.W),io.dividend) ,
|
||||
(run_state & (valid_ff_x | shortq_enable_ff)).asBool -> (Cat(dividend_eff(31,0),!a_in(32)) << shortq_shift_ff) ,
|
||||
(run_state & !(valid_ff_x | shortq_enable_ff)).asBool -> Cat(q_ff(31,0),!a_in(32))
|
||||
))
|
||||
val qff_enable = io.valid_in | (run_state & !shortq_enable)
|
||||
val qff_enable = io.dec_div.div_p.valid | (run_state & !shortq_enable)
|
||||
dividend_eff := Mux((sign_ff & dividend_neg_ff).asBool, rvtwoscomp(q_ff(31,0)),q_ff(31,0))
|
||||
|
||||
|
||||
m_eff := Mux(add.asBool , m_ff, ~m_ff )
|
||||
a_eff_shift := Cat(0.U(33.W), dividend_eff) << shortq_shift_ff(4,0)
|
||||
a_eff_shift := Cat(0.U(24.W), dividend_eff) << shortq_shift_ff
|
||||
a_eff := Mux1H(Seq(
|
||||
rem_correct.asBool -> a_ff ,
|
||||
(!rem_correct & !shortq_enable_ff).asBool -> Cat(a_ff(31,0), q_ff(32)) ,
|
||||
(!rem_correct & shortq_enable_ff).asBool -> a_eff_shift(64,32)
|
||||
(!rem_correct & shortq_enable_ff).asBool -> Cat(0.U(9.W),a_eff_shift(55,32))
|
||||
))
|
||||
val aff_enable = io.valid_in | (run_state & !shortq_enable & (count =/= 33.U(6.W))) | rem_correct
|
||||
val aff_enable = io.dec_div.div_p.valid | (run_state & !shortq_enable & (count =/= 33.U(6.W))) | rem_correct
|
||||
a_shift := Fill(33,run_state) & a_eff
|
||||
a_in := Fill(33,run_state) & (a_shift + m_eff + Cat(0.U(32.W),!add))
|
||||
val m_already_comp = divisor_neg_ff & sign_ff
|
||||
|
@ -258,698 +183,29 @@ class exu_div_existing_1bit_cheapshortq extends Module with RequireAsyncReset wi
|
|||
val q_ff_eff = Mux((sign_ff & (dividend_neg_ff ^ divisor_neg_ff)).asBool,rvtwoscomp(q_ff(31,0)), q_ff(31,0))
|
||||
val a_ff_eff = Mux((sign_ff & dividend_neg_ff ).asBool, rvtwoscomp(a_ff(31,0)), a_ff(31,0))
|
||||
|
||||
io.data_out := Mux1H(Seq(
|
||||
io.exu_div_result := Mux1H(Seq(
|
||||
smallnum_case_ff.asBool -> Cat(0.U(28.W), smallnum_ff),
|
||||
rem_ff.asBool -> a_ff_eff ,
|
||||
(!smallnum_case_ff & !rem_ff).asBool -> q_ff_eff
|
||||
))
|
||||
valid_ff_x := rvdffe(io.valid_in & !io.cancel, div_clken,clock,io.scan_mode)
|
||||
finish_ff := rvdffe(finish & !io.cancel, div_clken,clock,io.scan_mode)
|
||||
run_state := rvdffe(run_in,div_clken,clock,io.scan_mode)
|
||||
count := rvdffe(count_in, div_clken,clock,io.scan_mode)
|
||||
dividend_neg_ff := rvdffe((io.valid_in & io.dividend_in(31)) | (!io.valid_in & dividend_neg_ff), div_clken,clock,io.scan_mode)
|
||||
divisor_neg_ff := rvdffe((io.valid_in & io.divisor_in(31)) | (!io.valid_in & divisor_neg_ff), div_clken,clock,io.scan_mode)
|
||||
sign_ff := rvdffe((io.valid_in & sign_eff) | (!io.valid_in & sign_ff), div_clken,clock,io.scan_mode)
|
||||
rem_ff := rvdffe((io.valid_in & io.rem_in) | (!io.valid_in & rem_ff), div_clken,clock,io.scan_mode)
|
||||
smallnum_case_ff := rvdffe(smallnum_case, div_clken,clock,io.scan_mode)
|
||||
smallnum_ff := rvdffe(smallnum, div_clken,clock,io.scan_mode)
|
||||
shortq_enable_ff := rvdffe(shortq_enable, div_clken,clock,io.scan_mode)
|
||||
shortq_shift_xx := rvdffe(shortq_shift, div_clken,clock,io.scan_mode)
|
||||
q_ff := rvdffe(q_in, qff_enable,clock,io.scan_mode)
|
||||
a_ff := rvdffe(a_in, aff_enable,clock,io.scan_mode)
|
||||
m_ff := rvdffe(Cat(io.signed_in & io.divisor_in(31), io.divisor_in(31,0)), io.valid_in,clock,io.scan_mode)
|
||||
|
||||
}
|
||||
/////////////////////////////////////////////// 1 BIT FULL DIVIDER//////////////////////////////////
|
||||
class exu_div_new_1bit_fullshortq extends Module with RequireAsyncReset with lib {
|
||||
val io = IO(new Bundle{
|
||||
val scan_mode = Input(Bool())
|
||||
val cancel = Input(Bool())
|
||||
val valid_in = Input(Bool())
|
||||
val signed_in = Input(Bool())
|
||||
val rem_in = Input(Bool())
|
||||
val dividend_in = Input(UInt(32.W))
|
||||
val divisor_in = Input(UInt(32.W))
|
||||
val data_out = Output(UInt(32.W))
|
||||
val valid_out = Output(UInt(1.W))
|
||||
})
|
||||
val valid_ff = WireInit(Bool(),init=false.B)
|
||||
val finish_ff = WireInit(Bool(),init=false.B)
|
||||
val control_ff = WireInit(0.U(3.W))
|
||||
val count_ff = WireInit(0.U(7.W))
|
||||
val smallnum = WireInit(0.U(4.W))
|
||||
val a_ff = WireInit(0.U(32.W))
|
||||
val b_ff = WireInit(0.U(33.W))
|
||||
val q_ff = WireInit(0.U(32.W))
|
||||
val r_ff = WireInit(0.U(32.W))
|
||||
val quotient_set = WireInit(Bool(),init=false.B)
|
||||
val shortq_enable = WireInit(Bool(),init=false.B)
|
||||
val shortq_enable_ff = WireInit(Bool(),init=false.B)
|
||||
val by_zero_case_ff = WireInit(Bool(),init=false.B)
|
||||
val adder_out = WireInit(0.U(33.W))
|
||||
val ar_shifted = WireInit(0.U(64.W))
|
||||
val shortq_shift_ff = WireInit(0.U(5.W))
|
||||
val dividend_sign_ff = control_ff(2)
|
||||
val divisor_sign_ff = control_ff(1)
|
||||
val rem_ff = control_ff(0)
|
||||
val by_zero_case = valid_ff & (b_ff(31,0) === 0.U)
|
||||
val smallnum_case = ((a_ff(31,4) === 0.U) & (b_ff(31,4) === 0.U) & !by_zero_case & !rem_ff & valid_ff & !io.cancel) |
|
||||
((a_ff(31,0) === 0.U) & !by_zero_case & !rem_ff & valid_ff & !io.cancel)
|
||||
val valid_ff_in = io.valid_in & !io.cancel
|
||||
val control_in = Cat((!io.valid_in & control_ff(2)) | (io.valid_in & io.signed_in & io.dividend_in(31)), (!io.valid_in & control_ff(1)) | (io.valid_in & io.signed_in & io.divisor_in(31)), (!io.valid_in & control_ff(0)) | (io.valid_in & io.rem_in))
|
||||
val running_state = count_ff.orR() | shortq_enable_ff
|
||||
val misc_enable = io.valid_in | valid_ff | io.cancel | running_state | finish_ff
|
||||
val finish_raw = smallnum_case | by_zero_case | (count_ff === 32.U)
|
||||
val finish = finish_raw & !io.cancel
|
||||
val count_enable = (valid_ff | running_state) & !finish & !finish_ff & !io.cancel & !shortq_enable
|
||||
val count_in = Fill(7,count_enable) & (count_ff + Cat(0.U(6.W),1.U) + Cat(0.U(2.W),shortq_shift_ff))
|
||||
val a_enable = io.valid_in | running_state
|
||||
val a_shift = running_state & !shortq_enable_ff
|
||||
ar_shifted := Cat (Fill(32,dividend_sign_ff),a_ff) << shortq_shift_ff
|
||||
val b_twos_comp = valid_ff & !(dividend_sign_ff ^ divisor_sign_ff)
|
||||
val twos_comp_b_sel = valid_ff & !(dividend_sign_ff ^ divisor_sign_ff)
|
||||
val twos_comp_q_sel = !valid_ff & !rem_ff & (dividend_sign_ff ^ divisor_sign_ff) & !by_zero_case_ff
|
||||
val b_enable = io.valid_in | b_twos_comp
|
||||
val rq_enable = io.valid_in | valid_ff | running_state
|
||||
val r_sign_sel = valid_ff & dividend_sign_ff & !by_zero_case
|
||||
val r_restore_sel = running_state & !quotient_set & !shortq_enable_ff
|
||||
val r_adder_sel = running_state & quotient_set & !shortq_enable_ff
|
||||
val twos_comp_in = Mux1H(Seq (
|
||||
twos_comp_q_sel -> q_ff,
|
||||
twos_comp_b_sel -> b_ff(31,0)
|
||||
))
|
||||
val twos_comp_out = rvtwoscomp(twos_comp_in)
|
||||
val exu_div_cgc = rvclkhdr(clock,div_clken.asBool,io.scan_mode)
|
||||
|
||||
val a_in = Mux1H(Seq (
|
||||
(!a_shift & !shortq_enable_ff).asBool -> io.dividend_in,
|
||||
a_shift -> Cat(a_ff(30,0),0.U),
|
||||
shortq_enable_ff -> ar_shifted(31,0)
|
||||
))
|
||||
val b_in = Mux1H(Seq (
|
||||
!b_twos_comp -> Cat(io.signed_in & io.divisor_in(31),io.divisor_in(31,0)),
|
||||
b_twos_comp -> Cat(!divisor_sign_ff,twos_comp_out(31,0))
|
||||
))
|
||||
val r_in = Mux1H (Seq(
|
||||
r_sign_sel -> "hffffffff".U(32.W),
|
||||
r_restore_sel -> Cat(r_ff(30,0),a_ff(31)),
|
||||
r_adder_sel -> adder_out(31,0),
|
||||
shortq_enable_ff -> ar_shifted(63,32),
|
||||
by_zero_case -> a_ff
|
||||
))
|
||||
val q_in = Mux1H (Seq(
|
||||
!valid_ff -> Cat(q_ff(30,0),quotient_set),
|
||||
smallnum_case -> Cat(0.U(28.W),smallnum),
|
||||
by_zero_case -> Fill(32,1.U)
|
||||
))
|
||||
adder_out := Cat(r_ff,a_ff(31)) + b_ff
|
||||
quotient_set := (!adder_out(32) ^ dividend_sign_ff) | ((a_ff(30,0) === 0.U) & (adder_out === 0.U))
|
||||
io.valid_out := finish_ff & !io.cancel
|
||||
io.data_out := Mux1H(Seq(
|
||||
(!rem_ff & !twos_comp_q_sel).asBool() -> q_ff,
|
||||
rem_ff -> r_ff,
|
||||
twos_comp_q_sel -> twos_comp_out
|
||||
))
|
||||
def pat1(x : List[Int], y : List[Int]) = {
|
||||
val pat_a = (0 until x.size).map(i=> if(x(i)>=0) a_ff(x(i)) else !a_ff(x(i).abs)).reduce(_&_)
|
||||
val pat_b = (0 until y.size).map(i=> if(y(i)>=0) b_ff(y(i)) else !b_ff(y(i).abs)).reduce(_&_)
|
||||
pat_a & pat_b
|
||||
withClock(exu_div_cgc) {
|
||||
valid_ff_x := RegNext(io.dec_div.div_p.valid & !io.dec_div.dec_div_cancel, 0.U)
|
||||
finish_ff := RegNext(finish & !io.dec_div.dec_div_cancel, 0.U)
|
||||
run_state := RegNext(run_in, 0.U)
|
||||
count := RegNext(count_in, 0.U)
|
||||
dividend_neg_ff := RegEnable(io.dividend(31), 0.U, io.dec_div.div_p.valid.asBool)
|
||||
divisor_neg_ff := RegEnable(io.divisor(31), 0.U, io.dec_div.div_p.valid.asBool)
|
||||
sign_ff := RegEnable(sign_eff, 0.U, io.dec_div.div_p.valid.asBool)
|
||||
rem_ff := RegEnable(io.dec_div.div_p.bits.rem, 0.U, io.dec_div.div_p.valid.asBool)
|
||||
smallnum_case_ff := RegNext(smallnum_case, 0.U)
|
||||
smallnum_ff := RegNext(smallnum, 0.U)
|
||||
shortq_enable_ff := RegNext(shortq_enable, 0.U)
|
||||
shortq_shift_xx := RegNext(shortq_shift, 0.U)
|
||||
}
|
||||
|
||||
smallnum := Cat(
|
||||
pat1(List(3),List(-3, -2, -1)),
|
||||
|
||||
pat1(List(3),List(-3, -2))& !b_ff(0) | pat1(List(2),List(-3, -2, -1)) | pat1(List(3, 2),List(-3, -2)),
|
||||
|
||||
pat1(List(2),List(-3, -2))& !b_ff(0) | pat1(List(1),List(-3, -2, -1)) | pat1(List(3),List(-3, -1))& !b_ff(0) |
|
||||
pat1(List(3, -2),List(-3, -2, 1, 0)) | pat1(List(-3, 2, 1),List(-3, -2)) | pat1(List(3, 2),List(-3))& !b_ff(0) |
|
||||
pat1(List(3, 2),List(-3, 2, -1)) | pat1(List(3, 1),List(-3,-1)) | pat1(List(3, 2, 1),List(-3, 2)),
|
||||
|
||||
pat1(List(2, 1, 0),List(-3, -1)) | pat1(List(3, -2, 0),List(-3, 1, 0)) | pat1(List(2),List(-3, -1))& !b_ff(0) |
|
||||
pat1(List(1),List(-3, -2))& !b_ff(0) | pat1(List(0),List(-3, -2, -1)) | pat1(List(-3, 2, -1),List(-3, -2, 1, 0)) |
|
||||
pat1(List(-3, 2, 1),List(-3))& !b_ff(0) | pat1(List(3),List(-2, -1)) & !b_ff(0) | pat1(List(3, -2),List(-3, 2, 1)) |
|
||||
pat1(List(-3, 2, 1),List(-3, 2, -1)) | pat1(List(-3, 2, 0),List(-3, -1)) | pat1(List(3, -2, -1),List(-3, 2, 0)) |
|
||||
pat1(List(-2, 1, 0),List(-3, -2)) | pat1(List(3, 2),List(-1)) & !b_ff(0) | pat1(List(-3, 2, 1, 0),List(-3, 2)) |
|
||||
pat1(List(3, 2),List(3, -2)) | pat1(List(3, 1),List(3,-2,-1)) | pat1(List(3, 0),List(-2, -1)) |
|
||||
pat1(List(3, -1),List(-3, 2, 1, 0)) | pat1(List(3, 2, 1),List(3)) & !b_ff(0) | pat1(List(3, 2, 1),List(3, -1)) |
|
||||
pat1(List(3, 2, 0),List(3, -1)) | pat1(List(3, -2, 1),List(-3, 1)) | pat1(List(3, 1, 0),List(-2)) |
|
||||
pat1(List(3, 2, 1, 0),List(3)) |pat1(List(3, 1),List(-2)) & !b_ff(0))
|
||||
|
||||
val shortq_dividend = Cat(dividend_sign_ff,a_ff)
|
||||
val a_enc = Module(new exu_div_cls)
|
||||
a_enc.io.operand := shortq_dividend
|
||||
val dw_a_enc1 = a_enc.io.cls
|
||||
val b_enc = Module(new exu_div_cls)
|
||||
b_enc.io.operand := b_ff
|
||||
val dw_b_enc1 = b_enc.io.cls
|
||||
val dw_a_enc = Cat (0.U, dw_a_enc1)
|
||||
val dw_b_enc = Cat (0.U, dw_b_enc1)
|
||||
val dw_shortq_raw = Cat(0.U,dw_b_enc) - Cat(0.U,dw_a_enc) + 1.U(7.W)
|
||||
val shortq = Mux(dw_shortq_raw(6).asBool(),0.U,dw_shortq_raw(5,0))
|
||||
shortq_enable := valid_ff & !shortq(5) & !(shortq(4,1) === "b1111".U) & !io.cancel
|
||||
val shortq_shift = Mux(!shortq_enable,0.U,("b11111".U - shortq(4,0)))
|
||||
valid_ff := rvdffe(valid_ff_in, misc_enable,clock,io.scan_mode)
|
||||
control_ff := rvdffe(control_in, misc_enable,clock,io.scan_mode)
|
||||
by_zero_case_ff := rvdffe(by_zero_case,misc_enable,clock,io.scan_mode)
|
||||
shortq_enable_ff := rvdffe(shortq_enable, misc_enable,clock,io.scan_mode)
|
||||
shortq_shift_ff := rvdffe(shortq_shift, misc_enable,clock,io.scan_mode)
|
||||
finish_ff := rvdffe(finish, misc_enable,clock,io.scan_mode)
|
||||
count_ff := rvdffe(count_in, misc_enable,clock,io.scan_mode)
|
||||
|
||||
a_ff := rvdffe(a_in, a_enable,clock,io.scan_mode)
|
||||
b_ff := rvdffe(b_in, b_enable,clock,io.scan_mode)
|
||||
r_ff := rvdffe(r_in, rq_enable,clock,io.scan_mode)
|
||||
q_ff := rvdffe(q_in, rq_enable,clock,io.scan_mode)
|
||||
}
|
||||
/////////////////////////////////////////////// 2 BIT FULL DIVIDER//////////////////////////////////
|
||||
class exu_div_new_2bit_fullshortq extends Module with RequireAsyncReset with lib {
|
||||
val io = IO(new Bundle{
|
||||
val scan_mode = Input(Bool())
|
||||
val cancel = Input(Bool())
|
||||
val valid_in = Input(Bool())
|
||||
val signed_in = Input(Bool())
|
||||
val rem_in = Input(Bool())
|
||||
val dividend_in = Input(UInt(32.W))
|
||||
val divisor_in = Input(UInt(32.W))
|
||||
val data_out = Output(UInt(32.W))
|
||||
val valid_out = Output(UInt(1.W))
|
||||
})
|
||||
val valid_ff = WireInit(Bool(),init=false.B)
|
||||
val finish_ff = WireInit(Bool(),init=false.B)
|
||||
val control_ff = WireInit(0.U(3.W))
|
||||
val count_ff = WireInit(0.U(7.W))
|
||||
val smallnum = WireInit(0.U(4.W))
|
||||
val a_ff = WireInit(0.U(32.W))
|
||||
val b_ff1 = WireInit(0.U(33.W))
|
||||
val b_ff = WireInit(0.U(35.W))
|
||||
val q_ff = WireInit(0.U(32.W))
|
||||
val r_ff = WireInit(0.U(32.W))
|
||||
val quotient_raw = WireInit(0.U(4.W))
|
||||
val quotient_new = WireInit(0.U(2.W))
|
||||
val shortq_enable = WireInit(Bool(),init=false.B)
|
||||
val shortq_enable_ff = WireInit(Bool(),init=false.B)
|
||||
val by_zero_case_ff = WireInit(Bool(),init=false.B)
|
||||
val ar_shifted = WireInit(0.U(64.W))
|
||||
val shortq_shift_ff = WireInit(0.U(5.W))
|
||||
val valid_ff_in = io.valid_in & !io.cancel
|
||||
val control_in = Cat((!io.valid_in & control_ff(2)) | (io.valid_in & io.signed_in & io.dividend_in(31)), (!io.valid_in & control_ff(1)) | (io.valid_in & io.signed_in & io.divisor_in(31)), (!io.valid_in & control_ff(0)) | (io.valid_in & io.rem_in))
|
||||
val dividend_sign_ff = control_ff(2)
|
||||
val divisor_sign_ff = control_ff(1)
|
||||
val rem_ff = control_ff(0)
|
||||
val by_zero_case = valid_ff & (b_ff(31,0) === 0.U)
|
||||
val smallnum_case = ((a_ff(31,4) === 0.U) & (b_ff(31,4) === 0.U) & !by_zero_case & !rem_ff & valid_ff & !io.cancel) |
|
||||
((a_ff(31,0) === 0.U) & !by_zero_case & !rem_ff & valid_ff & !io.cancel)
|
||||
val running_state = count_ff.orR() | shortq_enable_ff
|
||||
val misc_enable = io.valid_in | valid_ff | io.cancel | running_state | finish_ff
|
||||
val finish_raw = smallnum_case | by_zero_case | (count_ff === 32.U)
|
||||
val finish = finish_raw & !io.cancel
|
||||
val count_enable = (valid_ff | running_state) & !finish & !finish_ff & !io.cancel & !shortq_enable
|
||||
val count_in = Fill(7,count_enable) & (count_ff + Cat(0.U(5.W),2.U) + Cat(0.U(2.W),shortq_shift_ff(4,1),0.U))
|
||||
val a_enable = io.valid_in | running_state
|
||||
val a_shift = running_state & !shortq_enable_ff
|
||||
ar_shifted := Cat (Fill(32,dividend_sign_ff),a_ff) << Cat(shortq_shift_ff(4,1),0.U)
|
||||
val b_twos_comp = valid_ff & !(dividend_sign_ff ^ divisor_sign_ff)
|
||||
val twos_comp_b_sel = valid_ff & !(dividend_sign_ff ^ divisor_sign_ff)
|
||||
val twos_comp_q_sel = !valid_ff & !rem_ff & (dividend_sign_ff ^ divisor_sign_ff) & !by_zero_case_ff
|
||||
val b_enable = io.valid_in | b_twos_comp
|
||||
val rq_enable = io.valid_in | valid_ff | running_state
|
||||
val r_sign_sel = valid_ff & dividend_sign_ff & !by_zero_case
|
||||
val r_restore_sel = running_state & (quotient_new === 0.U) & !shortq_enable_ff
|
||||
val r_adder1_sel = running_state & (quotient_new === 1.U) & !shortq_enable_ff
|
||||
val r_adder2_sel = running_state & (quotient_new === 2.U) & !shortq_enable_ff
|
||||
val r_adder3_sel = running_state & (quotient_new === 3.U) & !shortq_enable_ff
|
||||
val adder1_out = Cat(r_ff(30,0),a_ff(31,30)) + b_ff(32,0)
|
||||
val adder2_out = Cat(r_ff(31,0),a_ff(31,30)) + Cat(b_ff(32,0),0.U)
|
||||
val adder3_out = Cat(r_ff(31),r_ff(31,0),a_ff(31,30)) + Cat(b_ff(33,0),0.U) + b_ff
|
||||
quotient_raw := Cat((!adder3_out(34) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder3_out === 0.U)),
|
||||
(!adder2_out(33) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder2_out === 0.U)),
|
||||
(!adder1_out(32) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder1_out === 0.U)),0.U)
|
||||
quotient_new := Cat ((quotient_raw(3) | quotient_raw(2)) , (quotient_raw(3) |(!quotient_raw(2) & quotient_raw(1))))
|
||||
val twos_comp_in = Mux1H(Seq (
|
||||
twos_comp_q_sel -> q_ff,
|
||||
twos_comp_b_sel -> b_ff(31,0)
|
||||
))
|
||||
val twos_comp_out = rvtwoscomp(twos_comp_in)
|
||||
|
||||
val a_in = Mux1H(Seq (
|
||||
(!a_shift & !shortq_enable_ff).asBool -> io.dividend_in,
|
||||
a_shift -> Cat(a_ff(29,0),0.U(2.W)),
|
||||
shortq_enable_ff -> ar_shifted(31,0)
|
||||
))
|
||||
|
||||
val b_in = Mux1H(Seq (
|
||||
!b_twos_comp -> Cat(io.signed_in & io.divisor_in(31),io.divisor_in(31,0)),
|
||||
b_twos_comp -> Cat(!divisor_sign_ff,twos_comp_out(31,0))
|
||||
))
|
||||
val r_in = Mux1H (Seq(
|
||||
r_sign_sel -> "hffffffff".U(32.W),
|
||||
r_restore_sel -> Cat(r_ff(29,0),a_ff(31,30)),
|
||||
r_adder1_sel -> adder1_out(31,0),
|
||||
r_adder2_sel -> adder2_out(31,0),
|
||||
r_adder3_sel -> adder3_out(31,0),
|
||||
shortq_enable_ff -> ar_shifted(63,32),
|
||||
by_zero_case -> a_ff
|
||||
))
|
||||
val q_in = Mux1H (Seq(
|
||||
!valid_ff -> Cat(q_ff(29,0),quotient_new),
|
||||
smallnum_case -> Cat(0.U(28.W),smallnum),
|
||||
by_zero_case -> Fill(32,1.U)
|
||||
))
|
||||
io.valid_out := finish_ff & !io.cancel
|
||||
io.data_out := Mux1H(Seq(
|
||||
(!rem_ff & !twos_comp_q_sel).asBool() -> q_ff,
|
||||
rem_ff -> r_ff,
|
||||
twos_comp_q_sel -> twos_comp_out
|
||||
))
|
||||
def pat1(x : List[Int], y : List[Int]) = {
|
||||
val pat_a = (0 until x.size).map(i=> if(x(i)>=0) a_ff(x(i)) else !a_ff(x(i).abs)).reduce(_&_)
|
||||
val pat_b = (0 until y.size).map(i=> if(y(i)>=0) b_ff(y(i)) else !b_ff(y(i).abs)).reduce(_&_)
|
||||
pat_a & pat_b
|
||||
}
|
||||
smallnum := Cat(
|
||||
pat1(List(3),List(-3, -2, -1)),
|
||||
|
||||
pat1(List(3),List(-3, -2))& !b_ff(0) | pat1(List(2),List(-3, -2, -1)) | pat1(List(3, 2),List(-3, -2)),
|
||||
|
||||
pat1(List(2),List(-3, -2))& !b_ff(0) | pat1(List(1),List(-3, -2, -1)) | pat1(List(3),List(-3, -1))& !b_ff(0) |
|
||||
pat1(List(3, -2),List(-3, -2, 1, 0)) | pat1(List(-3, 2, 1),List(-3, -2)) | pat1(List(3, 2),List(-3))& !b_ff(0) |
|
||||
pat1(List(3, 2),List(-3, 2, -1)) | pat1(List(3, 1),List(-3,-1)) | pat1(List(3, 2, 1),List(-3, 2)),
|
||||
|
||||
pat1(List(2, 1, 0),List(-3, -1)) | pat1(List(3, -2, 0),List(-3, 1, 0)) | pat1(List(2),List(-3, -1))& !b_ff(0) |
|
||||
pat1(List(1),List(-3, -2))& !b_ff(0) | pat1(List(0),List(-3, -2, -1)) | pat1(List(-3, 2, -1),List(-3, -2, 1, 0)) |
|
||||
pat1(List(-3, 2, 1),List(-3))& !b_ff(0) | pat1(List(3),List(-2, -1)) & !b_ff(0) | pat1(List(3, -2),List(-3, 2, 1)) |
|
||||
pat1(List(-3, 2, 1),List(-3, 2, -1)) | pat1(List(-3, 2, 0),List(-3, -1)) | pat1(List(3, -2, -1),List(-3, 2, 0)) |
|
||||
pat1(List(-2, 1, 0),List(-3, -2)) | pat1(List(3, 2),List(-1)) & !b_ff(0) | pat1(List(-3, 2, 1, 0),List(-3, 2)) |
|
||||
pat1(List(3, 2),List(3, -2)) | pat1(List(3, 1),List(3,-2,-1)) | pat1(List(3, 0),List(-2, -1)) |
|
||||
pat1(List(3, -1),List(-3, 2, 1, 0)) | pat1(List(3, 2, 1),List(3)) & !b_ff(0) | pat1(List(3, 2, 1),List(3, -1)) |
|
||||
pat1(List(3, 2, 0),List(3, -1)) | pat1(List(3, -2, 1),List(-3, 1)) | pat1(List(3, 1, 0),List(-2)) |
|
||||
pat1(List(3, 2, 1, 0),List(3)) |pat1(List(3, 1),List(-2)) & !b_ff(0))
|
||||
|
||||
val shortq_dividend = Cat(dividend_sign_ff,a_ff)
|
||||
val a_enc = Module(new exu_div_cls)
|
||||
a_enc.io.operand := shortq_dividend
|
||||
val dw_a_enc1 = a_enc.io.cls
|
||||
val b_enc = Module(new exu_div_cls)
|
||||
b_enc.io.operand := b_ff(32,0)
|
||||
val dw_b_enc1 = b_enc.io.cls
|
||||
val dw_a_enc = Cat (0.U, dw_a_enc1)
|
||||
val dw_b_enc = Cat (0.U, dw_b_enc1)
|
||||
val dw_shortq_raw = Cat(0.U,dw_b_enc) - Cat(0.U,dw_a_enc) + 1.U(7.W)
|
||||
val shortq = Mux(dw_shortq_raw(6).asBool(),0.U,dw_shortq_raw(5,0))
|
||||
shortq_enable := valid_ff & !shortq(5) & !(shortq(4,1) === "b1111".U) & !io.cancel
|
||||
val shortq_shift = Mux(!shortq_enable,0.U,("b11111".U - shortq(4,0)))
|
||||
b_ff := Cat(b_ff1(32),b_ff1(32),b_ff1)
|
||||
valid_ff := rvdffe(valid_ff_in, misc_enable,clock,io.scan_mode)
|
||||
control_ff := rvdffe(control_in, misc_enable,clock,io.scan_mode)
|
||||
by_zero_case_ff := rvdffe(by_zero_case,misc_enable,clock,io.scan_mode)
|
||||
shortq_enable_ff := rvdffe(shortq_enable, misc_enable,clock,io.scan_mode)
|
||||
shortq_shift_ff := Cat(rvdffe(shortq_shift(4,1), misc_enable,clock,io.scan_mode),0.U)
|
||||
finish_ff := rvdffe(finish, misc_enable,clock,io.scan_mode)
|
||||
count_ff := rvdffe(count_in, misc_enable,clock,io.scan_mode)
|
||||
|
||||
a_ff := rvdffe(a_in, a_enable,clock,io.scan_mode)
|
||||
b_ff1 := rvdffe(b_in(32,0), b_enable,clock,io.scan_mode)
|
||||
r_ff := rvdffe(r_in, rq_enable,clock,io.scan_mode)
|
||||
q_ff := rvdffe(q_in, rq_enable,clock,io.scan_mode)
|
||||
|
||||
}
|
||||
/////////////////////////////////////////////// 3 BIT FULL DIVIDER//////////////////////////////////
|
||||
class exu_div_new_3bit_fullshortq extends Module with RequireAsyncReset with lib {
|
||||
val io = IO(new Bundle{
|
||||
val scan_mode = Input(Bool())
|
||||
val cancel = Input(Bool())
|
||||
val valid_in = Input(Bool())
|
||||
val signed_in = Input(Bool())
|
||||
val rem_in = Input(Bool())
|
||||
val dividend_in = Input(UInt(32.W))
|
||||
val divisor_in = Input(UInt(32.W))
|
||||
val data_out = Output(UInt(32.W))
|
||||
val valid_out = Output(UInt(1.W))
|
||||
})
|
||||
val valid_ff = WireInit(Bool(),init=false.B)
|
||||
val finish_ff = WireInit(Bool(),init=false.B)
|
||||
val control_ff = WireInit(0.U(3.W))
|
||||
val count_ff = WireInit(0.U(7.W))
|
||||
val smallnum = WireInit(0.U(4.W))
|
||||
val a_ff = WireInit(0.U(33.W))
|
||||
val b_ff1 = WireInit(0.U(33.W))
|
||||
val b_ff = WireInit(0.U(37.W))
|
||||
val q_ff = WireInit(0.U(32.W))
|
||||
val r_ff = WireInit(0.U(33.W))
|
||||
val quotient_raw = WireInit(0.U(8.W))
|
||||
val quotient_new = WireInit(0.U(3.W))
|
||||
val shortq_enable = WireInit(Bool(),init=false.B)
|
||||
val shortq_enable_ff = WireInit(Bool(),init=false.B)
|
||||
val by_zero_case_ff = WireInit(Bool(),init=false.B)
|
||||
val ar_shifted = WireInit(0.U(66.W))
|
||||
val shortq_shift = WireInit(0.U(5.W))
|
||||
val shortq_decode = WireInit(0.U(5.W))
|
||||
val shortq_shift_ff = WireInit(0.U(5.W))
|
||||
val valid_ff_in = io.valid_in & !io.cancel
|
||||
val control_in = Cat((!io.valid_in & control_ff(2)) | (io.valid_in & io.signed_in & io.dividend_in(31)), (!io.valid_in & control_ff(1)) | (io.valid_in & io.signed_in & io.divisor_in(31)), (!io.valid_in & control_ff(0)) | (io.valid_in & io.rem_in))
|
||||
val dividend_sign_ff = control_ff(2)
|
||||
val divisor_sign_ff = control_ff(1)
|
||||
val rem_ff = control_ff(0)
|
||||
val by_zero_case = valid_ff & (b_ff(31,0) === 0.U)
|
||||
|
||||
val smallnum_case = ((a_ff(31,4) === 0.U) & (b_ff(31,4) === 0.U) & !by_zero_case & !rem_ff & valid_ff & !io.cancel) |
|
||||
((a_ff(31,0) === 0.U) & !by_zero_case & !rem_ff & valid_ff & !io.cancel)
|
||||
val running_state = count_ff.orR() | shortq_enable_ff
|
||||
val misc_enable = io.valid_in | valid_ff | io.cancel | running_state | finish_ff
|
||||
val finish_raw = smallnum_case | by_zero_case | (count_ff === 33.U)
|
||||
val finish = finish_raw & !io.cancel
|
||||
val count_enable = (valid_ff | running_state) & !finish & !finish_ff & !io.cancel & !shortq_enable
|
||||
val count_in = Fill(7,count_enable) & (count_ff + Cat(0.U(5.W),3.U(2.W)) + Cat(0.U(2.W),shortq_shift_ff))
|
||||
val a_enable = io.valid_in | running_state
|
||||
val a_shift = running_state & !shortq_enable_ff
|
||||
ar_shifted := Cat (Fill(33,dividend_sign_ff),a_ff) << shortq_shift_ff(4,0)
|
||||
val b_twos_comp = valid_ff & !(dividend_sign_ff ^ divisor_sign_ff)
|
||||
val twos_comp_b_sel = valid_ff & !(dividend_sign_ff ^ divisor_sign_ff)
|
||||
val twos_comp_q_sel = !valid_ff & !rem_ff & (dividend_sign_ff ^ divisor_sign_ff) & !by_zero_case_ff
|
||||
val b_enable = io.valid_in | b_twos_comp
|
||||
val rq_enable = io.valid_in | valid_ff | running_state
|
||||
val r_sign_sel = valid_ff & dividend_sign_ff & !by_zero_case
|
||||
|
||||
val r_adder_sel = (0 to 7 ).map(i=> (running_state & (quotient_new === i.asUInt) & !shortq_enable_ff))
|
||||
val adder1_out = Cat(r_ff(30,0),a_ff(32,30)) + b_ff(33,0)
|
||||
val adder2_out = Cat(r_ff(31,0),a_ff(32,30)) + Cat(b_ff(33,0),0.U)
|
||||
val adder3_out = Cat(r_ff(32,0),a_ff(32,30)) + Cat(b_ff(34,0),0.U) + b_ff(35,0)
|
||||
val adder4_out = Cat(r_ff(32),r_ff(32,0),a_ff(32,30)) + Cat(b_ff(34,0),0.U(2.W))
|
||||
val adder5_out = Cat(r_ff(32),r_ff(32,0),a_ff(32,30)) + Cat(b_ff(34,0),0.U(2.W)) + b_ff
|
||||
val adder6_out = Cat(r_ff(32),r_ff(32,0),a_ff(32,30)) + Cat(b_ff(34,0),0.U(2.W)) + Cat(b_ff(35,0),0.U)
|
||||
val adder7_out = Cat(r_ff(32),r_ff(32,0),a_ff(32,30)) + Cat(b_ff(34,0),0.U(2.W)) + Cat(b_ff(35,0),0.U) + b_ff
|
||||
quotient_raw := Cat((!adder7_out(36) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder7_out === 0.U)),
|
||||
(!adder6_out(36) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder6_out === 0.U)),
|
||||
(!adder5_out(36) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder5_out === 0.U)),
|
||||
(!adder4_out(36) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder4_out === 0.U)),
|
||||
(!adder3_out(35) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder3_out === 0.U)),
|
||||
(!adder2_out(34) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder2_out === 0.U)),
|
||||
(!adder1_out(33) ^ dividend_sign_ff) | ((a_ff(29,0) === 0.U) & (adder1_out === 0.U)), 0.U)
|
||||
quotient_new := Cat ((quotient_raw(7) | quotient_raw(6) | quotient_raw(5) | quotient_raw(4)),
|
||||
(quotient_raw(7) | quotient_raw(6) |(!quotient_raw(4) & quotient_raw(3)) |(!quotient_raw(3) & quotient_raw(2))),
|
||||
(quotient_raw(7) | (!quotient_raw(6) & quotient_raw(5)) | (!quotient_raw(4) & quotient_raw(3)) |(!quotient_raw(2) & quotient_raw(1))))
|
||||
val twos_comp_in = Mux1H(Seq (
|
||||
twos_comp_q_sel -> q_ff,
|
||||
twos_comp_b_sel -> b_ff(31,0)
|
||||
))
|
||||
val twos_comp_out = rvtwoscomp(twos_comp_in)
|
||||
val a_in = Mux1H(Seq (
|
||||
(!a_shift & !shortq_enable_ff).asBool -> Cat(io.signed_in & io.dividend_in(31),io.dividend_in(31,0)),
|
||||
a_shift -> Cat(a_ff(29,0),0.U(3.W)),
|
||||
shortq_enable_ff -> ar_shifted(32,0)
|
||||
))
|
||||
val b_in = Mux1H(Seq (
|
||||
!b_twos_comp -> Cat(io.signed_in & io.divisor_in(31),io.divisor_in(31,0)),
|
||||
b_twos_comp -> Cat(!divisor_sign_ff,twos_comp_out(31,0))
|
||||
))
|
||||
val r_in = Mux1H (Seq(
|
||||
r_sign_sel -> Fill(33,1.U),
|
||||
r_adder_sel(0) -> Cat(r_ff(29,0),a_ff(32,30)),
|
||||
r_adder_sel(1) -> adder1_out(32,0),
|
||||
r_adder_sel(2) -> adder2_out(32,0),
|
||||
r_adder_sel(3) -> adder3_out(32,0),
|
||||
r_adder_sel(4) -> adder4_out(32,0),
|
||||
r_adder_sel(5) -> adder5_out(32,0),
|
||||
r_adder_sel(6) -> adder6_out(32,0),
|
||||
r_adder_sel(7) -> adder7_out(32,0),
|
||||
shortq_enable_ff -> ar_shifted(65,33),
|
||||
by_zero_case -> Cat(0.U,a_ff(31,0))
|
||||
))
|
||||
val q_in = Mux1H (Seq(
|
||||
!valid_ff -> Cat(q_ff(28,0),quotient_new),
|
||||
smallnum_case -> Cat(0.U(28.W),smallnum),
|
||||
by_zero_case -> Fill(32,1.U)
|
||||
))
|
||||
io.valid_out := finish_ff & !io.cancel
|
||||
io.data_out := Mux1H(Seq(
|
||||
(!rem_ff & !twos_comp_q_sel).asBool() -> q_ff,
|
||||
rem_ff -> r_ff(31,0),
|
||||
twos_comp_q_sel -> twos_comp_out
|
||||
))
|
||||
def pat1(x : List[Int], y : List[Int]) = {
|
||||
val pat_a = (0 until x.size).map(i=> if(x(i)>=0) a_ff(x(i)) else !a_ff(x(i).abs)).reduce(_&_)
|
||||
val pat_b = (0 until y.size).map(i=> if(y(i)>=0) b_ff(y(i)) else !b_ff(y(i).abs)).reduce(_&_)
|
||||
pat_a & pat_b
|
||||
}
|
||||
smallnum := Cat(
|
||||
pat1(List(3),List(-3, -2, -1)),
|
||||
|
||||
pat1(List(3),List(-3, -2))& !b_ff(0) | pat1(List(2),List(-3, -2, -1)) | pat1(List(3, 2),List(-3, -2)),
|
||||
|
||||
pat1(List(2),List(-3, -2))& !b_ff(0) | pat1(List(1),List(-3, -2, -1)) | pat1(List(3),List(-3, -1))& !b_ff(0) |
|
||||
pat1(List(3, -2),List(-3, -2, 1, 0)) | pat1(List(-3, 2, 1),List(-3, -2)) | pat1(List(3, 2),List(-3))& !b_ff(0) |
|
||||
pat1(List(3, 2),List(-3, 2, -1)) | pat1(List(3, 1),List(-3,-1)) | pat1(List(3, 2, 1),List(-3, 2)),
|
||||
|
||||
pat1(List(2, 1, 0),List(-3, -1)) | pat1(List(3, -2, 0),List(-3, 1, 0)) | pat1(List(2),List(-3, -1))& !b_ff(0) |
|
||||
pat1(List(1),List(-3, -2))& !b_ff(0) | pat1(List(0),List(-3, -2, -1)) | pat1(List(-3, 2, -1),List(-3, -2, 1, 0)) |
|
||||
pat1(List(-3, 2, 1),List(-3))& !b_ff(0) | pat1(List(3),List(-2, -1)) & !b_ff(0) | pat1(List(3, -2),List(-3, 2, 1)) |
|
||||
pat1(List(-3, 2, 1),List(-3, 2, -1)) | pat1(List(-3, 2, 0),List(-3, -1)) | pat1(List(3, -2, -1),List(-3, 2, 0)) |
|
||||
pat1(List(-2, 1, 0),List(-3, -2)) | pat1(List(3, 2),List(-1)) & !b_ff(0) | pat1(List(-3, 2, 1, 0),List(-3, 2)) |
|
||||
pat1(List(3, 2),List(3, -2)) | pat1(List(3, 1),List(3,-2,-1)) | pat1(List(3, 0),List(-2, -1)) |
|
||||
pat1(List(3, -1),List(-3, 2, 1, 0)) | pat1(List(3, 2, 1),List(3)) & !b_ff(0) | pat1(List(3, 2, 1),List(3, -1)) |
|
||||
pat1(List(3, 2, 0),List(3, -1)) | pat1(List(3, -2, 1),List(-3, 1)) | pat1(List(3, 1, 0),List(-2)) |
|
||||
pat1(List(3, 2, 1, 0),List(3)) |pat1(List(3, 1),List(-2)) & !b_ff(0))
|
||||
|
||||
val shortq_dividend = Cat(dividend_sign_ff,a_ff(31,0))
|
||||
val a_enc = Module(new exu_div_cls)
|
||||
a_enc.io.operand := shortq_dividend
|
||||
val dw_a_enc1 = a_enc.io.cls
|
||||
val b_enc = Module(new exu_div_cls)
|
||||
b_enc.io.operand := b_ff(32,0)
|
||||
val dw_b_enc1 = b_enc.io.cls
|
||||
val dw_a_enc = Cat (0.U, dw_a_enc1)
|
||||
val dw_b_enc = Cat (0.U, dw_b_enc1)
|
||||
|
||||
val dw_shortq_raw = Cat(0.U,dw_b_enc) - Cat(0.U,dw_a_enc) + 1.U(7.W)
|
||||
val shortq = Mux(dw_shortq_raw(6).asBool(),0.U,dw_shortq_raw(5,0))
|
||||
shortq_enable := valid_ff & !shortq(5) & !(shortq(4,2) === "b111".U) & !io.cancel
|
||||
val list = Array(27,27,27,27,27,27,24,24,24,21,21,21,18,18,18,15,15,15,12,12,12,9,9,9,6,6,6,3,0,0,0,0)
|
||||
shortq_decode := Mux1H((31 to 0 by -1).map(i=> (shortq === i.U) -> list(i).U))
|
||||
shortq_shift := Mux(!shortq_enable,0.U,shortq_decode)
|
||||
b_ff := Cat(b_ff1(32),b_ff1(32),b_ff1(32),b_ff1(32),b_ff1)
|
||||
valid_ff := rvdffe(valid_ff_in, misc_enable,clock,io.scan_mode)
|
||||
control_ff := rvdffe(control_in, misc_enable,clock,io.scan_mode)
|
||||
by_zero_case_ff := rvdffe(by_zero_case,misc_enable,clock,io.scan_mode)
|
||||
shortq_enable_ff := rvdffe(shortq_enable, misc_enable,clock,io.scan_mode)
|
||||
shortq_shift_ff := rvdffe(shortq_shift, misc_enable,clock,io.scan_mode)
|
||||
finish_ff := rvdffe(finish, misc_enable,clock,io.scan_mode)
|
||||
count_ff := rvdffe(count_in, misc_enable,clock,io.scan_mode)
|
||||
|
||||
a_ff := rvdffe(a_in, a_enable,clock,io.scan_mode)
|
||||
b_ff1 := rvdffe(b_in(32,0), b_enable,clock,io.scan_mode)
|
||||
r_ff := rvdffe(r_in, rq_enable,clock,io.scan_mode)
|
||||
q_ff := rvdffe(q_in, rq_enable,clock,io.scan_mode)
|
||||
|
||||
}
|
||||
/////////////////////////////////////////////// 4 BIT FULL DIVIDER//////////////////////////////////
|
||||
class exu_div_new_4bit_fullshortq extends Module with RequireAsyncReset with lib {
|
||||
val io = IO(new Bundle {
|
||||
val scan_mode = Input(Bool())
|
||||
val cancel = Input(Bool())
|
||||
val valid_in = Input(Bool())
|
||||
val signed_in = Input(Bool())
|
||||
val rem_in = Input(Bool())
|
||||
val dividend_in = Input(UInt(32.W))
|
||||
val divisor_in = Input(UInt(32.W))
|
||||
val data_out = Output(UInt(32.W))
|
||||
val valid_out = Output(UInt(1.W))
|
||||
})
|
||||
|
||||
val valid_ff = WireInit(Bool(),init=false.B)
|
||||
val finish_ff = WireInit(Bool(),init=false.B)
|
||||
val control_ff = WireInit(0.U(3.W))
|
||||
val count_ff = WireInit(0.U(7.W))
|
||||
val smallnum = WireInit(0.U(4.W))
|
||||
val a_ff = WireInit(0.U(32.W))
|
||||
val b_ff1 = WireInit(0.U(33.W))
|
||||
val b_ff = WireInit(0.U(38.W))
|
||||
val q_ff = WireInit(0.U(32.W))
|
||||
val r_ff = WireInit(0.U(33.W))
|
||||
val quotient_raw = WireInit(0.U(16.W))
|
||||
val quotient_new = WireInit(0.U(4.W))
|
||||
val shortq_enable = WireInit(Bool(),init=false.B)
|
||||
val shortq_enable_ff = WireInit(Bool(),init=false.B)
|
||||
val by_zero_case_ff = WireInit(Bool(),init=false.B)
|
||||
val ar_shifted = WireInit(0.U(65.W))
|
||||
val shortq_shift = WireInit(0.U(5.W))
|
||||
val shortq_decode = WireInit(0.U(5.W))
|
||||
val shortq_shift_ff = WireInit(0.U(5.W))
|
||||
val valid_ff_in = io.valid_in & !io.cancel
|
||||
val control_in = Cat((!io.valid_in & control_ff(2)) | (io.valid_in & io.signed_in & io.dividend_in(31)), (!io.valid_in & control_ff(1)) | (io.valid_in & io.signed_in & io.divisor_in(31)), (!io.valid_in & control_ff(0)) | (io.valid_in & io.rem_in))
|
||||
val dividend_sign_ff = control_ff(2)
|
||||
val divisor_sign_ff = control_ff(1)
|
||||
val rem_ff = control_ff(0)
|
||||
val by_zero_case = valid_ff & (b_ff(31,0) === 0.U)
|
||||
|
||||
val smallnum_case = ((a_ff(31,4) === 0.U) & (b_ff(31,4) === 0.U) & !by_zero_case & !rem_ff & valid_ff & !io.cancel) |
|
||||
((a_ff(31,0) === 0.U) & !by_zero_case & !rem_ff & valid_ff & !io.cancel)
|
||||
val running_state = count_ff.orR() | shortq_enable_ff
|
||||
val misc_enable = io.valid_in | valid_ff | io.cancel | running_state | finish_ff
|
||||
val finish_raw = smallnum_case | by_zero_case | (count_ff === 32.U)
|
||||
val finish = finish_raw & !io.cancel
|
||||
val count_enable = (valid_ff | running_state) & !finish & !finish_ff & !io.cancel & !shortq_enable
|
||||
val count_in = Fill(7,count_enable) & (count_ff + 4.U(7.W) + Cat(0.U(2.W),shortq_shift_ff))
|
||||
val a_enable = io.valid_in | running_state
|
||||
val a_shift = running_state & !shortq_enable_ff
|
||||
ar_shifted := Cat (Fill(33,dividend_sign_ff),a_ff(31,0)) << shortq_shift_ff
|
||||
val b_twos_comp = valid_ff & !(dividend_sign_ff ^ divisor_sign_ff)
|
||||
val twos_comp_b_sel = valid_ff & !(dividend_sign_ff ^ divisor_sign_ff)
|
||||
val twos_comp_q_sel = !valid_ff & !rem_ff & (dividend_sign_ff ^ divisor_sign_ff) & !by_zero_case_ff
|
||||
val b_enable = io.valid_in | b_twos_comp
|
||||
val rq_enable = io.valid_in | valid_ff | running_state
|
||||
val r_sign_sel = valid_ff & dividend_sign_ff & !by_zero_case
|
||||
val r_adder_sel = (0 to 15 ).map(i=> (running_state & (quotient_new === i.asUInt) & !shortq_enable_ff))
|
||||
val adder1_out = Cat(r_ff(30,0),a_ff(31,28)) + b_ff(34,0)
|
||||
val adder2_out = Cat(r_ff(31,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U)
|
||||
val adder3_out = Cat(r_ff(32,0),a_ff(31,28)) + Cat(b_ff(35,0),0.U) + b_ff(36,0)
|
||||
val adder4_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(35,0),0.U(2.W))
|
||||
val adder5_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(35,0),0.U(2.W)) + b_ff
|
||||
val adder6_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(35,0),0.U(2.W)) + Cat(b_ff(36,0),0.U)
|
||||
val adder7_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(35,0),0.U(2.W)) + Cat(b_ff(36,0),0.U) + b_ff
|
||||
val adder8_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U(3.W))
|
||||
val adder9_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U(3.W)) + b_ff
|
||||
val adder10_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U(3.W)) + Cat(b_ff(36,0),0.U)
|
||||
val adder11_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U(3.W)) + Cat(b_ff(36,0),0.U) + b_ff
|
||||
val adder12_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U(3.W)) + Cat(b_ff(35,0),0.U(2.W))
|
||||
val adder13_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U(3.W)) + Cat(b_ff(35,0),0.U(2.W)) + b_ff
|
||||
val adder14_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U(3.W)) + Cat(b_ff(35,0),0.U(2.W)) + Cat(b_ff(36,0),0.U)
|
||||
val adder15_out = Cat(r_ff(32),r_ff(32,0),a_ff(31,28)) + Cat(b_ff(34,0),0.U(3.W)) + Cat(b_ff(35,0),0.U(2.W)) + Cat(b_ff(36,0),0.U) + b_ff
|
||||
|
||||
quotient_raw := Cat(
|
||||
(!adder15_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder15_out === 0.U)),
|
||||
(!adder14_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder14_out === 0.U)),
|
||||
(!adder13_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder13_out === 0.U)),
|
||||
(!adder12_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder12_out === 0.U)),
|
||||
(!adder11_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder11_out === 0.U)),
|
||||
(!adder10_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder10_out === 0.U)),
|
||||
(!adder9_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder9_out === 0.U)),
|
||||
(!adder8_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder8_out === 0.U)),
|
||||
(!adder7_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder7_out === 0.U)),
|
||||
(!adder6_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder6_out === 0.U)),
|
||||
(!adder5_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder5_out === 0.U)),
|
||||
(!adder4_out(37) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder4_out === 0.U)),
|
||||
(!adder3_out(36) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder3_out === 0.U)),
|
||||
(!adder2_out(35) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder2_out === 0.U)),
|
||||
(!adder1_out(34) ^ dividend_sign_ff) | ((a_ff(27,0) === 0.U) & (adder1_out === 0.U)), 0.U)
|
||||
|
||||
quotient_new := Cat(
|
||||
(Mux1H((8 to 14).map(i=> (quotient_raw(15,i)=== Cat(Fill(15-i,0.U),1.U)).asBool -> 1.U)) | (quotient_raw(15)===1.U)),
|
||||
Mux1H (Seq(( quotient_raw(15,4) === "b000000000001".U(12.W)) -> 1.U, ( quotient_raw(15,5) === "b00000000001".U(11.W)) -> 1.U, ( quotient_raw(15,6) === "b0000000001".U(10.W)) -> 1.U, ( quotient_raw(15,7) === "b000000001".U(9.W)) -> 1.U,
|
||||
( quotient_raw(15,12)=== "b0001".U(4.W)) -> 1.U, ( quotient_raw(15,13)=== "b001".U(3.W)) -> 1.U, ( quotient_raw(15,14)=== "b01".U(2.W)) -> 1.U, ( quotient_raw(15) === "b1".U) -> 1.U)),
|
||||
Mux1H(Seq(( quotient_raw(15,2) === "b00000000000001".U(14.W)) -> 1.U, ( quotient_raw(15,3) === "b0000000000001".U(13.W)) -> 1.U, ( quotient_raw(15,6) === "b0000000001".U(10.W)) -> 1.U, ( quotient_raw(15,7) === "b000000001".U(9.W)) -> 1.U,
|
||||
( quotient_raw(15,10)=== "b000001".U(6.W)) -> 1.U, ( quotient_raw(15,11)=== "b00001".U(5.W)) -> 1.U, ( quotient_raw(15,14)=== "b01".U(2.W)) -> 1.U, ( quotient_raw(15) === "b1".U) -> 1.U)),
|
||||
(Mux1H((1 to 13 by 2).map(i=> (quotient_raw(15,i)=== Cat(Fill(15-i,0.U),1.U)).asBool -> 1.U)) | (quotient_raw(15)===1.U) ))
|
||||
val twos_comp_in = Mux1H(Seq (
|
||||
twos_comp_q_sel -> q_ff,
|
||||
twos_comp_b_sel -> b_ff(31,0)
|
||||
))
|
||||
val twos_comp_out = rvtwoscomp(twos_comp_in)
|
||||
val a_in = Mux1H(Seq (
|
||||
(!a_shift & !shortq_enable_ff).asBool -> io.dividend_in(31,0),
|
||||
a_shift -> Cat(a_ff(27,0),0.U(4.W)),
|
||||
shortq_enable_ff -> ar_shifted(31,0)
|
||||
))
|
||||
val b_in = Mux1H(Seq (
|
||||
!b_twos_comp -> Cat(io.signed_in & io.divisor_in(31),io.divisor_in(31,0)),
|
||||
b_twos_comp -> Cat(!divisor_sign_ff,twos_comp_out(31,0))
|
||||
))
|
||||
val r_in = Mux1H (Seq(
|
||||
r_sign_sel -> Fill(33,1.U),
|
||||
r_adder_sel(0) -> Cat(r_ff(28,0),a_ff(31,28)),
|
||||
r_adder_sel(1) -> adder1_out(32,0),
|
||||
r_adder_sel(2) -> adder2_out(32,0),
|
||||
r_adder_sel(3) -> adder3_out(32,0),
|
||||
r_adder_sel(4) -> adder4_out(32,0),
|
||||
r_adder_sel(5) -> adder5_out(32,0),
|
||||
r_adder_sel(6) -> adder6_out(32,0),
|
||||
r_adder_sel(7) -> adder7_out(32,0),
|
||||
r_adder_sel(8) -> adder8_out(32,0),
|
||||
r_adder_sel(9) -> adder9_out(32,0),
|
||||
r_adder_sel(10) -> adder10_out(32,0),
|
||||
r_adder_sel(11) -> adder11_out(32,0),
|
||||
r_adder_sel(12) -> adder12_out(32,0),
|
||||
r_adder_sel(13) -> adder13_out(32,0),
|
||||
r_adder_sel(14) -> adder14_out(32,0),
|
||||
r_adder_sel(15) -> adder15_out(32,0),
|
||||
shortq_enable_ff -> ar_shifted(64,32),
|
||||
by_zero_case -> Cat(0.U,a_ff(31,0))
|
||||
))
|
||||
val q_in = Mux1H (Seq(
|
||||
!valid_ff -> Cat(q_ff(27,0),quotient_new),
|
||||
smallnum_case -> Cat(0.U(28.W),smallnum),
|
||||
by_zero_case -> Fill(32,1.U)
|
||||
))
|
||||
io.valid_out := finish_ff & !io.cancel
|
||||
io.data_out := Mux1H(Seq(
|
||||
(!rem_ff & !twos_comp_q_sel).asBool() -> q_ff,
|
||||
rem_ff -> r_ff(31,0),
|
||||
twos_comp_q_sel -> twos_comp_out
|
||||
))
|
||||
def pat1(x : List[Int], y : List[Int]) = {
|
||||
val pat_a = (0 until x.size).map(i=> if(x(i)>=0) a_ff(x(i)) else !a_ff(x(i).abs)).reduce(_&_)
|
||||
val pat_b = (0 until y.size).map(i=> if(y(i)>=0) b_ff(y(i)) else !b_ff(y(i).abs)).reduce(_&_)
|
||||
pat_a & pat_b
|
||||
}
|
||||
smallnum := Cat(
|
||||
pat1(List(3),List(-3, -2, -1)),
|
||||
|
||||
pat1(List(3),List(-3, -2))& !b_ff(0) | pat1(List(2),List(-3, -2, -1)) | pat1(List(3, 2),List(-3, -2)),
|
||||
|
||||
pat1(List(2),List(-3, -2))& !b_ff(0) | pat1(List(1),List(-3, -2, -1)) | pat1(List(3),List(-3, -1))& !b_ff(0) |
|
||||
pat1(List(3, -2),List(-3, -2, 1, 0)) | pat1(List(-3, 2, 1),List(-3, -2)) | pat1(List(3, 2),List(-3))& !b_ff(0) |
|
||||
pat1(List(3, 2),List(-3, 2, -1)) | pat1(List(3, 1),List(-3,-1)) | pat1(List(3, 2, 1),List(-3, 2)),
|
||||
|
||||
pat1(List(2, 1, 0),List(-3, -1)) | pat1(List(3, -2, 0),List(-3, 1, 0)) | pat1(List(2),List(-3, -1))& !b_ff(0) |
|
||||
pat1(List(1),List(-3, -2))& !b_ff(0) | pat1(List(0),List(-3, -2, -1)) | pat1(List(-3, 2, -1),List(-3, -2, 1, 0)) |
|
||||
pat1(List(-3, 2, 1),List(-3))& !b_ff(0) | pat1(List(3),List(-2, -1)) & !b_ff(0) | pat1(List(3, -2),List(-3, 2, 1)) |
|
||||
pat1(List(-3, 2, 1),List(-3, 2, -1)) | pat1(List(-3, 2, 0),List(-3, -1)) | pat1(List(3, -2, -1),List(-3, 2, 0)) |
|
||||
pat1(List(-2, 1, 0),List(-3, -2)) | pat1(List(3, 2),List(-1)) & !b_ff(0) | pat1(List(-3, 2, 1, 0),List(-3, 2)) |
|
||||
pat1(List(3, 2),List(3, -2)) | pat1(List(3, 1),List(3,-2,-1)) | pat1(List(3, 0),List(-2, -1)) |
|
||||
pat1(List(3, -1),List(-3, 2, 1, 0)) | pat1(List(3, 2, 1),List(3)) & !b_ff(0) | pat1(List(3, 2, 1),List(3, -1)) |
|
||||
pat1(List(3, 2, 0),List(3, -1)) | pat1(List(3, -2, 1),List(-3, 1)) | pat1(List(3, 1, 0),List(-2)) |
|
||||
pat1(List(3, 2, 1, 0),List(3)) |pat1(List(3, 1),List(-2)) & !b_ff(0))
|
||||
|
||||
|
||||
val shortq_dividend = Cat(dividend_sign_ff,a_ff(31,0))
|
||||
val a_enc = Module(new exu_div_cls)
|
||||
a_enc.io.operand := shortq_dividend
|
||||
val dw_a_enc1 = a_enc.io.cls
|
||||
val b_enc = Module(new exu_div_cls)
|
||||
b_enc.io.operand := b_ff(32,0)
|
||||
val dw_b_enc1 = b_enc.io.cls
|
||||
val dw_a_enc = Cat (0.U, dw_a_enc1)
|
||||
val dw_b_enc = Cat (0.U, dw_b_enc1)
|
||||
val dw_shortq_raw = Cat(0.U,dw_b_enc) - Cat(0.U,dw_a_enc) + 1.U(7.W)
|
||||
val shortq = Mux(dw_shortq_raw(6).asBool(),0.U,dw_shortq_raw(5,0))
|
||||
shortq_enable := valid_ff & !shortq(5) & !(shortq(4,2) === "b111".U) & !io.cancel
|
||||
val list = Array(28,28,28,28,24,24,24,24,20,20,20,20,16,16,16,16,12,12,12,12,8,8,8,8,4,4,4,4,0,0,0,0)
|
||||
shortq_decode := Mux1H((31 to 0 by -1).map(i=> (shortq === i.U) -> list(i).U))
|
||||
shortq_shift := Mux(!shortq_enable,0.U,shortq_decode)
|
||||
b_ff := Cat(b_ff1(32),b_ff1(32),b_ff1(32),b_ff1(32),b_ff1(32),b_ff1)
|
||||
valid_ff := rvdffe(valid_ff_in, misc_enable,clock,io.scan_mode)
|
||||
control_ff := rvdffe(control_in, misc_enable,clock,io.scan_mode)
|
||||
by_zero_case_ff := rvdffe(by_zero_case,misc_enable,clock,io.scan_mode)
|
||||
shortq_enable_ff := rvdffe(shortq_enable, misc_enable,clock,io.scan_mode)
|
||||
shortq_shift_ff := rvdffe(shortq_shift, misc_enable,clock,io.scan_mode)
|
||||
finish_ff := rvdffe(finish, misc_enable,clock,io.scan_mode)
|
||||
count_ff := rvdffe(count_in, misc_enable,clock,io.scan_mode)
|
||||
|
||||
a_ff := rvdffe(a_in, a_enable,clock,io.scan_mode)
|
||||
b_ff1 := rvdffe(b_in(32,0), b_enable,clock,io.scan_mode)
|
||||
r_ff := rvdffe(r_in, rq_enable,clock,io.scan_mode)
|
||||
q_ff := rvdffe(q_in, rq_enable,clock,io.scan_mode)
|
||||
|
||||
}
|
||||
class exu_div_cls extends Module{
|
||||
val io= IO(new Bundle{
|
||||
val operand = Input(UInt(33.W))
|
||||
val cls = Output(UInt(5.W))
|
||||
})
|
||||
val cls_zeros = WireInit(0.U(5.W))
|
||||
val cls_ones = WireInit(0.U(5.W))
|
||||
|
||||
cls_zeros := Mux1H((0 until 32).map(i=> (io.operand(31,31-i)===1.U)->i.U))
|
||||
|
||||
when(io.operand(31,0) === "hffffffff".U) { cls_ones := 31.U}
|
||||
.otherwise{cls_ones := Mux1H((1 until 32).map(i=> (io.operand(31,31-i) === Cat(Fill(i,1.U),0.U)).asBool -> (i-1).U ))}
|
||||
io.cls := Mux(io.operand(32),cls_ones,cls_zeros)
|
||||
}
|
||||
q_ff := rvdffe(q_in, qff_enable.asBool,clock,io.scan_mode)
|
||||
a_ff := rvdffe(a_in, aff_enable.asBool,clock,io.scan_mode)
|
||||
m_ff := rvdffe(Cat(!io.dec_div.div_p.bits.unsign & io.divisor(31), io.divisor), io.dec_div.div_p.valid.asBool,clock,io.scan_mode)
|
||||
}
|
|
@ -4,7 +4,7 @@ import chisel3._
|
|||
import chisel3.util._
|
||||
import include._
|
||||
import lib._
|
||||
import chisel3.stage.ChiselStage
|
||||
|
||||
|
||||
class exu_mul_ctl extends Module with RequireAsyncReset with lib {
|
||||
val io = IO(new Bundle{
|
||||
|
@ -22,104 +22,7 @@ class exu_mul_ctl extends Module with RequireAsyncReset with lib {
|
|||
val prod_x = WireInit(SInt(66.W), 0.S)
|
||||
val low_x = WireInit(0.U(1.W))
|
||||
|
||||
// *** Start - BitManip ***
|
||||
|
||||
// val bitmanip_sel_d = WireInit(Bool(),0.B)
|
||||
// val bitmanip_sel_x = WireInit(Bool(),0.B)
|
||||
// val bitmanip_d = WireInit(UInt(32.W),0.U)
|
||||
// val bitmanip_x = WireInit(UInt(32.W),0.U)
|
||||
|
||||
|
||||
|
||||
// ZBE
|
||||
val ap_bext = WireInit(Bool(),0.B)
|
||||
val ap_bdep = WireInit(Bool(),0.B)
|
||||
|
||||
// ZBC
|
||||
val ap_clmul = WireInit(Bool(),0.B)
|
||||
val ap_clmulh = WireInit(Bool(),0.B)
|
||||
val ap_clmulr = WireInit(Bool(),0.B)
|
||||
|
||||
// ZBP
|
||||
val ap_grev = WireInit(Bool(),0.B)
|
||||
val ap_gorc = WireInit(Bool(),0.B)
|
||||
val ap_shfl = WireInit(Bool(),0.B)
|
||||
val ap_unshfl = WireInit(Bool(),0.B)
|
||||
|
||||
// ZBR
|
||||
val ap_crc32_b = WireInit(Bool(),0.B)
|
||||
val ap_crc32_h = WireInit(Bool(),0.B)
|
||||
val ap_crc32_w = WireInit(Bool(),0.B)
|
||||
val ap_crc32c_b = WireInit(Bool(),0.B)
|
||||
val ap_crc32c_h = WireInit(Bool(),0.B)
|
||||
val ap_crc32c_w = WireInit(Bool(),0.B)
|
||||
|
||||
// ZBF
|
||||
val ap_bfp = WireInit(Bool(),0.B)
|
||||
|
||||
|
||||
if (BITMANIP_ZBE == 1) {
|
||||
ap_bext := io.mul_p.bits.bext
|
||||
ap_bdep := io.mul_p.bits.bdep
|
||||
|
||||
}
|
||||
else{
|
||||
ap_bext := 0.U
|
||||
ap_bdep := 0.U
|
||||
}
|
||||
|
||||
if (BITMANIP_ZBC == 1) {
|
||||
ap_clmul := io.mul_p.bits.clmul
|
||||
ap_clmulh := io.mul_p.bits.clmulh
|
||||
ap_clmulr := io.mul_p.bits.clmulr
|
||||
}
|
||||
else{
|
||||
ap_clmul := 0.U
|
||||
ap_clmulh := 0.U
|
||||
ap_clmulr := 0.U
|
||||
}
|
||||
|
||||
if (BITMANIP_ZBP == 1) {
|
||||
ap_grev := io.mul_p.bits.grev
|
||||
ap_gorc := io.mul_p.bits.gorc
|
||||
ap_shfl := io.mul_p.bits.shfl
|
||||
ap_unshfl := io.mul_p.bits.unshfl
|
||||
}
|
||||
else{
|
||||
ap_grev := 0.U
|
||||
ap_gorc := 0.U
|
||||
ap_shfl := 0.U
|
||||
ap_unshfl := 0.U
|
||||
}
|
||||
|
||||
if (BITMANIP_ZBR == 1) {
|
||||
ap_crc32_b := io.mul_p.bits.crc32_b
|
||||
ap_crc32_h := io.mul_p.bits.crc32_h
|
||||
ap_crc32_w := io.mul_p.bits.crc32_w
|
||||
ap_crc32c_b := io.mul_p.bits.crc32c_b
|
||||
ap_crc32c_h := io.mul_p.bits.crc32c_h
|
||||
ap_crc32c_w := io.mul_p.bits.crc32c_w
|
||||
}
|
||||
else{
|
||||
ap_crc32_b := 0.U
|
||||
ap_crc32_h := 0.U
|
||||
ap_crc32_w := 0.U
|
||||
ap_crc32c_b := 0.U
|
||||
ap_crc32c_h := 0.U
|
||||
ap_crc32c_w := 0.U
|
||||
}
|
||||
|
||||
if (BITMANIP_ZBF == 1) {
|
||||
ap_bfp := io.mul_p.bits.bfp
|
||||
}
|
||||
else{
|
||||
ap_bfp := 0.U
|
||||
}
|
||||
|
||||
// *** End - BitManip ***
|
||||
|
||||
val mul_x_enable = io.mul_p.valid
|
||||
val bit_x_enable = io.mul_p.valid
|
||||
rs1_ext_in := Cat(io.mul_p.bits.rs1_sign & io.rs1_in(31),io.rs1_in).asSInt
|
||||
rs2_ext_in := Cat(io.mul_p.bits.rs2_sign & io.rs2_in(31),io.rs2_in).asSInt
|
||||
|
||||
|
@ -128,269 +31,5 @@ class exu_mul_ctl extends Module with RequireAsyncReset with lib {
|
|||
rs2_x := rvdffe (rs2_ext_in, mul_x_enable.asBool,clock,io.scan_mode)
|
||||
|
||||
prod_x := rs1_x * rs2_x
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : BEXT, BDEP * * * * * * * * * * * * * * * * * *
|
||||
|
||||
|
||||
// *** BEXT == "gather" ***
|
||||
|
||||
def one_cal (ind:Int) : UInt = if (ind == 0) io.rs2_in(ind) else (0 to ind).map(io.rs2_in(_).asUInt).reduce(_+&_)
|
||||
val bext_d = (0 until 32).map(i=> MuxCase(false.B, (0 until 32).map(j=> (one_cal(j) === (i+1).U).asBool -> io.rs1_in(j).asUInt))).reverse.reduce(Cat(_,_))
|
||||
|
||||
// *** BDEP == "scatter" ***
|
||||
val bdep_d =(0 until 32).map(j => Mux((io.rs2_in(j) === 1.U), io.rs1_in(one_cal(j)-1.U),0.U)).reverse.reduce(Cat(_,_))
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : CLMUL, CLMULH, CLMULR * * * * * * * * * * * * *
|
||||
|
||||
val clmul_raw_d = WireInit(UInt(63.W),0.U)
|
||||
clmul_raw_d := (1 until 31).map(i => Fill(63,io.rs2_in(i)) & Cat(Fill(31-i,0.U),io.rs1_in(31,0),Fill(i,0.U))).reduce(_^_) ^ ( Fill(63,io.rs2_in(0)) & Cat(Fill(31,0.U),io.rs1_in) ) ^ ( Fill(63,io.rs2_in(31)) & Cat(io.rs1_in,Fill(31,0.U)) )
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : GREV * * * * * * * * * * * * * * * * * *
|
||||
|
||||
// uint32_t grev32(uint32_t rs1, uint32_t rs2)
|
||||
// {
|
||||
// uint32_t x = rs1;
|
||||
// int shamt = rs2 & 31;
|
||||
//
|
||||
// if (shamt & 1) x = ( (x & 0x55555555) << 1) | ( (x & 0xAAAAAAAA) >> 1);
|
||||
// if (shamt & 2) x = ( (x & 0x33333333) << 2) | ( (x & 0xCCCCCCCC) >> 2);
|
||||
// if (shamt & 4) x = ( (x & 0x0F0F0F0F) << 4) | ( (x & 0xF0F0F0F0) >> 4);
|
||||
// if (shamt & 8) x = ( (x & 0x00FF00FF) << 8) | ( (x & 0xFF00FF00) >> 8);
|
||||
// if (shamt & 16) x = ( (x & 0x0000FFFF) << 16) | ( (x & 0xFFFF0000) >> 16);
|
||||
//
|
||||
// return x;
|
||||
// }
|
||||
|
||||
|
||||
val grev1_d = Mux(io.rs2_in(0), Range(0, 31, 2).map(i=> Cat(io.rs1_in(i),io.rs1_in(i+1))).reverse.reduce(Cat(_,_)), io.rs1_in)
|
||||
|
||||
val grev2_d = Mux(io.rs2_in(1), Range(0, 31, 4).map(i=> Cat(grev1_d(i+1,i),grev1_d(i+1+2,i+2))).reverse.reduce(Cat(_,_)) , grev1_d(31,0))
|
||||
|
||||
val grev4_d = Mux(io.rs2_in(2), Range(0, 31, 8).map(i=> Cat(grev2_d(i+3,i),grev2_d(i+3+4,i+4))).reverse.reduce(Cat(_,_)) , grev2_d(31,0))
|
||||
|
||||
val grev8_d = Mux(io.rs2_in(3), Range(0, 31, 16).map(i=> Cat(grev4_d(i+7,i),grev4_d(i+7+8,i+8))).reverse.reduce(Cat(_,_)), grev4_d(31,0))
|
||||
|
||||
val grev_d = Mux(io.rs2_in(4), Cat(grev8_d(15,0),grev8_d(31,16)), grev8_d(31,0) )
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : GORC * * * * * * * * * * * * * * * * * *
|
||||
|
||||
// uint32_t gorc32(uint32_t rs1, uint32_t rs2)
|
||||
// {
|
||||
// uint32_t x = rs1;
|
||||
// int shamt = rs2 & 31;
|
||||
//
|
||||
// if (shamt & 1) x |= ( (x & 0x55555555) << 1) | ( (x & 0xAAAAAAAA) >> 1);
|
||||
// if (shamt & 2) x |= ( (x & 0x33333333) << 2) | ( (x & 0xCCCCCCCC) >> 2);
|
||||
// if (shamt & 4) x |= ( (x & 0x0F0F0F0F) << 4) | ( (x & 0xF0F0F0F0) >> 4);
|
||||
// if (shamt & 8) x |= ( (x & 0x00FF00FF) << 8) | ( (x & 0xFF00FF00) >> 8);
|
||||
// if (shamt & 16) x |= ( (x & 0x0000FFFF) << 16) | ( (x & 0xFFFF0000) >> 16);
|
||||
//
|
||||
// return x;
|
||||
// }
|
||||
|
||||
|
||||
// logic [31:0] gorc1_d;
|
||||
// logic [31:0] gorc2_d;
|
||||
// logic [31:0] gorc4_d;
|
||||
// logic [31:0] gorc8_d;
|
||||
// logic [31:0] gorc_d;
|
||||
//
|
||||
|
||||
val gorc1_d = ( Fill(32,io.rs2_in(0)) & Range(0, 31, 2).map(i=> Cat(io.rs1_in(i),io.rs1_in(i+1))).reverse.reduce(Cat(_,_)) ) | io.rs1_in
|
||||
|
||||
val gorc2_d = ( Fill(32,io.rs2_in(1)) & Range(0, 31, 4).map(i=> Cat(gorc1_d(i+1,i),gorc1_d(i+1+2,i+2))).reverse.reduce(Cat(_,_)) ) | gorc1_d
|
||||
|
||||
val gorc4_d = ( Fill(32,io.rs2_in(2)) & Range(0, 31, 8).map(i=> Cat(gorc2_d(i+3,i),gorc2_d(i+3+4,i+4))).reverse.reduce(Cat(_,_)) ) | gorc2_d
|
||||
|
||||
val gorc8_d = ( Fill(32,io.rs2_in(3)) & Range(0, 31, 16).map(i=> Cat(gorc4_d(i+7,i),gorc4_d(i+7+8,i+8))).reverse.reduce(Cat(_,_)) ) | gorc4_d
|
||||
|
||||
val gorc_d = ( Fill(32,io.rs2_in(4)) & Cat(gorc8_d(15,0),gorc8_d(31,16)) ) | gorc8_d
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : SHFL, UNSHLF * * * * * * * * * * * * * * * * * *
|
||||
|
||||
// uint32_t shuffle32_stage (uint32_t src, uint32_t maskL, uint32_t maskR, int N)
|
||||
// {
|
||||
// uint32_t x = src & ~(maskL | maskR);
|
||||
// x |= ((src << N) & maskL) | ((src >> N) & maskR);
|
||||
// return x;
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// uint32_t shfl32(uint32_t rs1, uint32_t rs2)
|
||||
// {
|
||||
// uint32_t x = rs1;
|
||||
// int shamt = rs2 & 15
|
||||
//
|
||||
// if (shamt & 8) x = shuffle32_stage(x, 0x00ff0000, 0x0000ff00, 8);
|
||||
// if (shamt & 4) x = shuffle32_stage(x, 0x0f000f00, 0x00f000f0, 4);
|
||||
// if (shamt & 2) x = shuffle32_stage(x, 0x30303030, 0xc0c0c0c0, 2);
|
||||
// if (shamt & 1) x = shuffle32_stage(x, 0x44444444, 0x22222222, 1);
|
||||
//
|
||||
// return x;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
val shfl8_d = Mux(io.rs2_in(3),Range(0, 9,8).map(i=> Cat(io.rs1_in(i+7+16,i+16),io.rs1_in(i+7,i))).reverse.reduce(Cat(_,_)) ,io.rs1_in)
|
||||
|
||||
val shfl4_d = Mux(io.rs2_in(2),Range(0, 13,4).map(i=> if(i<8) Cat(shfl8_d(i+3+8,i+8),shfl8_d(i+3,i))else Cat(shfl8_d(i+3+8+8,i+8+8),shfl8_d(i+3+8,i+8))).reverse.reduce(Cat(_,_)), shfl8_d)
|
||||
|
||||
val shfl2_d = Mux(io.rs2_in(1), Range(0, 15,2).map(i=> if(i<4)Cat(shfl4_d(i+1+4,i+4),shfl4_d(i+1,i))else if(i<8)Cat(shfl4_d(i+9,i+8),shfl4_d(i+5,i+4))else if(i<12)Cat(shfl4_d(i+13,i+12),shfl4_d(i+9,i+8))else Cat(shfl4_d(i+17,i+16),shfl4_d(i+13,i+12))).reverse.reduce(Cat(_,_)), shfl4_d)
|
||||
|
||||
val shfl_d = Mux(io.rs2_in(0), Range(0, 16,1).map(i=> if(i<2) Cat(shfl2_d(i+2),shfl2_d(i))else if(i<4) Cat(shfl2_d(i+4),shfl2_d(i+2))else if(i<6) Cat(shfl2_d(i+6),shfl2_d(i+4))else if(i<8) Cat(shfl2_d(i+8),shfl2_d(i+6))else if(i<10) Cat(shfl2_d(i+10),shfl2_d(i+8))else if(i<12) Cat(shfl2_d(i+12),shfl2_d(i+10))else if(i<14) Cat(shfl2_d(i+14),shfl2_d(i+12))else Cat(shfl2_d(i+16),shfl2_d(i+14))).reverse.reduce(Cat(_,_)), shfl2_d)
|
||||
|
||||
|
||||
|
||||
|
||||
// // uint32_t unshfl32(uint32_t rs1, uint32_t rs2)
|
||||
// // {
|
||||
// // uint32_t x = rs1;
|
||||
// // int shamt = rs2 & 15
|
||||
// //
|
||||
// // if (shamt & 1) x = shuffle32_stage(x, 0x44444444, 0x22222222, 1);
|
||||
// // if (shamt & 2) x = shuffle32_stage(x, 0x30303030, 0xc0c0c0c0, 2);
|
||||
// // if (shamt & 4) x = shuffle32_stage(x, 0x0f000f00, 0x00f000f0, 4);
|
||||
// // if (shamt & 8) x = shuffle32_stage(x, 0x00ff0000, 0x0000ff00, 8);
|
||||
// //
|
||||
// // return x;
|
||||
// // }
|
||||
//
|
||||
//
|
||||
val unshfl1_d = Mux(io.rs2_in(0) , Range(0, 16,1).map(i=> if(i<2) Cat(io.rs1_in(i+2),io.rs1_in(i))else if(i<4) Cat(io.rs1_in(i+4),io.rs1_in(i+2))else if(i<6) Cat(io.rs1_in(i+6),io.rs1_in(i+4))else if(i<8) Cat(io.rs1_in(i+8),io.rs1_in(i+6))else if(i<10) Cat(io.rs1_in(i+10),io.rs1_in(i+8))else if(i<12) Cat(io.rs1_in(i+12),io.rs1_in(i+10))else if(i<14) Cat(io.rs1_in(i+14),io.rs1_in(i+12))else Cat(io.rs1_in(i+16),io.rs1_in(i+14))).reverse.reduce(Cat(_,_)) , io.rs1_in)
|
||||
|
||||
val unshfl2_d =Mux(io.rs2_in(1) , Range(0, 15,2).map(i=> if(i<4)Cat(unshfl1_d(i+1+4,i+4),unshfl1_d(i+1,i))else if(i<8)Cat(unshfl1_d(i+9,i+8),unshfl1_d(i+5,i+4))else if(i<12)Cat(unshfl1_d(i+13,i+12),unshfl1_d(i+9,i+8))else Cat(unshfl1_d(i+17,i+16),unshfl1_d(i+13,i+12))).reverse.reduce(Cat(_,_)) , unshfl1_d)
|
||||
|
||||
val unshfl4_d = Mux(io.rs2_in(2) , Range(0, 13,4).map(i=> if(i<8) Cat(unshfl2_d(i+3+8,i+8),unshfl2_d(i+3,i))else Cat(unshfl2_d(i+3+8+8,i+8+8),unshfl2_d(i+3+8,i+8))).reverse.reduce(Cat(_,_)) , unshfl2_d)
|
||||
|
||||
val unshfl_d = Mux(io.rs2_in(3) , Range(0, 9,8).map(i=> Cat(unshfl4_d(i+7+16,i+16),unshfl4_d(i+7,i))).reverse.reduce(Cat(_,_)) , unshfl4_d)
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : BFP * * * * * * * * * * * * * * * * * *
|
||||
|
||||
|
||||
|
||||
val bfp_len = Cat(io.rs2_in(27,24) === 0.U,io.rs2_in(27,24)) // If LEN field is zero, then LEN=16
|
||||
val bfp_off = io.rs2_in(20,16)
|
||||
|
||||
val bfp_len_mask_ = "hffff_ffff".U(32.W) << bfp_len
|
||||
val bfp_preshift_data = io.rs2_in(15,0) & ~bfp_len_mask_(15,0)
|
||||
|
||||
val bfp_shift_data = Cat(Fill(16,0.U),bfp_preshift_data(15,0), Fill(16,0.U),bfp_preshift_data(15,0)) << bfp_off
|
||||
val bfp_shift_mask = Cat(bfp_len_mask_(31,0), bfp_len_mask_(31,0)) << bfp_off
|
||||
|
||||
val bfp_result_d = bfp_shift_data(63,32) | (io.rs1_in & bfp_shift_mask(63,32))
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : CRC32, CRC32c * * * * * * * * * * * * * * * * *
|
||||
|
||||
// *** computed from https: //crccalc.com ***
|
||||
//
|
||||
// "a" is 8'h61 = 8'b0110_0001 (8'h61 ^ 8'hff = 8'h9e)
|
||||
//
|
||||
// Input must first be XORed with 32'hffff_ffff
|
||||
//
|
||||
//
|
||||
// CRC32
|
||||
//
|
||||
// Input Output Input Output
|
||||
// ----- -------- -------- --------
|
||||
// "a" e8b7be43 ffffff9e 174841bc
|
||||
// "aa" 078a19d7 ffff9e9e f875e628
|
||||
// "aaaa" ad98e545 9e9e9e9e 5267a1ba
|
||||
//
|
||||
//
|
||||
//
|
||||
// CRC32c
|
||||
//
|
||||
// Input Output Input Output
|
||||
// ----- -------- -------- --------
|
||||
// "a" c1d04330 ffffff9e 3e2fbccf
|
||||
// "aa" f1f2dac2 ffff9e9e 0e0d253d
|
||||
// "aaaa" 6a52eeb0 9e9e9e9e 95ad114f
|
||||
|
||||
|
||||
val crc32_all = ap_crc32_b | ap_crc32_h | ap_crc32_w | ap_crc32c_b | ap_crc32c_h | ap_crc32c_w
|
||||
|
||||
val crc32_poly_rev = "hEDB88320".U(32.W) // bit reverse of 32'h04C11DB7
|
||||
val crc32c_poly_rev = "h82F63B78".U(32.W) // bit reverse of 32'h1EDC6F41
|
||||
|
||||
|
||||
val crc32_bd = Wire(Vec(9,UInt(32.W)))
|
||||
crc32_bd(0) := io.rs1_in
|
||||
for(i <- 1 to 8) {
|
||||
crc32_bd(i) := (crc32_bd(i-1) >> 1) ^ (crc32_poly_rev & Fill(32,crc32_bd(i-1)(0)))//io.rs1_in
|
||||
}
|
||||
|
||||
val crc32_hd = Wire(Vec(17,UInt(32.W)))
|
||||
crc32_hd(0) := io.rs1_in
|
||||
for(i <- 1 to 16) {
|
||||
crc32_hd(i) := (crc32_hd(i-1) >> 1) ^ (crc32_poly_rev & Fill(32,crc32_hd(i-1)(0)))//io.rs1_in
|
||||
}
|
||||
|
||||
val crc32_wd = Wire(Vec(33,UInt(32.W)))
|
||||
crc32_wd(0) := io.rs1_in
|
||||
for(i <- 1 to 32) {
|
||||
crc32_wd(i) := (crc32_wd(i-1) >> 1) ^ (crc32_poly_rev & Fill(32,crc32_wd(i-1)(0)))//io.rs1_in
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
val crc32c_bd = Wire(Vec(9,UInt(32.W)))
|
||||
crc32c_bd(0) := io.rs1_in
|
||||
for(i <- 1 to 8) {
|
||||
crc32c_bd(i) := (crc32c_bd(i-1) >> 1) ^ (crc32c_poly_rev & Fill(32,crc32c_bd(i-1)(0)))//io.rs1_in
|
||||
}
|
||||
|
||||
|
||||
val crc32c_hd = Wire(Vec(17,UInt(32.W)))
|
||||
crc32c_hd(0) := io.rs1_in
|
||||
for(i <- 1 to 16) {
|
||||
crc32c_hd(i) := (crc32c_hd(i-1) >> 1) ^ (crc32c_poly_rev & Fill(32,crc32c_hd(i-1)(0)))//io.rs1_in
|
||||
}
|
||||
|
||||
|
||||
val crc32c_wd = Wire(Vec(33,UInt(32.W)))
|
||||
crc32c_wd(0) := io.rs1_in
|
||||
for(i <- 1 to 32) {
|
||||
crc32c_wd(i) := (crc32c_wd(i-1) >> 1) ^ (crc32c_poly_rev & Fill(32,crc32c_wd(i-1)(0)))//io.rs1_in
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * BitManip : Common logic * * * * * * * * * * * * * * * * * *
|
||||
|
||||
|
||||
val bitmanip_sel_d = ap_bext | ap_bdep | ap_clmul | ap_clmulh | ap_clmulr | ap_grev | ap_gorc | ap_shfl | ap_unshfl | crc32_all | ap_bfp
|
||||
|
||||
val bitmanip_d = Mux1H(Seq(
|
||||
ap_bext -> bext_d(31,0) ,
|
||||
ap_bdep -> bdep_d(31,0) ,
|
||||
ap_clmul -> clmul_raw_d(31,0) ,
|
||||
ap_clmulh -> Cat(0.U(1.W),clmul_raw_d(62,32)) ,
|
||||
ap_clmulr -> clmul_raw_d(62,31) ,
|
||||
ap_grev -> grev_d(31,0) ,
|
||||
ap_gorc -> gorc_d(31,0) ,
|
||||
ap_shfl -> shfl_d(31,0) ,
|
||||
ap_unshfl -> unshfl_d(31,0) ,
|
||||
ap_crc32_b -> crc32_bd(8)(31,0) ,
|
||||
ap_crc32_h -> crc32_hd(16)(31,0) ,
|
||||
ap_crc32_w -> crc32_wd(32)(31,0) ,
|
||||
ap_crc32c_b -> crc32c_bd(8)(31,0) ,
|
||||
ap_crc32c_h -> crc32c_hd(16)(31,0) ,
|
||||
ap_crc32c_w -> crc32c_wd(32)(31,0) ,
|
||||
ap_bfp -> bfp_result_d(31,0) ))
|
||||
|
||||
|
||||
|
||||
//rvdffe #(33) i_bitmanip_ff (.*, .clk(clk), .din({bitmanip_sel_d,bitmanip_d[31:0]}), .dout({bitmanip_sel_x,bitmanip_x[31:0]}), .en(bit_x_enable));
|
||||
val bitmanip_sel_x = rvdffe(bitmanip_sel_d,bit_x_enable,clock,io.scan_mode)
|
||||
val bitmanip_x = rvdffe(bitmanip_d,bit_x_enable,clock,io.scan_mode)
|
||||
|
||||
|
||||
io.result_x := (Fill(32,~bitmanip_sel_x & ~low_x) & prod_x(63,32) ) |
|
||||
(Fill(32,~bitmanip_sel_x & low_x) & prod_x(31,0) ) |
|
||||
bitmanip_x
|
||||
|
||||
io.result_x := Mux1H (Seq(!low_x.asBool -> prod_x(63,32), low_x.asBool -> prod_x(31,0)))
|
||||
}
|
||||
object mul extends App {
|
||||
println((new ChiselStage).emitVerilog(new exu_mul_ctl))}
|
||||
|
||||
|
||||
|
|
|
@ -9,14 +9,9 @@ import include._
|
|||
@chiselName
|
||||
class ifu extends Module with lib with RequireAsyncReset {
|
||||
val io = IO(new Bundle{
|
||||
val ifu_i0_fa_index = Output(UInt(log2Ceil(BTB_SIZE).W))
|
||||
val dec_i0_decode_d = Input(Bool()) // Dec
|
||||
val dec_fa_error_index = Input(UInt(log2Ceil(BTB_SIZE).W))// Fully associative btb error index
|
||||
|
||||
|
||||
val exu_flush_final = Input(Bool())
|
||||
val exu_flush_path_final = Input(UInt(31.W))
|
||||
val free_l2clk = Input(Clock())
|
||||
val exu_flush_final = Input(Bool())
|
||||
val exu_flush_path_final = Input(UInt(31.W))
|
||||
val free_clk = Input(Clock())
|
||||
val active_clk = Input(Clock())
|
||||
val ifu_dec = new ifu_dec() // IFU and DEC interconnects
|
||||
val exu_ifu = new exu_ifu() // IFU and EXU interconnects
|
||||
|
@ -42,7 +37,8 @@ class ifu extends Module with lib with RequireAsyncReset {
|
|||
val ifc_ctl = Module(new ifu_ifc_ctl)
|
||||
|
||||
// IFC wiring Inputs
|
||||
ifc_ctl.io.free_l2clk := io.free_l2clk
|
||||
ifc_ctl.io.active_clk := io.active_clk
|
||||
ifc_ctl.io.free_clk := io.free_clk
|
||||
ifc_ctl.io.scan_mode := io.scan_mode
|
||||
ifc_ctl.io.ic_hit_f := mem_ctl.io.ic_hit_f
|
||||
ifc_ctl.io.ifu_fb_consume1 := aln_ctl.io.ifu_fb_consume1
|
||||
|
@ -75,16 +71,13 @@ class ifu extends Module with lib with RequireAsyncReset {
|
|||
aln_ctl.io.ifu_bp_ret_f := bp_ctl.io.ifu_bp_ret_f
|
||||
aln_ctl.io.exu_flush_final := io.exu_flush_final
|
||||
aln_ctl.io.dec_aln <> io.ifu_dec.dec_aln
|
||||
io.ifu_i0_fa_index := aln_ctl.io.ifu_i0_fa_index
|
||||
aln_ctl.io.dec_i0_decode_d := io.dec_i0_decode_d
|
||||
aln_ctl.io.ifu_bp_fa_index_f := bp_ctl.io.ifu_bp_fa_index_f
|
||||
|
||||
aln_ctl.io.ifu_fetch_data_f := mem_ctl.io.ic_data_f
|
||||
aln_ctl.io.ifu_fetch_val := mem_ctl.io.ifu_fetch_val
|
||||
aln_ctl.io.ifu_fetch_pc := ifc_ctl.io.ifc_fetch_addr_f
|
||||
|
||||
// BP wiring Inputs
|
||||
bp_ctl.io.scan_mode := io.scan_mode
|
||||
bp_ctl.io.active_clk := io.active_clk
|
||||
bp_ctl.io.ic_hit_f := mem_ctl.io.ic_hit_f
|
||||
bp_ctl.io.ifc_fetch_addr_f := ifc_ctl.io.ifc_fetch_addr_f
|
||||
bp_ctl.io.ifc_fetch_req_f := ifc_ctl.io.ifc_fetch_req_f
|
||||
|
@ -92,10 +85,9 @@ class ifu extends Module with lib with RequireAsyncReset {
|
|||
bp_ctl.io.exu_bp <> io.exu_ifu.exu_bp
|
||||
bp_ctl.io.exu_flush_final := io.exu_flush_final
|
||||
bp_ctl.io.dec_tlu_flush_lower_wb := io.dec_tlu_flush_lower_wb
|
||||
bp_ctl.io.dec_fa_error_index := io.dec_fa_error_index
|
||||
|
||||
// mem-ctl Inputs
|
||||
mem_ctl.io.free_l2clk := io.free_l2clk
|
||||
mem_ctl.io.free_clk := io.free_clk
|
||||
mem_ctl.io.active_clk := io.active_clk
|
||||
mem_ctl.io.exu_flush_final := io.exu_flush_final
|
||||
mem_ctl.io.dec_mem_ctrl <> io.ifu_dec.dec_mem_ctrl
|
||||
|
@ -127,6 +119,3 @@ class ifu extends Module with lib with RequireAsyncReset {
|
|||
}
|
||||
|
||||
|
||||
object ifu_top extends App {
|
||||
println((new chisel3.stage.ChiselStage).emitVerilog(new ifu()))
|
||||
}
|
|
@ -6,30 +6,12 @@ import include._
|
|||
|
||||
class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
|
||||
val io = IO(new Bundle{
|
||||
val scan_mode = Input(Bool())
|
||||
val scan_mode = Input(Bool())
|
||||
val active_clk = Input(Clock())
|
||||
val ifu_async_error_start = Input(Bool()) // Error coming from mem-ctl
|
||||
val iccm_rd_ecc_double_err = Input(UInt(2.W)) // ICCM double error coming from mem-ctl
|
||||
val ic_access_fault_f = Input(UInt(2.W)) // Access fault in I$
|
||||
val iccm_rd_ecc_double_err = Input(Bool()) // ICCM double error coming from mem-ctl
|
||||
val ic_access_fault_f = Input(Bool()) // Access fault in I$
|
||||
val ic_access_fault_type_f = Input(UInt(2.W)) // Type of access fault occured
|
||||
val dec_i0_decode_d = Input(Bool())
|
||||
val dec_aln = new dec_aln()
|
||||
// val ifu_i0_valid = Output(Bool())
|
||||
// val ifu_i0_icaf = Output(Bool())
|
||||
// val ifu_i0_icaf_type = Output(UInt(2.W))
|
||||
// val ifu_i0_icaf_second = Output(Bool())
|
||||
// val ifu_i0_dbecc = Output(Bool())
|
||||
// val ifu_i0_instr = Output(UInt(32.W))
|
||||
// val ifu_i0_pc = Output(UInt(31.W))
|
||||
// val ifu_i0_pc4 = Output(Bool())
|
||||
val ifu_bp_fa_index_f = Vec(2, Input(UInt(log2Ceil(BTB_SIZE).W)))
|
||||
// val i0_brp = Output(Valid(new br_pkt_t()))
|
||||
// val ifu_i0_bp_index = Output(UInt((BTB_ADDR_HI-BTB_ADDR_LO+1).W))
|
||||
// val ifu_i0_bp_fghr = Output(UInt(BHT_GHR_SIZE.W))
|
||||
// val ifu_i0_bp_btag = Output(UInt(BTB_BTAG_SIZE.W))
|
||||
val ifu_i0_fa_index = Output(UInt(log2Ceil(BTB_SIZE).W))
|
||||
// val ifu_pmu_instr_aligned = Output(Bool())
|
||||
// val ifu_i0_cinst = Output(UInt(16.W))
|
||||
val ifu_bp_fghr_f = Input(UInt(BHT_GHR_SIZE.W)) // Data coming from the branch predictor to put in the FP
|
||||
val ifu_bp_btb_target_f = Input(UInt(31.W)) // Target for the instruction enqueue in the FP
|
||||
val ifu_bp_poffset_f = Input(UInt(12.W)) // Offset to the current PC for branch
|
||||
|
@ -40,19 +22,19 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
|
|||
val ifu_bp_valid_f = Input(UInt(2.W)) // Valid Branch prediction
|
||||
val ifu_bp_ret_f = Input(UInt(2.W)) // BP ret
|
||||
val exu_flush_final = Input(Bool()) // Miss prediction
|
||||
val dec_aln = new dec_aln() // Data going to the dec from the ALN
|
||||
val ifu_fetch_data_f = Input(UInt(32.W)) // PC of the current instruction in the FP
|
||||
val ifu_fetch_val = Input(UInt(2.W)) // PC boundary i.e 'x' of 2 or 4
|
||||
val ifu_fetch_pc = Input(UInt(31.W)) // Current PC
|
||||
/////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////
|
||||
val ifu_fb_consume1 = Output(Bool()) // FP used 1
|
||||
val ifu_fb_consume2 = Output(Bool()) // FP used 2
|
||||
|
||||
})
|
||||
val MHI = 1 + (BTB_ENABLE * (43+BHT_GHR_SIZE))
|
||||
val MSIZE = 2 + (BTB_ENABLE * (43+BHT_GHR_SIZE))
|
||||
val BRDATA_SIZE = if(BTB_ENABLE) 16+log2Ceil(BTB_SIZE) * 2 * BTB_FULLYA else 2
|
||||
val BRDATA_WIDTH = if(BTB_ENABLE) 8+log2Ceil(BTB_SIZE)*BTB_FULLYA else 1
|
||||
|
||||
val MHI = 46+BHT_GHR_SIZE // 54
|
||||
val MSIZE = 47+BHT_GHR_SIZE // 55
|
||||
val BRDATA_SIZE = 12
|
||||
val error_stall_in = WireInit(Bool(),0.U)
|
||||
val alignval = WireInit(UInt(2.W), 0.U)
|
||||
val q0final = WireInit(UInt(32.W), 0.U)
|
||||
val q1final = WireInit(UInt(16.W), 0.U)
|
||||
|
@ -76,8 +58,8 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
|
|||
val shift_f2_f0 = WireInit(Bool(), init = 0.U)
|
||||
val shift_f1_f0 = WireInit(Bool(), init = 0.U)
|
||||
|
||||
val f0icaf = WireInit(UInt(2.W), init = 0.U)
|
||||
val f1icaf = WireInit(UInt(2.W), init = 0.U)
|
||||
val f0icaf = WireInit(Bool(), init = 0.U)
|
||||
val f1icaf = WireInit(Bool(), init = 0.U)
|
||||
|
||||
val sf0val = WireInit(UInt(2.W), 0.U)
|
||||
val sf1val = WireInit(UInt(2.W), 0.U)
|
||||
|
@ -86,9 +68,9 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
|
|||
val misc1 = WireInit(UInt((MHI+1).W), 0.U)
|
||||
val misc2 = WireInit(UInt((MHI+1).W), 0.U)
|
||||
|
||||
val brdata1 = WireInit(UInt(BRDATA_SIZE.W), init = 0.U)
|
||||
val brdata0 = WireInit(UInt(BRDATA_SIZE.W), init = 0.U)
|
||||
val brdata2 = WireInit(UInt(BRDATA_SIZE.W), init = 0.U)
|
||||
val brdata1 = WireInit(UInt(12.W), init = 0.U)
|
||||
val brdata0 = WireInit(UInt(12.W), init = 0.U)
|
||||
val brdata2 = WireInit(UInt(12.W), init = 0.U)
|
||||
|
||||
val q0 = WireInit(UInt(32.W), init = 0.U)
|
||||
val q1 = WireInit(UInt(32.W), init = 0.U)
|
||||
|
@ -112,55 +94,52 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
|
|||
val first4B = WireInit(Bool(), 0.U)
|
||||
val shift_2B = WireInit(Bool(), 0.U)
|
||||
val f0_shift_2B = WireInit(Bool(), 0.U)
|
||||
implicit val clk = clock
|
||||
implicit val rst = reset.asAsyncReset()
|
||||
implicit val scan_mode = io.scan_mode
|
||||
|
||||
// Stall if there is an error in the instrucion
|
||||
val error_stall_in = (error_stall | io.ifu_async_error_start) & !io.exu_flush_final
|
||||
error_stall_in := (error_stall | io.ifu_async_error_start) & !io.exu_flush_final
|
||||
|
||||
// Flop the stall until flush
|
||||
error_stall := withClock(io.active_clk) {RegNext(error_stall_in, init = 0.U)}
|
||||
// Write Ptr of the FP
|
||||
val wrptr = withClock(io.active_clk) {RegNext(wrptr_in, init = 0.U)}
|
||||
// Read Ptr of the FP
|
||||
val rdptr = withClock(io.active_clk) {RegNext(rdptr_in, init = 0.U)}
|
||||
// Fetch Instruction boundary
|
||||
val f2val = withClock(io.active_clk) {RegNext(f2val_in, init = 0.U)}
|
||||
val f1val = withClock(io.active_clk) {RegNext(f1val_in, init = 0.U)}
|
||||
val f0val = withClock(io.active_clk) {RegNext(f0val_in, init = 0.U)}
|
||||
|
||||
val q2off = withClock(io.active_clk) {RegNext(q2off_in, init = 0.U)}
|
||||
val q1off = withClock(io.active_clk) {RegNext(q1off_in, init = 0.U)}
|
||||
val q0off = withClock(io.active_clk) {RegNext(q0off_in, init = 0.U)}
|
||||
|
||||
// Flop the stall until flush
|
||||
error_stall := rvdffie(error_stall_in,clock,reset.asAsyncReset(),io.scan_mode)
|
||||
val f2val = rvdffie(f2val_in,clock,reset.asAsyncReset(),io.scan_mode)
|
||||
val f1val = rvdffie(f1val_in,clock,reset.asAsyncReset(),io.scan_mode)
|
||||
val f0val = rvdffie(f0val_in,clock,reset.asAsyncReset(),io.scan_mode)
|
||||
// Instrution PC to the FP
|
||||
val f2pc = rvdffe(io.ifu_fetch_pc, f2_wr_en.asBool, clock, io.scan_mode)
|
||||
val f1pc = rvdffe(f1pc_in, f1_shift_wr_en.asBool, clock, io.scan_mode)
|
||||
val f0pc = rvdffe(f0pc_in, f0_shift_wr_en.asBool, clock, io.scan_mode)
|
||||
// Branch data to the FP
|
||||
if(BTB_ENABLE){
|
||||
brdata2 := rvdffe(brdata_in, qwen(2),clock,io.scan_mode)
|
||||
brdata1 := rvdffe(brdata_in, qwen(1),clock,io.scan_mode)
|
||||
brdata0 := rvdffe(brdata_in, qwen(0),clock,io.scan_mode)
|
||||
// Miscalanious data to the FP including error's
|
||||
misc2 := rvdffe(misc_data_in, qwen(2),clock,io.scan_mode)
|
||||
misc1 := rvdffe(misc_data_in, qwen(1),clock,io.scan_mode)
|
||||
misc0 := rvdffe(misc_data_in, qwen(0),clock,io.scan_mode)
|
||||
}
|
||||
else{
|
||||
brdata2 := rvdffie(Mux(qwen(2),brdata_in, brdata2),clock,reset.asAsyncReset(),io.scan_mode)
|
||||
brdata1 := rvdffie(Mux(qwen(1),brdata_in, brdata1),clock,reset.asAsyncReset(),io.scan_mode)
|
||||
brdata0 := rvdffie(Mux(qwen(0),brdata_in, brdata0),clock,reset.asAsyncReset(),io.scan_mode)
|
||||
// Miscalanious data to the FP including error's
|
||||
misc2 := rvdffie(Mux(qwen(2),misc_data_in, misc2),clock,reset.asAsyncReset(),io.scan_mode)
|
||||
misc1 := rvdffie(Mux(qwen(1),misc_data_in, misc1),clock,reset.asAsyncReset(),io.scan_mode)
|
||||
misc0 := rvdffie(Mux(qwen(0),misc_data_in, misc0),clock,reset.asAsyncReset(),io.scan_mode)
|
||||
}
|
||||
|
||||
brdata2 := rvdffe(brdata_in, qwen(2), clock, io.scan_mode)
|
||||
brdata1 := rvdffe(brdata_in, qwen(1), clock, io.scan_mode)
|
||||
brdata0 := rvdffe(brdata_in, qwen(0), clock, io.scan_mode)
|
||||
// Miscalanious data to the FP including error's
|
||||
misc2 := rvdffe(misc_data_in, qwen(2), clock, io.scan_mode)
|
||||
misc1 := rvdffe(misc_data_in, qwen(1), clock, io.scan_mode)
|
||||
misc0 := rvdffe(misc_data_in, qwen(0), clock, io.scan_mode)
|
||||
// Instruction in the FP
|
||||
q2 := rvdffe(io.ifu_fetch_data_f, qwen(2),clock,io.scan_mode)
|
||||
q1 := rvdffe(io.ifu_fetch_data_f, qwen(1),clock,io.scan_mode)
|
||||
q0 := rvdffe(io.ifu_fetch_data_f, qwen(0),clock,io.scan_mode)
|
||||
|
||||
val q2pc = rvdffe(io.ifu_fetch_pc, qwen(2),clock,io.scan_mode)
|
||||
val q1pc = rvdffe(io.ifu_fetch_pc, qwen(1),clock,io.scan_mode)
|
||||
val q0pc = rvdffe(io.ifu_fetch_pc, qwen(0),clock,io.scan_mode)
|
||||
q2 := rvdffe(io.ifu_fetch_data_f, qwen(2), clock, io.scan_mode)
|
||||
q1 := rvdffe(io.ifu_fetch_data_f, qwen(1), clock, io.scan_mode)
|
||||
q0 := rvdffe(io.ifu_fetch_data_f, qwen(0), clock, io.scan_mode)
|
||||
|
||||
// Shift FP logic
|
||||
f2_wr_en := fetch_to_f2
|
||||
f1_shift_wr_en := fetch_to_f1 | shift_f2_f1 | f1_shift_2B
|
||||
f0_shift_wr_en := fetch_to_f0 | shift_f2_f0 | shift_f1_f0 | shift_2B | shift_4B
|
||||
// FP read enable .. 3-bit for Implemenation of 1HMux
|
||||
val qren = Cat(rdptr === 2.U, rdptr === 1.U, rdptr === 0.U)
|
||||
// FP write enable .. 3-bit for Implemenation of 1HMux
|
||||
qwen := Cat(wrptr === 2.U & ifvalid, wrptr === 1.U & ifvalid, wrptr === 0.U & ifvalid)
|
||||
|
||||
qwen := Cat((wrptr === 2.U) & ifvalid, (wrptr === 1.U) & ifvalid, (wrptr === 0.U) & ifvalid)
|
||||
|
||||
// Read Pointer calculation
|
||||
// Next rdptr = # of consume + current ptr location (Rounding it from 2)
|
||||
rdptr_in := Mux1H(Seq((qren(0) & io.ifu_fb_consume1 & !io.exu_flush_final).asBool -> 1.U,
|
||||
(qren(1) & io.ifu_fb_consume1 & !io.exu_flush_final).asBool -> 2.U,
|
||||
(qren(2) & io.ifu_fb_consume1 & !io.exu_flush_final).asBool -> 0.U,
|
||||
|
@ -169,156 +148,86 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
|
|||
(qren(2) & io.ifu_fb_consume2 & !io.exu_flush_final).asBool -> 1.U,
|
||||
(!io.ifu_fb_consume1 & !io.ifu_fb_consume2 & !io.exu_flush_final).asBool -> rdptr))
|
||||
|
||||
|
||||
// As there is only 1 enqueue so each time move by 1
|
||||
wrptr_in := Mux1H(Seq((qwen(0) & !io.exu_flush_final).asBool -> 1.U,
|
||||
(qwen(1) & !io.exu_flush_final).asBool -> 2.U,
|
||||
(qwen(2) & !io.exu_flush_final).asBool -> 0.U,
|
||||
(!ifvalid & !io.exu_flush_final).asBool-> wrptr))
|
||||
(!ifvalid & !io.exu_flush_final).asBool->wrptr))
|
||||
|
||||
q2off_in := Mux1H(Seq((!qwen(2) & (rdptr===2.U)).asBool -> (q2off.asUInt | f0_shift_2B),
|
||||
(!qwen(2) & (rdptr===1.U)).asBool -> (q2off.asUInt | f1_shift_2B),
|
||||
(!qwen(2) & (rdptr===0.U)).asBool -> q2off))
|
||||
q2off_in := Mux1H(Seq((!qwen(2) & (rdptr===2.U)).asBool->(q2off.asUInt | f0_shift_2B),
|
||||
(!qwen(2) & (rdptr===1.U)).asBool->(q2off.asUInt | f1_shift_2B),
|
||||
(!qwen(2) & (rdptr===0.U)).asBool->q2off))
|
||||
|
||||
q1off_in := Mux1H(Seq((!qwen(1) & (rdptr===1.U)).asBool -> (q1off.asUInt | f0_shift_2B),
|
||||
(!qwen(1) & (rdptr===0.U)).asBool -> (q1off.asUInt | f1_shift_2B),
|
||||
(!qwen(1) & (rdptr===2.U)).asBool -> q1off))
|
||||
q1off_in := Mux1H(Seq((!qwen(1) & (rdptr===1.U)).asBool->(q1off.asUInt | f0_shift_2B),
|
||||
(!qwen(1) & (rdptr===0.U)).asBool->(q1off.asUInt | f1_shift_2B),
|
||||
(!qwen(1) & (rdptr===2.U)).asBool->q1off))
|
||||
|
||||
q0off_in := Mux1H(Seq((!qwen(0) & (rdptr===0.U)).asBool -> (q0off.asUInt | f0_shift_2B),
|
||||
(!qwen(0) & (rdptr===2.U)).asBool -> (q0off.asUInt | f1_shift_2B),
|
||||
(!qwen(0) & (rdptr===1.U)).asBool -> q0off))
|
||||
(!qwen(0) & (rdptr===2.U)).asBool -> (q0off.asUInt | f1_shift_2B),
|
||||
(!qwen(0) & (rdptr===1.U)).asBool -> q0off))
|
||||
|
||||
// Shift FP logic
|
||||
val q0ptr = Mux1H(Seq((rdptr===0.U)->q0off,
|
||||
(rdptr===1.U)->q1off,
|
||||
(rdptr===2.U)->q2off))
|
||||
|
||||
val q0ptr = Mux1H(Seq((rdptr===0.U) -> q0off,
|
||||
(rdptr===1.U) -> q1off,
|
||||
(rdptr===2.U) -> q2off))
|
||||
|
||||
val q1ptr = Mux1H(Seq((rdptr===0.U) -> q1off, (rdptr === 1.U) -> q2off, (rdptr === 2.U) -> q0off))
|
||||
val q1ptr = Mux1H(Seq((rdptr===0.U) -> q1off, (rdptr === 1.U) -> q2off, (rdptr === 2.U) -> q0off))
|
||||
|
||||
val q0sel = Cat(q0ptr, !q0ptr)
|
||||
|
||||
val q1sel = Cat(q1ptr, !q1ptr)
|
||||
// Misc data error, access-fault, type of fault, target, offset and ghr value
|
||||
|
||||
if(BTB_ENABLE){
|
||||
misc_data_in := Cat(io.ic_access_fault_type_f, io.ifu_bp_btb_target_f, io.ifu_bp_poffset_f, io.ifu_bp_fghr_f)
|
||||
|
||||
}else{
|
||||
misc_data_in := io.ic_access_fault_type_f
|
||||
}
|
||||
misc_data_in := Cat(io.iccm_rd_ecc_double_err, io.ic_access_fault_f, io.ic_access_fault_type_f,
|
||||
io.ifu_bp_btb_target_f, io.ifu_bp_poffset_f, io.ifu_bp_fghr_f)
|
||||
|
||||
val misceff = Mux1H(Seq(qren(0).asBool() -> Cat(misc1, misc0),
|
||||
qren(1).asBool() -> Cat(misc2, misc1),
|
||||
qren(2).asBool() -> Cat(misc0, misc2)))
|
||||
qren(1).asBool()->Cat(misc2, misc1),
|
||||
qren(2).asBool()->Cat(misc0, misc2)))
|
||||
|
||||
val misc1eff = misceff(misceff.getWidth-1,MHI+1)
|
||||
val misc0eff = misceff(MHI, 0)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
val f1ictype = if(BTB_ENABLE) misc1eff(misc1eff.getWidth-1, misc1eff.getWidth-2) else misc1eff
|
||||
val f1prett = if(BTB_ENABLE) misc1eff(misc1eff.getWidth-3, misc1eff.getWidth-33) else 0.U
|
||||
val f1poffset = if(BTB_ENABLE) misc1eff(misc1eff.getWidth-34, misc1eff.getWidth-45) else 0.U
|
||||
val f1fghr = if(BTB_ENABLE) misc1eff(BHT_GHR_SIZE-1, 0) else 0.U
|
||||
|
||||
val f0ictype = if(BTB_ENABLE) misc0eff(misc0eff.getWidth-1, misc0eff.getWidth-2) else misc0eff
|
||||
val f0prett = if(BTB_ENABLE) misc0eff(misc0eff.getWidth-3, misc0eff.getWidth-33) else 0.U
|
||||
val f0poffset = if(BTB_ENABLE) misc0eff(misc0eff.getWidth-34, misc0eff.getWidth-45) else 0.U
|
||||
val f0fghr = if(BTB_ENABLE) misc0eff(BHT_GHR_SIZE-1, 0) else 0.U
|
||||
val f1dbecc = misc1eff(misc1eff.getWidth-1)
|
||||
f1icaf := misc1eff(misc1eff.getWidth-2)
|
||||
val f1ictype = misc1eff(misc1eff.getWidth-3,misc1eff.getWidth-4)
|
||||
val f1prett = misc1eff(misc1eff.getWidth-5,misc1eff.getWidth-35)
|
||||
val f1poffset = misc1eff(BHT_GHR_SIZE+11, BHT_GHR_SIZE)
|
||||
val f1fghr = misc1eff(BHT_GHR_SIZE-1, 0)
|
||||
|
||||
val f0ret = WireInit(UInt(2.W), 0.U)
|
||||
val f0brend = WireInit(UInt(2.W), 0.U)
|
||||
val f0way = WireInit(UInt(2.W), 0.U)
|
||||
val f0pc4 = WireInit(UInt(2.W), 0.U)
|
||||
val f0hist0 = WireInit(UInt(2.W), 0.U)
|
||||
val f0hist1 = WireInit(UInt(2.W), 0.U)
|
||||
val f1ret = WireInit(UInt(2.W), 0.U)
|
||||
val f1brend = WireInit(UInt(2.W), 0.U)
|
||||
val f1way = WireInit(UInt(2.W), 0.U)
|
||||
val f1pc4 = WireInit(UInt(2.W), 0.U)
|
||||
val f1hist0 = WireInit(UInt(2.W), 0.U)
|
||||
val f1hist1 = WireInit(UInt(2.W), 0.U)
|
||||
val f0dbecc = misc0eff(misc1eff.getWidth-1)
|
||||
f0icaf := misc0eff(misc1eff.getWidth-2)
|
||||
val f0ictype = misc0eff(misc1eff.getWidth-3,misc1eff.getWidth-4)
|
||||
val f0prett = misc0eff(misc1eff.getWidth-5,misc1eff.getWidth-35)
|
||||
val f0poffset = misc0eff(BHT_GHR_SIZE+11, BHT_GHR_SIZE)
|
||||
val f0fghr = misc0eff(BHT_GHR_SIZE-1, 0)
|
||||
|
||||
// Branch information
|
||||
brdata_in := Cat(io.ifu_bp_hist1_f(1),io.ifu_bp_hist0_f(1),io.ifu_bp_pc4_f(1),io.ifu_bp_way_f(1),io.ifu_bp_valid_f(1),
|
||||
io.ifu_bp_ret_f(1), io.ifu_bp_hist1_f(0),io.ifu_bp_hist0_f(0),io.ifu_bp_pc4_f(0),io.ifu_bp_way_f(0),
|
||||
io.ifu_bp_valid_f(0),io.ifu_bp_ret_f(0))
|
||||
// Effective branch information
|
||||
val brdataeff = Mux1H(Seq(qren(0).asBool->Cat(brdata1,brdata0),
|
||||
qren(1).asBool->Cat(brdata2,brdata1),
|
||||
qren(2).asBool->Cat(brdata0,brdata2)))
|
||||
|
||||
val f0dbecc = WireInit(UInt(2.W), 0.U)
|
||||
val f1dbecc = WireInit(UInt(2.W), 0.U)
|
||||
val f0index = Wire(Vec(2,UInt(log2Ceil(BTB_SIZE).W)))
|
||||
val f1index = Wire(Vec(2,UInt(log2Ceil(BTB_SIZE).W)))
|
||||
f0index := (0 until 2).map(i => 0.U)
|
||||
f1index := (0 until 2).map(i => 0.U)
|
||||
val brdataeff = WireInit(UInt(((2*BRDATA_SIZE)).W),0.U)
|
||||
brdataeff := Mux1H(Seq(qren(0).asBool -> Cat(brdata1,brdata0),
|
||||
qren(1).asBool -> Cat(brdata2,brdata1),
|
||||
qren(2).asBool -> Cat(brdata0,brdata2)))
|
||||
val brdata1eff = WireInit(UInt(BRDATA_SIZE.W),0.U)
|
||||
val brdata0eff = WireInit(UInt(BRDATA_SIZE.W),0.U)
|
||||
brdata1eff := brdataeff(brdataeff.getWidth - 1,brdataeff.getWidth/2)
|
||||
brdata0eff := brdataeff(brdataeff.getWidth/2 - 1,0)
|
||||
val brdata0final = Mux1H(Seq(q0sel(0).asBool -> brdata0eff(2*BRDATA_WIDTH-1,0),
|
||||
q0sel(1).asBool -> brdata0eff(BRDATA_SIZE-1,BRDATA_WIDTH)))
|
||||
val brdata1final = Mux1H(Seq(q1sel(0).asBool -> brdata1eff(2*BRDATA_WIDTH-1,0),
|
||||
q1sel(1).asBool -> brdata1eff(BRDATA_SIZE-1,BRDATA_WIDTH)))
|
||||
if(BTB_ENABLE){
|
||||
if(BTB_FULLYA){
|
||||
brdata_in := Cat(io.ifu_bp_fa_index_f(1), io.iccm_rd_ecc_double_err(1), io.ic_access_fault_f(1), io.ifu_bp_hist1_f(1), io.ifu_bp_hist0_f(1), io.ifu_bp_pc4_f(1), io.ifu_bp_way_f(1), io.ifu_bp_valid_f(1), io.ifu_bp_ret_f(1),
|
||||
io.ifu_bp_fa_index_f(0), io.iccm_rd_ecc_double_err(0), io.ic_access_fault_f(0), io.ifu_bp_hist1_f(0), io.ifu_bp_hist0_f(0), io.ifu_bp_pc4_f(0), io.ifu_bp_way_f(0), io.ifu_bp_valid_f(0), io.ifu_bp_ret_f(0))
|
||||
val (brdata0eff,brdata1eff) = (brdataeff(11,0) , brdataeff(23,12))
|
||||
|
||||
f0ret := Cat(brdata0final(17) , brdata0final(0))
|
||||
f0brend := Cat(brdata0final(18), brdata0final(1))
|
||||
f0way := Cat(brdata0final(19), brdata0final(2))
|
||||
f0pc4 := Cat(brdata0final(20), brdata0final(3))
|
||||
f0hist0 := Cat(brdata0final(21), brdata0final(4))
|
||||
f0hist1 := Cat(brdata0final(22), brdata0final(5))
|
||||
f0icaf := Cat(brdata0final(23), brdata0final(6))
|
||||
f0dbecc := Cat(brdata0final(24), brdata0final(7))
|
||||
f0index(1) := Cat(brdata0final(33), brdata0final(32), brdata0final(31), brdata0final(30), brdata0final(29), brdata0final(28), brdata0final(27), brdata0final(26), brdata0final(25))
|
||||
f0index(0) := Cat(brdata0final(16), brdata0final(15), brdata0final(14), brdata0final(13), brdata0final(12), brdata0final(11), brdata0final(10), brdata0final(9), brdata0final(8))
|
||||
val brdata0final = Mux1H(Seq(q0sel(0).asBool -> brdata0eff, q0sel(1).asBool -> brdata0eff(11,6)))
|
||||
val brdata1final = Mux1H(Seq(q1sel(0).asBool -> brdata1eff, q1sel(1).asBool -> brdata1eff(11,6)))
|
||||
|
||||
f1ret := Cat(brdata1final(17) , brdata1final(0))
|
||||
f1brend := Cat(brdata1final(18), brdata1final(1))
|
||||
f1way := Cat(brdata1final(19), brdata1final(2))
|
||||
f1pc4 := Cat(brdata1final(20), brdata1final(3))
|
||||
f1hist0 := Cat(brdata1final(21), brdata1final(4))
|
||||
f1hist1 := Cat(brdata1final(22), brdata1final(5))
|
||||
f1icaf := Cat(brdata1final(23), brdata1final(6))
|
||||
f1dbecc := Cat(brdata1final(24), brdata1final(7))
|
||||
f1index(1) := Cat(brdata1final(33), brdata1final(32), brdata1final(31), brdata1final(30), brdata1final(29), brdata1final(28), brdata1final(27), brdata1final(26), brdata1final(25))
|
||||
f1index(0) := Cat(brdata1final(16), brdata1final(15), brdata1final(14), brdata1final(13), brdata1final(12), brdata1final(11), brdata1final(10), brdata1final(9), brdata1final(8))
|
||||
val f0ret = Cat(brdata0final(6),brdata0final(0))
|
||||
val f0brend = Cat(brdata0final(7),brdata0final(1))
|
||||
val f0way = Cat(brdata0final(8),brdata0final(2))
|
||||
val f0pc4 = Cat(brdata0final(9),brdata0final(3))
|
||||
val f0hist0 = Cat(brdata0final(10),brdata0final(4))
|
||||
val f0hist1 = Cat(brdata0final(11),brdata0final(5))
|
||||
|
||||
}else{
|
||||
brdata_in := Cat(io.iccm_rd_ecc_double_err(1), io.ic_access_fault_f(1), io.ifu_bp_hist1_f(1), io.ifu_bp_hist0_f(1), io.ifu_bp_pc4_f(1), io.ifu_bp_way_f(1), io.ifu_bp_valid_f(1), io.ifu_bp_ret_f(1),
|
||||
io.iccm_rd_ecc_double_err(0), io.ic_access_fault_f(0), io.ifu_bp_hist1_f(0), io.ifu_bp_hist0_f(0), io.ifu_bp_pc4_f(0), io.ifu_bp_way_f(0), io.ifu_bp_valid_f(0), io.ifu_bp_ret_f(0))
|
||||
f0ret := Cat(brdata0final(8) , brdata0final(0))
|
||||
f0brend := Cat(brdata0final(9) , brdata0final(1))
|
||||
f0way := Cat(brdata0final(10), brdata0final(2))
|
||||
f0pc4 := Cat(brdata0final(11), brdata0final(3))
|
||||
f0hist0 := Cat(brdata0final(12), brdata0final(4))
|
||||
f0hist1 := Cat(brdata0final(13), brdata0final(5))
|
||||
f0icaf := Cat(brdata0final(14), brdata0final(6))
|
||||
f0dbecc := Cat(brdata0final(15), brdata0final(7))
|
||||
|
||||
f1ret := Cat(brdata1final(8) , brdata1final(0))
|
||||
f1brend := Cat(brdata1final(9) , brdata1final(1))
|
||||
f1way := Cat(brdata1final(10), brdata1final(2))
|
||||
f1pc4 := Cat(brdata1final(11), brdata1final(3))
|
||||
f1hist0 := Cat(brdata1final(12), brdata1final(4))
|
||||
f1hist1 := Cat(brdata1final(13), brdata1final(5))
|
||||
f1icaf := Cat(brdata1final(14), brdata1final(6))
|
||||
f1dbecc := Cat(brdata1final(15), brdata1final(7))
|
||||
|
||||
}
|
||||
}else{
|
||||
brdata_in := Cat(io.iccm_rd_ecc_double_err(1),io.ic_access_fault_f(1),
|
||||
io.iccm_rd_ecc_double_err(0),io.ic_access_fault_f(0))
|
||||
|
||||
|
||||
f0dbecc := Cat(brdata0final(3),brdata0final(1))
|
||||
f0icaf := Cat(brdata0final(2),brdata0final(0))
|
||||
|
||||
f1dbecc := Cat(brdata1final(3),brdata1final(1))
|
||||
f1icaf := Cat(brdata1final(2),brdata1final(0))
|
||||
|
||||
|
||||
}
|
||||
val f1ret = Cat(brdata1final(6),brdata1final(0))
|
||||
val f1brend = Cat(brdata1final(7),brdata1final(1))
|
||||
val f1way = Cat(brdata1final(8),brdata1final(2))
|
||||
val f1pc4 = Cat(brdata1final(9),brdata1final(3))
|
||||
val f1hist0 = Cat(brdata1final(10),brdata1final(4))
|
||||
val f1hist1 = Cat(brdata1final(11),brdata1final(5))
|
||||
|
||||
|
||||
f2_valid := f2val(0)
|
||||
|
@ -341,82 +250,81 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
|
|||
|
||||
fetch_to_f0 := !sf0_valid & !sf1_valid & !f2_valid & ifvalid
|
||||
fetch_to_f1 := (!sf0_valid & !sf1_valid & f2_valid & ifvalid) |
|
||||
(!sf0_valid & sf1_valid & !f2_valid & ifvalid) |
|
||||
( sf0_valid & !sf1_valid & !f2_valid & ifvalid)
|
||||
(!sf0_valid & sf1_valid & !f2_valid & ifvalid) |
|
||||
( sf0_valid & !sf1_valid & !f2_valid & ifvalid)
|
||||
|
||||
fetch_to_f2 := (!sf0_valid & sf1_valid & f2_valid & ifvalid) |
|
||||
( sf0_valid & sf1_valid & !f2_valid & ifvalid)
|
||||
( sf0_valid & sf1_valid & !f2_valid & ifvalid)
|
||||
|
||||
val f0pc_plus1 = f0pc + 1.U
|
||||
|
||||
val f1pc_plus1 = f1pc + 1.U
|
||||
|
||||
val sf1pc = (Fill(31, f1_shift_2B) & f1pc_plus1) | (Fill(31, !f1_shift_2B) & f1pc)
|
||||
|
||||
f1pc_in := Mux1H(Seq(fetch_to_f1.asBool->io.ifu_fetch_pc,
|
||||
shift_f2_f1.asBool->f2pc,
|
||||
(!fetch_to_f1 & !shift_f2_f1).asBool -> sf1pc))
|
||||
|
||||
f0pc_in := Mux1H(Seq(fetch_to_f0.asBool->io.ifu_fetch_pc,
|
||||
shift_f2_f0.asBool->f2pc,
|
||||
shift_f1_f0.asBool->sf1pc,
|
||||
(!fetch_to_f0 & !shift_f2_f0 & !shift_f1_f0).asBool->f0pc_plus1))
|
||||
|
||||
f2val_in := Mux1H(Seq((fetch_to_f2 & !io.exu_flush_final).asBool->io.ifu_fetch_val,
|
||||
(!fetch_to_f2 & !shift_f2_f1 & !shift_f2_f0 & !io.exu_flush_final).asBool->f2val))
|
||||
(!fetch_to_f2 & !shift_f2_f1 & !shift_f2_f0 & !io.exu_flush_final).asBool->f2val))
|
||||
|
||||
sf1val := Mux1H(Seq(f1_shift_2B.asBool->f1val(1), !f1_shift_2B.asBool->f1val))
|
||||
|
||||
f1val_in := Mux1H(Seq(( fetch_to_f1 & !io.exu_flush_final).asBool -> io.ifu_fetch_val,
|
||||
( shift_f2_f1 & !io.exu_flush_final).asBool->f2val,
|
||||
(!fetch_to_f1 & !shift_f2_f1 & !shift_f1_f0 & !io.exu_flush_final).asBool->sf1val))
|
||||
( shift_f2_f1 & !io.exu_flush_final).asBool->f2val,
|
||||
(!fetch_to_f1 & !shift_f2_f1 & !shift_f1_f0 & !io.exu_flush_final).asBool->sf1val))
|
||||
|
||||
sf0val := Mux1H(Seq(shift_2B.asBool->Cat(0.U, f0val(1)),
|
||||
(!shift_2B & !shift_4B).asBool->f0val))
|
||||
(!shift_2B & !shift_4B).asBool->f0val))
|
||||
|
||||
f0val_in := Mux1H(Seq((fetch_to_f0 & !io.exu_flush_final).asBool->io.ifu_fetch_val,
|
||||
( shift_f2_f0 & !io.exu_flush_final).asBool->f2val,
|
||||
( shift_f1_f0 & !io.exu_flush_final).asBool->sf1val,
|
||||
(!fetch_to_f0 & !shift_f2_f0 & !shift_f1_f0 & !io.exu_flush_final).asBool->sf0val))
|
||||
( shift_f2_f0 & !io.exu_flush_final).asBool->f2val,
|
||||
( shift_f1_f0 & !io.exu_flush_final).asBool->sf1val,
|
||||
(!fetch_to_f0 & !shift_f2_f0 & !shift_f1_f0 & !io.exu_flush_final).asBool->sf0val))
|
||||
|
||||
val qeff = Mux1H(Seq(qren(0).asBool -> Cat(q1,q0),
|
||||
qren(1).asBool -> Cat(q2,q1),
|
||||
qren(2).asBool -> Cat(q0,q2)))
|
||||
val qeff = Mux1H(Seq(qren(0).asBool->Cat(q1,q0),
|
||||
qren(1).asBool->Cat(q2,q1),
|
||||
qren(2).asBool->Cat(q0,q2)))
|
||||
val (q1eff, q0eff) = (qeff(63,32), qeff(31,0))
|
||||
|
||||
q0final := Mux1H(Seq(q0sel(0).asBool->q0eff,
|
||||
q0sel(1).asBool->q0eff(31,16)))
|
||||
q0final := Mux1H(Seq(q0sel(0).asBool->q0eff, q0sel(1).asBool->q0eff(31,16)))
|
||||
|
||||
q1final := Mux1H(Seq(q1sel(0).asBool->q1eff(15,0), q1sel(1).asBool->q1eff(31,16)))
|
||||
|
||||
val qpceff = Mux1H(Seq(qren(0).asBool -> Cat(q1pc, q0pc),
|
||||
qren(1).asBool -> Cat(q2pc, q1pc),
|
||||
qren(2).asBool -> Cat(q0pc, q2pc)))
|
||||
val q1pceff = qpceff(61, 31)
|
||||
val q0pceff = qpceff(30, 0)
|
||||
val q0pcfinal = Mux1H(Seq(q0sel(0) -> q0pceff, q0sel(1) -> (q0pceff+1.U)))
|
||||
// Alinging the data according to the boundary of PC
|
||||
val aligndata = Mux1H(Seq(f0val(1).asBool -> q0final, (!f0val(1) & f0val(0)).asBool -> Cat(q1final(15,0),q0final(15,0))))
|
||||
val aligndata = Mux1H(Seq(f0val(1).asBool -> q0final, (~f0val(1) & f0val(0)).asBool -> Cat(q1final(15,0),q0final(15,0))))
|
||||
|
||||
alignval := Mux1H(Seq(f0val(1).asBool->3.U, (!f0val(1) & f0val(0)) -> Cat(f1val(0),1.U)))
|
||||
|
||||
val alignicaf = Mux1H(Seq(f0val(1).asBool -> f0icaf, (~f0val(1) & f0val(0)).asBool -> Cat(f1icaf(0),f0icaf(0))))
|
||||
val alignicaf = Mux1H(Seq(f0val(1).asBool -> f0icaf, (~f0val(1) & f0val(0)).asBool -> Cat(f1icaf,f0icaf)))
|
||||
|
||||
val aligndbecc = Mux1H(Seq(f0val(1).asBool -> f0dbecc, (!f0val(1) & f0val(0)).asBool -> Cat(f1dbecc(0),f0dbecc(0))))
|
||||
val aligndbecc = Mux1H(Seq(f0val(1).asBool -> Fill(2,f0dbecc), (!f0val(1) & f0val(0)).asBool -> Cat(f1dbecc,f0dbecc)))
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
val alignbrend = if(BTB_ENABLE) Mux1H(Seq(f0val(1).asBool()->f0brend, (!f0val(1) & f0val(0)).asBool->Cat(f1brend(0),f0brend(0)))) else 0.U
|
||||
val alignbrend = Mux1H(Seq(f0val(1).asBool()->f0brend, (!f0val(1) & f0val(0)).asBool->Cat(f1brend(0),f0brend(0))))
|
||||
|
||||
val alignpc4 = if(BTB_ENABLE) Mux1H(Seq(f0val(1).asBool()->f0pc4, (!f0val(1) & f0val(0)).asBool->Cat(f1pc4(0),f0pc4(0)))) else 0.U
|
||||
val alignpc4 = Mux1H(Seq(f0val(1).asBool()->f0pc4, (!f0val(1) & f0val(0)).asBool->Cat(f1pc4(0),f0pc4(0))))
|
||||
|
||||
val alignret = if(BTB_ENABLE) Mux1H(Seq(f0val(1).asBool()->f0ret, (!f0val(1) & f0val(0)).asBool->Cat(f1ret(0),f0ret(0)))) else 0.U
|
||||
val alignret = Mux1H(Seq(f0val(1).asBool()->f0ret, (!f0val(1) & f0val(0)).asBool->Cat(f1ret(0),f0ret(0))))
|
||||
|
||||
val alignway = if(BTB_ENABLE) Mux1H(Seq(f0val(1).asBool()->f0way, (!f0val(1) & f0val(0)).asBool->Cat(f1way(0),f0way(0)))) else 0.U
|
||||
val alignway = Mux1H(Seq(f0val(1).asBool()->f0way, (!f0val(1) & f0val(0)).asBool->Cat(f1way(0),f0way(0))))
|
||||
|
||||
val alignhist1 = if(BTB_ENABLE) Mux1H(Seq(f0val(1).asBool()->f0hist1, (!f0val(1) & f0val(0)).asBool->Cat(f1hist1(0),f0hist1(0)))) else 0.U
|
||||
val alignhist1 = Mux1H(Seq(f0val(1).asBool()->f0hist1, (!f0val(1) & f0val(0)).asBool->Cat(f1hist1(0),f0hist1(0))))
|
||||
|
||||
val alignhist0 = if(BTB_ENABLE) Mux1H(Seq(f0val(1).asBool()->f0hist0, (!f0val(1) & f0val(0)).asBool->Cat(f1hist0(0),f0hist0(0)))) else 0.U
|
||||
|
||||
val secondpc = if(BTB_ENABLE) Mux1H(Seq(f0val(1).asBool() -> (q0pceff + 1.U), (!f0val(1) & f0val(0)).asBool -> q1pceff)) else 0.U
|
||||
|
||||
val firstpc = if(BTB_ENABLE) q0pcfinal else 0.U
|
||||
|
||||
val alignindex = Wire(Vec(2,UInt(log2Ceil(BTB_SIZE).W)))
|
||||
alignindex := (0 until 2).map(i => 0.U)
|
||||
if(BTB_ENABLE){if(BTB_FULLYA) {
|
||||
alignindex(0):= f0index(0)
|
||||
alignindex(1):= Mux(f0val(1).asBool, f0index(1), f1index(0))
|
||||
} }
|
||||
/////////////////////////////////////////////////////////
|
||||
val alignhist0 = Mux1H(Seq(f0val(1).asBool()->f0hist0, (!f0val(1) & f0val(0)).asBool->Cat(f1hist0(0),f0hist0(0))))
|
||||
|
||||
val alignfromf1 = !f0val(1) & f0val(0)
|
||||
|
||||
io.dec_aln.aln_ib.ifu_i0_pc := q0pcfinal
|
||||
val secondpc = Mux1H(Seq(f0val(1).asBool()->f0pc_plus1 , (!f0val(1) & f0val(0)).asBool->f1pc))
|
||||
|
||||
io.dec_aln.aln_ib.ifu_i0_pc := f0pc
|
||||
|
||||
val firstpc = f0pc
|
||||
|
||||
io.dec_aln.aln_ib.ifu_i0_pc4 := first4B
|
||||
|
||||
|
@ -425,7 +333,7 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
|
|||
// Instruction is compressed or not
|
||||
first4B := aligndata(1,0) === 3.U
|
||||
|
||||
val first2B = !first4B
|
||||
val first2B = ~first4B
|
||||
|
||||
io.dec_aln.aln_ib.ifu_i0_valid := Mux1H(Seq(first4B.asBool -> alignval(1), first2B.asBool -> alignval(0)))
|
||||
|
||||
|
@ -433,9 +341,9 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
|
|||
|
||||
io.dec_aln.aln_ib.ifu_i0_icaf_type := Mux((first4B & !f0val(1) & f0val(0) & !alignicaf(0) & !aligndbecc(0)).asBool, f1ictype, f0ictype)
|
||||
|
||||
val icaf_eff = alignicaf | aligndbecc
|
||||
val icaf_eff = alignicaf(1) | aligndbecc(1)
|
||||
|
||||
io.dec_aln.aln_ib.ifu_i0_icaf_second := first4B & !icaf_eff(0) & icaf_eff(1)
|
||||
io.dec_aln.aln_ib.ifu_i0_icaf_f1 := first4B & icaf_eff & alignfromf1
|
||||
|
||||
io.dec_aln.aln_ib.ifu_i0_dbecc := Mux1H(Seq(first4B.asBool->aligndbecc.orR, first2B.asBool->aligndbecc(0)))
|
||||
|
||||
|
@ -443,74 +351,55 @@ class ifu_aln_ctl extends Module with lib with RequireAsyncReset {
|
|||
// Expander from 16-bit to 32-bit
|
||||
val decompressed = Module(new ifu_compress_ctl())
|
||||
|
||||
io.dec_aln.aln_ib.ifu_i0_instr := Mux1H(Seq((first4B & alignval(1)).asBool -> ifirst,
|
||||
(first2B & alignval(0)).asBool -> decompressed.io.dout))
|
||||
io.dec_aln.aln_ib.ifu_i0_instr := Mux1H(Seq(first4B.asBool -> ifirst, first2B.asBool -> decompressed.io.dout))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
val firstpc_hash = btb_addr_hash(firstpc)
|
||||
// Hashing the PC
|
||||
val firstpc_hash = btb_addr_hash(f0pc)
|
||||
|
||||
val secondpc_hash = btb_addr_hash(secondpc)
|
||||
|
||||
val firstbrtag_hash = WireInit(UInt(BTB_BTAG_SIZE.W),0.U)
|
||||
val secondbrtag_hash = WireInit(UInt(BTB_BTAG_SIZE.W),0.U)
|
||||
if(BTB_ENABLE){if(BTB_FULLYA)
|
||||
firstbrtag_hash := firstpc else {if(BTB_BTAG_FOLD) firstbrtag_hash := btb_tag_hash_fold(firstpc) else firstbrtag_hash := btb_tag_hash(firstpc)} }
|
||||
if(BTB_ENABLE){if(BTB_FULLYA)
|
||||
secondbrtag_hash := secondpc else {if(BTB_BTAG_FOLD) secondbrtag_hash := btb_tag_hash_fold(secondpc) else secondbrtag_hash := btb_tag_hash(secondpc)} }
|
||||
val firstbrtag_hash = if(BTB_BTAG_FOLD) btb_tag_hash_fold(firstpc) else btb_tag_hash(firstpc)
|
||||
|
||||
if(BTB_ENABLE){
|
||||
io.dec_aln.aln_ib.i0_brp.valid := (first2B & alignbrend(0)) | (first4B & alignbrend(1)) | (first4B & alignval(1) & alignbrend(0))
|
||||
val secondbrtag_hash = if(BTB_BTAG_FOLD) btb_tag_hash_fold(secondpc) else btb_tag_hash(secondpc)
|
||||
|
||||
val i0_brp_pc4 = (first2B & alignpc4(0)) | (first4B & alignpc4(1))
|
||||
io.dec_aln.aln_ib.i0_brp.valid :=(first2B & alignbrend(0)) | (first4B & alignbrend(1)) | (first4B & alignval(1) & alignbrend(0))
|
||||
|
||||
io.dec_aln.aln_ib.i0_brp.bits.ret := (first2B & alignret(0)) | (first4B & alignret(1))
|
||||
io.dec_aln.aln_ib.i0_brp.bits.ret := (first2B & alignret(0)) | (first4B & alignret(1))
|
||||
|
||||
io.dec_aln.aln_ib.i0_brp.bits.way := Mux((first2B | alignbrend(0)).asBool, alignway(0), alignway(1))
|
||||
val i0_brp_pc4 = (first2B & alignpc4(0)) | (first4B & alignpc4(1))
|
||||
|
||||
io.dec_aln.aln_ib.i0_brp.bits.hist := Cat((first2B & alignhist1(0)) | (first4B & alignhist1(1)),
|
||||
(first2B & alignhist0(0)) | (first4B & alignhist0(1)))
|
||||
io.dec_aln.aln_ib.i0_brp.bits.way := Mux((first2B | alignbrend(0)).asBool, alignway(0), alignway(1))
|
||||
|
||||
val i0_ends_f1 = first4B & alignfromf1
|
||||
io.dec_aln.aln_ib.i0_brp.bits.toffset := Mux(i0_ends_f1.asBool, f1poffset, f0poffset)
|
||||
io.dec_aln.aln_ib.i0_brp.bits.hist := Cat((first2B & alignhist1(0)) | (first4B & alignhist1(1)),
|
||||
(first2B & alignhist0(0)) | (first4B & alignhist0(1)))
|
||||
|
||||
io.dec_aln.aln_ib.i0_brp.bits.prett := Mux(i0_ends_f1.asBool, f1prett, f0prett)
|
||||
val i0_ends_f1 = first4B & alignfromf1
|
||||
io.dec_aln.aln_ib.i0_brp.bits.toffset := Mux(i0_ends_f1.asBool, f1poffset, f0poffset)
|
||||
|
||||
io.dec_aln.aln_ib.i0_brp.bits.br_start_error := (first4B & alignval(1) & alignbrend(0))
|
||||
io.dec_aln.aln_ib.i0_brp.bits.prett := Mux(i0_ends_f1.asBool, f1prett, f0prett)
|
||||
|
||||
io.dec_aln.aln_ib.i0_brp.bits.bank := Mux((first2B | alignbrend(0)).asBool, firstpc(0), secondpc(0))
|
||||
io.dec_aln.aln_ib.i0_brp.bits.br_start_error := (first4B & alignval(1) & alignbrend(0))
|
||||
|
||||
io.dec_aln.aln_ib.i0_brp.bits.br_error := (io.dec_aln.aln_ib.i0_brp.valid & i0_brp_pc4 & first2B) | (io.dec_aln.aln_ib.i0_brp.valid & !i0_brp_pc4 & first4B)
|
||||
io.dec_aln.aln_ib.i0_brp.bits.bank := Mux((first2B | alignbrend(0)).asBool, firstpc(0), secondpc(0))
|
||||
|
||||
io.dec_aln.aln_ib.ifu_i0_bp_index := Mux((first2B | alignbrend(0)).asBool, firstpc_hash, secondpc_hash)
|
||||
io.dec_aln.aln_ib.ifu_i0_bp_fghr := Mux((first4B & alignfromf1).asBool, f1fghr, f0fghr)
|
||||
io.dec_aln.aln_ib.ifu_i0_bp_btag := Mux((first2B | alignbrend(0)).asBool, firstbrtag_hash, secondbrtag_hash)
|
||||
io.dec_aln.aln_ib.i0_brp.bits.br_error := (io.dec_aln.aln_ib.i0_brp.valid & i0_brp_pc4 & first2B) | (io.dec_aln.aln_ib.i0_brp.valid & !i0_brp_pc4 & first4B)
|
||||
|
||||
if(BTB_FULLYA){
|
||||
io.ifu_i0_fa_index := Mux((first2B | alignbrend(0)).asBool, alignindex(0), alignindex(1))
|
||||
}else{
|
||||
io.ifu_i0_fa_index := 0.U
|
||||
}
|
||||
}else{
|
||||
io.dec_aln.aln_ib.ifu_i0_bp_index := 0.U
|
||||
io.dec_aln.aln_ib.ifu_i0_bp_fghr := 0.U
|
||||
io.dec_aln.aln_ib.ifu_i0_bp_btag := 0.U
|
||||
io.dec_aln.aln_ib.i0_brp := 0.U.asTypeOf(io.dec_aln.aln_ib.i0_brp)
|
||||
}
|
||||
io.dec_aln.aln_ib.ifu_i0_bp_index := Mux((first2B | alignbrend(0)).asBool, firstpc_hash, secondpc_hash)
|
||||
|
||||
io.dec_aln.aln_ib.ifu_i0_bp_fghr := Mux((first4B & alignfromf1).asBool, f1fghr, f0fghr)
|
||||
|
||||
io.dec_aln.aln_ib.ifu_i0_bp_btag := Mux((first2B | alignbrend(0)).asBool, firstbrtag_hash, secondbrtag_hash)
|
||||
|
||||
decompressed.io.din := Mux(first2B.asBool(),aligndata,0.U)
|
||||
decompressed.io.din := aligndata
|
||||
|
||||
val i0_shift = io.dec_i0_decode_d & !error_stall
|
||||
val i0_shift = io.dec_aln.aln_dec.dec_i0_decode_d & ~error_stall
|
||||
|
||||
io.dec_aln.ifu_pmu_instr_aligned := i0_shift
|
||||
|
||||
shift_2B := i0_shift & first2B
|
||||
shift_4B := i0_shift & first4B
|
||||
////
|
||||
|
||||
f0_shift_2B := Mux1H(Seq(shift_2B.asBool -> f0val(0), shift_4B.asBool -> (f0val(0) & !f0val(1))))
|
||||
f1_shift_2B := f0val(0) & !f0val(1) & shift_4B
|
||||
|
||||
}
|
||||
//object Aligner extends App {
|
||||
// (new chisel3.stage.ChiselStage).emitVerilog(new ifu_aln_ctl())
|
||||
//}
|
|
@ -9,73 +9,52 @@ import chisel3.experimental.chiselName
|
|||
@chiselName
|
||||
class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
||||
val io = IO (new Bundle {
|
||||
val ic_hit_f = Input(Bool())
|
||||
val exu_flush_final = Input(Bool())
|
||||
val ifc_fetch_addr_f = Input(UInt(31.W))
|
||||
val ifc_fetch_req_f = Input(Bool()) // Fetch request generated by the IFC
|
||||
val dec_bp = new dec_bp()
|
||||
val active_clk = Input(Clock())
|
||||
val ic_hit_f = Input(Bool())
|
||||
val exu_flush_final = Input(Bool())
|
||||
val ifc_fetch_addr_f = Input(UInt(31.W))
|
||||
val ifc_fetch_req_f = Input(Bool()) // Fetch request generated by the IFC
|
||||
val dec_bp = new dec_bp()
|
||||
val dec_tlu_flush_lower_wb = Input(Bool())
|
||||
val exu_bp = Flipped(new exu_bp())
|
||||
val dec_fa_error_index = Input(UInt(log2Ceil(BTB_SIZE).W))// Fully associative btb error index
|
||||
val ifu_bp_hit_taken_f = Output(Bool())
|
||||
val ifu_bp_btb_target_f = Output(UInt(31.W))
|
||||
val ifu_bp_inst_mask_f = Output(Bool())
|
||||
val ifu_bp_fghr_f = Output(UInt(BHT_GHR_SIZE.W))
|
||||
val ifu_bp_way_f = Output(UInt(2.W))
|
||||
val ifu_bp_ret_f = Output(UInt(2.W))
|
||||
val ifu_bp_hist1_f = Output(UInt(2.W))
|
||||
val ifu_bp_hist0_f = Output(UInt(2.W))
|
||||
val ifu_bp_pc4_f = Output(UInt(2.W))
|
||||
val ifu_bp_valid_f = Output(UInt(2.W))
|
||||
val ifu_bp_poffset_f = Output(UInt(12.W))
|
||||
val ifu_bp_fa_index_f = Output(Vec(2,UInt(log2Ceil(BTB_SIZE).W)))// predicted branch index (fully associative option)
|
||||
val scan_mode = Input(Bool())
|
||||
val exu_bp = Flipped(new exu_bp())
|
||||
val ifu_bp_hit_taken_f = Output(Bool())
|
||||
val ifu_bp_btb_target_f = Output(UInt(31.W))
|
||||
val ifu_bp_inst_mask_f = Output(Bool())
|
||||
val ifu_bp_fghr_f = Output(UInt(BHT_GHR_SIZE.W))
|
||||
val ifu_bp_way_f = Output(UInt(2.W))
|
||||
val ifu_bp_ret_f = Output(UInt(2.W))
|
||||
val ifu_bp_hist1_f = Output(UInt(2.W))
|
||||
val ifu_bp_hist0_f = Output(UInt(2.W))
|
||||
val ifu_bp_pc4_f = Output(UInt(2.W))
|
||||
val ifu_bp_valid_f = Output(UInt(2.W))
|
||||
val ifu_bp_poffset_f = Output(UInt(12.W))
|
||||
val scan_mode = Input(Bool())
|
||||
})
|
||||
io.ifu_bp_fa_index_f := io.ifu_bp_fa_index_f.map(i=> 0.U)
|
||||
val BTB_DWIDTH = BTB_TOFFSET_SIZE+ BTB_BTAG_SIZE + 5
|
||||
val BTB_DWIDTH_TOP = BTB_TOFFSET_SIZE + BTB_BTAG_SIZE + 4
|
||||
val BTB_FA_INDEX = log2Ceil(BTB_SIZE) - 1
|
||||
val FA_CMP_LOWER = log2Ceil(ICACHE_LN_SZ)
|
||||
val FA_TAG_END_UPPER = 5 + BTB_TOFFSET_SIZE + FA_CMP_LOWER - 1 // must cast to int or vcs build fails
|
||||
val FA_TAG_START_LOWER =3 + BTB_TOFFSET_SIZE + FA_CMP_LOWER
|
||||
val FA_TAG_END_LOWER = 5 + BTB_TOFFSET_SIZE
|
||||
|
||||
val TAG_START = BTB_DWIDTH - 1
|
||||
val PC4 = 4 // Branch = pc + 4 (BTB Index)
|
||||
val BOFF = 3 // Branch offset (BTB Index)
|
||||
val CALL = 2 // Branch CALL (BTB Index)
|
||||
val RET = 1 // Branch RET (BTB Index)
|
||||
val BV = 0 // Branch Valid (BTB Index)
|
||||
val TAG_START = 16+BTB_BTAG_SIZE
|
||||
val PC4 = 4 // Branch = pc + 4 (BTB Index)
|
||||
val BOFF = 3 // Branch offset (BTB Index)
|
||||
val CALL = 2 // Branch CALL (BTB Index)
|
||||
val RET = 1 // Branch RET (BTB Index)
|
||||
val BV = 0 // Branch Valid (BTB Index)
|
||||
|
||||
val LRU_SIZE = BTB_ARRAY_DEPTH
|
||||
val NUM_BHT_LOOP = if(BHT_ARRAY_DEPTH > 16) 16 else BHT_ARRAY_DEPTH
|
||||
val LRU_SIZE = BTB_ARRAY_DEPTH
|
||||
val NUM_BHT_LOOP = if(BHT_ARRAY_DEPTH > 16) 16 else BHT_ARRAY_DEPTH
|
||||
val NUM_BHT_LOOP_INNER_HI = if(BHT_ARRAY_DEPTH > 16) BHT_ADDR_LO+3 else BHT_ADDR_HI
|
||||
val NUM_BHT_LOOP_OUTER_LO = if(BHT_ARRAY_DEPTH > 16) BHT_ADDR_LO+4 else BHT_ADDR_LO
|
||||
val BHT_NO_ADDR_MATCH = BHT_ARRAY_DEPTH <= 16
|
||||
val BHT_NO_ADDR_MATCH = BHT_ARRAY_DEPTH <= 16
|
||||
/////////////////////////////////////////////////////////
|
||||
val leak_one_f = WireInit(Bool(), 0.U)
|
||||
val leak_one_f_d1 = WireInit(Bool(), 0.U)
|
||||
val bht_dir_f = WireInit(UInt(2.W), 0.U)
|
||||
val dec_tlu_error_wb = WireInit(Bool(), 0.U)
|
||||
val leak_one_f = WireInit(Bool(), 0.U)
|
||||
val bht_dir_f = WireInit(UInt(2.W), 0.U)
|
||||
val dec_tlu_error_wb = WireInit(Bool(), 0.U)
|
||||
val btb_error_addr_wb = WireInit(UInt((BTB_ADDR_HI-BTB_ADDR_LO+1).W), 0.U)
|
||||
|
||||
val btb_vbank0_rd_data_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
|
||||
val btb_vbank1_rd_data_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
|
||||
val btb_bank0_rd_data_way0_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
|
||||
val btb_bank0_rd_data_way1_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
|
||||
val btb_bank0_rd_data_way0_p1_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
|
||||
val btb_bank0_rd_data_way1_p1_f = WireInit(UInt((BTB_DWIDTH).W), 0.U)
|
||||
val eoc_mask = WireInit(Bool(), 0.U)
|
||||
val btb_lru_b0_f = WireInit(UInt(LRU_SIZE.W), init = 0.U)
|
||||
val dec_tlu_way_wb = WireInit(Bool(), 0.U)
|
||||
|
||||
val btb_vlru_rd_f = WireInit(UInt(2.W), 0.U)
|
||||
val vwayhit_f = WireInit(UInt(2.W), 0.U)
|
||||
val tag_match_vway1_expanded_f = WireInit(UInt(2.W), 0.U)
|
||||
val wayhit_f = WireInit(UInt(2.W), 0.U)
|
||||
val wayhit_p1_f = WireInit(UInt(2.W), 0.U)
|
||||
val way_raw = WireInit(UInt(2.W), 0.U)
|
||||
val exu_flush_final_d1 = WireInit(Bool(), 0.U)
|
||||
val btb_bank0_rd_data_way0_f = WireInit(UInt((TAG_START+1).W), 0.U)
|
||||
val btb_bank0_rd_data_way1_f = WireInit(UInt((TAG_START+1).W), 0.U)
|
||||
val btb_bank0_rd_data_way0_p1_f = WireInit(UInt((TAG_START+1).W), 0.U)
|
||||
val btb_bank0_rd_data_way1_p1_f = WireInit(UInt((TAG_START+1).W), 0.U)
|
||||
val eoc_mask = WireInit(Bool(), 0.U)
|
||||
val btb_lru_b0_f = WireInit(UInt(LRU_SIZE.W), init = 0.U)
|
||||
val dec_tlu_way_wb = WireInit(Bool(), 0.U)
|
||||
/////////////////////////////////////////////////////////
|
||||
// Misprediction packet
|
||||
val exu_mp_valid = io.exu_bp.exu_mp_pkt.bits.misp & !leak_one_f
|
||||
|
@ -89,7 +68,6 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
|||
val exu_mp_tgt = io.exu_bp.exu_mp_pkt.bits.toffset
|
||||
val exu_mp_addr = io.exu_bp.exu_mp_index
|
||||
val exu_mp_ataken = io.exu_bp.exu_mp_pkt.bits.ataken
|
||||
val exu_mp_way_f = WireInit(Bool(), 0.U)
|
||||
|
||||
// Its a commit or update packet
|
||||
val dec_tlu_br0_v_wb = io.dec_bp.dec_tlu_br0_r_pkt.valid
|
||||
|
@ -129,132 +107,139 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
|||
val branch_error_bank_conflict_p1_f = branch_error_collision_p1_f & dec_tlu_error_wb
|
||||
|
||||
// Hashing the PC to generate the index for the btb
|
||||
val fetch_rd_tag_f = if(BTB_BTAG_FOLD) btb_tag_hash_fold(io.ifc_fetch_addr_f) else btb_tag_hash(io.ifc_fetch_addr_f)
|
||||
val fetch_rd_tag_p1_f = if(BTB_BTAG_FOLD) btb_tag_hash_fold(Cat(fetch_addr_p1_f,0.U)) else btb_tag_hash(Cat(fetch_addr_p1_f,0.U))
|
||||
|
||||
// There is a misprediction and the exu is writing back
|
||||
val fetch_mp_collision_f = (io.exu_bp.exu_mp_btag === fetch_rd_tag_f) & exu_mp_valid & io.ifc_fetch_req_f & (exu_mp_addr === btb_rd_addr_f)
|
||||
val fetch_mp_collision_p1_f = (io.exu_bp.exu_mp_btag === fetch_rd_tag_p1_f) & exu_mp_valid & io.ifc_fetch_req_f & (exu_mp_addr === btb_rd_addr_p1_f)
|
||||
|
||||
val leak_one_f_d1 = withClock(io.active_clk) {RegNext(leak_one_f, init = 0.U)}
|
||||
val dec_tlu_way_wb_f = withClock(io.active_clk) {RegNext(dec_tlu_way_wb, init = 0.U)}
|
||||
val exu_mp_way_f = withClock(io.active_clk) {RegNext(exu_mp_way, init = 0.U)}
|
||||
val exu_flush_final_d1 = withClock(io.active_clk) {RegNext(io.exu_flush_final, init = 0.U)}
|
||||
|
||||
// If there is a flush from the lower pipe wait until the flush gets deasserted from the (decode) side
|
||||
leak_one_f := (io.dec_bp.dec_tlu_flush_leak_one_wb & io.dec_tlu_flush_lower_wb) | (leak_one_f_d1 & !io.dec_tlu_flush_lower_wb)
|
||||
if(!BTB_FULLYA) {
|
||||
val fetch_rd_tag_f = if (BTB_BTAG_FOLD) btb_tag_hash_fold(io.ifc_fetch_addr_f) else btb_tag_hash(io.ifc_fetch_addr_f)
|
||||
val fetch_rd_tag_p1_f = if (BTB_BTAG_FOLD) btb_tag_hash_fold(Cat(fetch_addr_p1_f, 0.U)) else btb_tag_hash(Cat(fetch_addr_p1_f, 0.U))
|
||||
// There is a misprediction and the exu is writing back
|
||||
val fetch_mp_collision_f = (io.exu_bp.exu_mp_btag === fetch_rd_tag_f) & exu_mp_valid & io.ifc_fetch_req_f & (exu_mp_addr === btb_rd_addr_f)
|
||||
val fetch_mp_collision_p1_f = (io.exu_bp.exu_mp_btag === fetch_rd_tag_p1_f) & exu_mp_valid & io.ifc_fetch_req_f & (exu_mp_addr === btb_rd_addr_p1_f)
|
||||
// For a tag to match the branch should be valid tag should match and a fetch request should be generated
|
||||
// Also there should be no bank conflict or leak-one
|
||||
val tag_match_way0_f = btb_bank0_rd_data_way0_f(BV) & (btb_bank0_rd_data_way0_f(TAG_START, 17) === fetch_rd_tag_f) &
|
||||
!(dec_tlu_way_wb & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
|
||||
|
||||
// Similar to the way-0 -> way-1
|
||||
val tag_match_way1_f = btb_bank0_rd_data_way1_f(BV) & (btb_bank0_rd_data_way1_f(TAG_START, 17) === fetch_rd_tag_f) &
|
||||
!(dec_tlu_way_wb & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
|
||||
// For a tag to match the branch should be valid tag should match and a fetch request should be generated
|
||||
// Also there should be no bank conflict or leak-one
|
||||
val tag_match_way0_f = btb_bank0_rd_data_way0_f(BV) & (btb_bank0_rd_data_way0_f(TAG_START,17) === fetch_rd_tag_f) &
|
||||
!(dec_tlu_way_wb_f & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
|
||||
|
||||
// Similar to above matches
|
||||
val tag_match_way0_p1_f = btb_bank0_rd_data_way0_p1_f(BV) & (btb_bank0_rd_data_way0_p1_f(TAG_START, 17) === fetch_rd_tag_p1_f) &
|
||||
!(dec_tlu_way_wb & branch_error_bank_conflict_p1_f) & io.ifc_fetch_req_f & !leak_one_f
|
||||
// Similar to above matches
|
||||
val tag_match_way1_p1_f = btb_bank0_rd_data_way1_p1_f(BV) & (btb_bank0_rd_data_way1_p1_f(TAG_START, 17) === fetch_rd_tag_p1_f) &
|
||||
!(dec_tlu_way_wb & branch_error_bank_conflict_p1_f) & io.ifc_fetch_req_f & !leak_one_f
|
||||
// Similar to the way-0 -> way-1
|
||||
val tag_match_way1_f = btb_bank0_rd_data_way1_f(BV) & (btb_bank0_rd_data_way1_f(TAG_START,17) === fetch_rd_tag_f) &
|
||||
!(dec_tlu_way_wb_f & branch_error_bank_conflict_f) & io.ifc_fetch_req_f & !leak_one_f
|
||||
|
||||
// Reordering to avoid multiple hit
|
||||
val tag_match_way0_expanded_f = Cat(tag_match_way0_f & (btb_bank0_rd_data_way0_f(BOFF) ^ btb_bank0_rd_data_way0_f(PC4)),
|
||||
tag_match_way0_f & !(btb_bank0_rd_data_way0_f(BOFF) ^ btb_bank0_rd_data_way0_f(PC4)))
|
||||
// Similar to above matches
|
||||
val tag_match_way0_p1_f = btb_bank0_rd_data_way0_p1_f(BV) & (btb_bank0_rd_data_way0_p1_f(TAG_START,17) === fetch_rd_tag_p1_f) &
|
||||
!(dec_tlu_way_wb_f & branch_error_bank_conflict_p1_f) & io.ifc_fetch_req_f & !leak_one_f
|
||||
// Similar to above matches
|
||||
val tag_match_way1_p1_f = btb_bank0_rd_data_way1_p1_f(BV) & (btb_bank0_rd_data_way1_p1_f(TAG_START,17) === fetch_rd_tag_p1_f) &
|
||||
!(dec_tlu_way_wb_f & branch_error_bank_conflict_p1_f) & io.ifc_fetch_req_f & !leak_one_f
|
||||
|
||||
val tag_match_way1_expanded_f = Cat(tag_match_way1_f & (btb_bank0_rd_data_way1_f(BOFF) ^ btb_bank0_rd_data_way1_f(PC4)),
|
||||
tag_match_way1_f & !(btb_bank0_rd_data_way1_f(BOFF) ^ btb_bank0_rd_data_way1_f(PC4)))
|
||||
// Reordering to avoid multiple hit
|
||||
val tag_match_way0_expanded_f = Cat(tag_match_way0_f & (btb_bank0_rd_data_way0_f(BOFF) ^ btb_bank0_rd_data_way0_f(PC4)),
|
||||
tag_match_way0_f & !(btb_bank0_rd_data_way0_f(BOFF) ^ btb_bank0_rd_data_way0_f(PC4)))
|
||||
|
||||
val tag_match_way0_expanded_p1_f = Cat(tag_match_way0_p1_f & (btb_bank0_rd_data_way0_p1_f(BOFF) ^ btb_bank0_rd_data_way0_p1_f(PC4)),
|
||||
tag_match_way0_p1_f & !(btb_bank0_rd_data_way0_p1_f(BOFF) ^ btb_bank0_rd_data_way0_p1_f(PC4)))
|
||||
val tag_match_way1_expanded_f = Cat(tag_match_way1_f & (btb_bank0_rd_data_way1_f(BOFF) ^ btb_bank0_rd_data_way1_f(PC4)),
|
||||
tag_match_way1_f & !(btb_bank0_rd_data_way1_f(BOFF) ^ btb_bank0_rd_data_way1_f(PC4)))
|
||||
|
||||
val tag_match_way1_expanded_p1_f = Cat(tag_match_way1_p1_f & (btb_bank0_rd_data_way1_p1_f(BOFF) ^ btb_bank0_rd_data_way1_p1_f(PC4)),
|
||||
tag_match_way1_p1_f & !(btb_bank0_rd_data_way1_p1_f(BOFF) ^ btb_bank0_rd_data_way1_p1_f(PC4)))
|
||||
val tag_match_way0_expanded_p1_f = Cat(tag_match_way0_p1_f & (btb_bank0_rd_data_way0_p1_f(BOFF) ^ btb_bank0_rd_data_way0_p1_f(PC4)),
|
||||
tag_match_way0_p1_f & !(btb_bank0_rd_data_way0_p1_f(BOFF) ^ btb_bank0_rd_data_way0_p1_f(PC4)))
|
||||
|
||||
// Final hit calculation
|
||||
wayhit_f := tag_match_way0_expanded_f | tag_match_way1_expanded_f
|
||||
val tag_match_way1_expanded_p1_f = Cat(tag_match_way1_p1_f & (btb_bank0_rd_data_way1_p1_f(BOFF) ^ btb_bank0_rd_data_way1_p1_f(PC4)),
|
||||
tag_match_way1_p1_f & !(btb_bank0_rd_data_way1_p1_f(BOFF) ^ btb_bank0_rd_data_way1_p1_f(PC4)))
|
||||
|
||||
wayhit_p1_f := tag_match_way0_expanded_p1_f | tag_match_way1_expanded_p1_f
|
||||
// Final hit calculation
|
||||
val wayhit_f = tag_match_way0_expanded_f | tag_match_way1_expanded_f
|
||||
|
||||
// Chopping off the ways that had a hit btb_vbank0_rd_data_f
|
||||
// e-> Lower half o-> Upper half
|
||||
val btb_bank0e_rd_data_f = Mux1H(Seq(tag_match_way0_expanded_f(0).asBool -> btb_bank0_rd_data_way0_f,
|
||||
tag_match_way1_expanded_f(0).asBool -> btb_bank0_rd_data_way1_f))
|
||||
val wayhit_p1_f = tag_match_way0_expanded_p1_f | tag_match_way1_expanded_p1_f
|
||||
|
||||
val btb_bank0o_rd_data_f = Mux1H(Seq(tag_match_way0_expanded_f(1).asBool -> btb_bank0_rd_data_way0_f,
|
||||
tag_match_way1_expanded_f(1).asBool -> btb_bank0_rd_data_way1_f))
|
||||
// Chopping off the ways that had a hit btb_vbank0_rd_data_f
|
||||
// e-> Lower half o-> Upper half
|
||||
val btb_bank0e_rd_data_f = Mux1H(Seq(tag_match_way0_expanded_f(0).asBool->btb_bank0_rd_data_way0_f,
|
||||
tag_match_way1_expanded_f(0).asBool->btb_bank0_rd_data_way1_f))
|
||||
|
||||
val btb_bank0e_rd_data_p1_f = Mux1H(Seq(tag_match_way0_expanded_p1_f(0).asBool -> btb_bank0_rd_data_way0_p1_f,
|
||||
tag_match_way1_expanded_p1_f(0).asBool -> btb_bank0_rd_data_way1_p1_f))
|
||||
val btb_bank0o_rd_data_f = Mux1H(Seq(tag_match_way0_expanded_f(1).asBool->btb_bank0_rd_data_way0_f,
|
||||
tag_match_way1_expanded_f(1).asBool->btb_bank0_rd_data_way1_f))
|
||||
|
||||
// Making virtual banks, made from pc-bit(1) if it comes from a multiple of 4 we get the lower half of the bank
|
||||
// and the upper half of the bank-0 in vbank 1
|
||||
btb_vbank0_rd_data_f := Mux1H(Seq(!io.ifc_fetch_addr_f(0) -> btb_bank0e_rd_data_f,
|
||||
io.ifc_fetch_addr_f(0) -> btb_bank0o_rd_data_f))
|
||||
btb_vbank1_rd_data_f := Mux1H(Seq(!io.ifc_fetch_addr_f(0) -> btb_bank0o_rd_data_f,
|
||||
io.ifc_fetch_addr_f(0) -> btb_bank0e_rd_data_p1_f))
|
||||
val btb_bank0e_rd_data_p1_f = Mux1H(Seq(tag_match_way0_expanded_p1_f(0).asBool->btb_bank0_rd_data_way0_p1_f,
|
||||
tag_match_way1_expanded_p1_f(0).asBool->btb_bank0_rd_data_way1_p1_f))
|
||||
|
||||
way_raw := tag_match_vway1_expanded_f | (~vwayhit_f & btb_vlru_rd_f)
|
||||
// Making virtual banks, made from pc-bit(1) if it comes from a multiple of 4 we get the lower half of the bank
|
||||
// and the upper half of the bank-0 in vbank 1
|
||||
val btb_vbank0_rd_data_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0)->btb_bank0e_rd_data_f,
|
||||
io.ifc_fetch_addr_f(0)->btb_bank0o_rd_data_f))
|
||||
val btb_vbank1_rd_data_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0)->btb_bank0o_rd_data_f,
|
||||
io.ifc_fetch_addr_f(0)->btb_bank0e_rd_data_p1_f))
|
||||
|
||||
// Branch prediction info is sent with the 2byte lane associated with the end of the branch.
|
||||
// Cases
|
||||
// BANK1 BANK0
|
||||
// -------------------------------
|
||||
// | : | : |
|
||||
// -------------------------------
|
||||
// <------------> : PC4 branch, offset, should be in B1 (indicated on [2])
|
||||
// <------------> : PC4 branch, no offset, indicate PC4, VALID, HIST on [1]
|
||||
// <------------> : PC4 branch, offset, indicate PC4, VALID, HIST on [0]
|
||||
// <------> : PC2 branch, offset, indicate VALID, HIST on [1]
|
||||
// <------> : PC2 branch, no offset, indicate VALID, HIST on [0]
|
||||
// Branch prediction info is sent with the 2byte lane associated with the end of the branch.
|
||||
// Cases
|
||||
// BANK1 BANK0
|
||||
// -------------------------------
|
||||
// | : | : |
|
||||
// -------------------------------
|
||||
// <------------> : PC4 branch, offset, should be in B1 (indicated on [2])
|
||||
// <------------> : PC4 branch, no offset, indicate PC4, VALID, HIST on [1]
|
||||
// <------------> : PC4 branch, offset, indicate PC4, VALID, HIST on [0]
|
||||
// <------> : PC2 branch, offset, indicate VALID, HIST on [1]
|
||||
// <------> : PC2 branch, no offset, indicate VALID, HIST on [0]
|
||||
|
||||
|
||||
// Make an LRU value with execution mis-prediction
|
||||
val mp_wrindex_dec = 1.U << exu_mp_addr
|
||||
// Make an LRU value with execution mis-prediction
|
||||
val mp_wrindex_dec = 1.U << exu_mp_addr
|
||||
|
||||
// Make an LRU value with current read pc
|
||||
val fetch_wrindex_dec = 1.U << btb_rd_addr_f
|
||||
// Make an LRU value with current read pc
|
||||
val fetch_wrindex_dec = 1.U << btb_rd_addr_f
|
||||
|
||||
// Make an LRU value with current read pc + 4
|
||||
val fetch_wrindex_p1_dec = 1.U << btb_rd_addr_p1_f
|
||||
// Make an LRU value with current read pc + 4
|
||||
val fetch_wrindex_p1_dec = 1.U << btb_rd_addr_p1_f
|
||||
|
||||
// Checking if the mis-prediction was valid or not and make a new LRU value
|
||||
val mp_wrlru_b0 = mp_wrindex_dec & Fill(LRU_SIZE, exu_mp_valid)
|
||||
// Checking if the mis-prediction was valid or not and make a new LRU value
|
||||
val mp_wrlru_b0 = mp_wrindex_dec & Fill(LRU_SIZE, exu_mp_valid)
|
||||
|
||||
// Is the update of the lru valid or not
|
||||
val lru_update_valid_f = (vwayhit_f(0) | vwayhit_f(1)) & io.ifc_fetch_req_f & !leak_one_f
|
||||
val vwayhit_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool->wayhit_f,
|
||||
io.ifc_fetch_addr_f(0).asBool->Cat(wayhit_p1_f(0), wayhit_f(1)))) & Cat(eoc_mask, 1.U(1.W))
|
||||
|
||||
val fetch_wrlru_b0 = fetch_wrindex_dec & Fill(LRU_SIZE, lru_update_valid_f)
|
||||
val fetch_wrlru_p1_b0 = fetch_wrindex_p1_dec & Fill(LRU_SIZE, lru_update_valid_f)
|
||||
// Is the update of the lru valid or not
|
||||
val lru_update_valid_f = (vwayhit_f(0) | vwayhit_f(1)) & io.ifc_fetch_req_f & !leak_one_f
|
||||
|
||||
val btb_lru_b0_hold = ~mp_wrlru_b0 & ~fetch_wrlru_b0
|
||||
val fetch_wrlru_b0 = fetch_wrindex_dec & Fill(LRU_SIZE, lru_update_valid_f)
|
||||
val fetch_wrlru_p1_b0 = fetch_wrindex_p1_dec & Fill(LRU_SIZE, lru_update_valid_f)
|
||||
|
||||
// If there is a collision the use the mis-predicted value as output and update accordingly
|
||||
val use_mp_way = fetch_mp_collision_f
|
||||
val use_mp_way_p1 = fetch_mp_collision_p1_f
|
||||
val btb_lru_b0_hold = ~mp_wrlru_b0 & ~fetch_wrlru_b0
|
||||
|
||||
// Calculate the lru next value and flop it
|
||||
val btb_lru_b0_ns: UInt = Mux1H(Seq(!exu_mp_way.asBool -> mp_wrlru_b0,
|
||||
tag_match_way0_f.asBool -> fetch_wrlru_b0,
|
||||
tag_match_way0_p1_f.asBool -> fetch_wrlru_p1_b0)) | btb_lru_b0_hold & btb_lru_b0_f
|
||||
// If there is a collision the use the mis-predicted value as output and update accordingly
|
||||
val use_mp_way = fetch_mp_collision_f
|
||||
val use_mp_way_p1 = fetch_mp_collision_p1_f
|
||||
|
||||
// Calculate the lru next value and flop it
|
||||
val btb_lru_b0_ns : UInt = Mux1H(Seq(!exu_mp_way.asBool -> mp_wrlru_b0,
|
||||
tag_match_way0_f.asBool -> fetch_wrlru_b0,
|
||||
tag_match_way0_p1_f.asBool -> fetch_wrlru_p1_b0)) | btb_lru_b0_hold & btb_lru_b0_f
|
||||
|
||||
|
||||
val btb_lru_rd_f = Mux(use_mp_way.asBool, exu_mp_way_f, (fetch_wrindex_dec & btb_lru_b0_f).orR)
|
||||
val btb_lru_rd_f = Mux(use_mp_way.asBool, exu_mp_way_f, (fetch_wrindex_dec & btb_lru_b0_f).orR)
|
||||
|
||||
val btb_lru_rd_p1_f = Mux(use_mp_way_p1.asBool, exu_mp_way_f, (fetch_wrindex_p1_dec & btb_lru_b0_f).orR)
|
||||
val btb_lru_rd_p1_f = Mux(use_mp_way_p1.asBool, exu_mp_way_f, (fetch_wrindex_p1_dec & btb_lru_b0_f).orR)
|
||||
|
||||
// Similar to the vbank make vlru
|
||||
btb_vlru_rd_f := Mux1H(Seq(!io.ifc_fetch_addr_f(0) -> Cat(btb_lru_rd_f, btb_lru_rd_f),
|
||||
io.ifc_fetch_addr_f(0).asBool -> Cat(btb_lru_rd_p1_f, btb_lru_rd_f)))
|
||||
// Similar to the vbank make vlru
|
||||
val btb_vlru_rd_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0) -> Cat(btb_lru_rd_f, btb_lru_rd_f),
|
||||
io.ifc_fetch_addr_f(0).asBool -> Cat(btb_lru_rd_p1_f, btb_lru_rd_f)))
|
||||
|
||||
// virtual way depending on pc value
|
||||
tag_match_vway1_expanded_f := Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool -> tag_match_way1_expanded_f,
|
||||
io.ifc_fetch_addr_f(0).asBool -> Cat(tag_match_way1_expanded_p1_f(0), tag_match_way1_expanded_f(1))))
|
||||
// virtual way depending on pc value
|
||||
val tag_match_vway1_expanded_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool->tag_match_way1_expanded_f,
|
||||
io.ifc_fetch_addr_f(0).asBool->Cat(tag_match_way1_expanded_p1_f(0),tag_match_way1_expanded_f(1))))
|
||||
|
||||
btb_lru_b0_f := rvdffe(btb_lru_b0_ns, (io.ifc_fetch_req_f|exu_mp_valid).asBool, clock, io.scan_mode)
|
||||
}
|
||||
io.ifu_bp_way_f := tag_match_vway1_expanded_f | (~vwayhit_f & btb_vlru_rd_f)
|
||||
|
||||
io.ifu_bp_way_f := way_raw
|
||||
// update the lru
|
||||
//io.test := btb_lru_b0_ns
|
||||
btb_lru_b0_f := rvdffe(btb_lru_b0_ns, (io.ifc_fetch_req_f|exu_mp_valid).asBool, clock, io.scan_mode)
|
||||
//io.test := btb_lru_b0_ns
|
||||
// Checking if the end of line is near
|
||||
val eoc_near = io.ifc_fetch_addr_f(ICACHE_BEAT_ADDR_HI-1, 2).andR
|
||||
|
||||
// Mask according to eoc-near and make the hit-final
|
||||
eoc_mask := !eoc_near | (~io.ifc_fetch_addr_f(1,0)).orR()
|
||||
|
||||
|
@ -270,32 +255,31 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
|||
|
||||
// This is 1-index shifted to that of the btb-data-read so we have 1-bit shifted
|
||||
btb_sel_data_f := Mux1H(Seq(btb_sel_f(1).asBool-> btb_vbank1_rd_data_f(16,1),
|
||||
btb_sel_f(0).asBool-> btb_vbank0_rd_data_f(16,1)))
|
||||
btb_sel_f(0).asBool-> btb_vbank0_rd_data_f(16,1)))
|
||||
|
||||
// No lower flush or bp-disabple and a fetch request is generated with virtual way hit
|
||||
io.ifu_bp_hit_taken_f := (vwayhit_f & hist1_raw).orR & io.ifc_fetch_req_f & !leak_one_f_d1 & !io.dec_bp.dec_tlu_bpred_disable
|
||||
|
||||
// If the prediction is a call or ret btb entry then do not check the bht just force a taken with data from the RAS
|
||||
val bht_force_taken_f = Cat( btb_vbank1_rd_data_f(CALL) | btb_vbank1_rd_data_f(RET) ,
|
||||
btb_vbank0_rd_data_f(CALL) | btb_vbank0_rd_data_f(RET))
|
||||
btb_vbank0_rd_data_f(CALL) | btb_vbank0_rd_data_f(RET))
|
||||
|
||||
val bht_valid_f = vwayhit_f
|
||||
|
||||
val bht_bank1_rd_data_f =WireInit(UInt(2.W), 0.U)
|
||||
val bht_bank0_rd_data_f =WireInit(UInt(2.W), 0.U)
|
||||
val bht_bank0_rd_data_p1_f =WireInit(UInt(2.W), 0.U)
|
||||
|
||||
|
||||
// Depending on pc make the virtual bank as commented above
|
||||
val bht_vbank0_rd_data_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool->bht_bank0_rd_data_f,
|
||||
io.ifc_fetch_addr_f(0).asBool->bht_bank1_rd_data_f))
|
||||
io.ifc_fetch_addr_f(0).asBool->bht_bank1_rd_data_f))
|
||||
|
||||
val bht_vbank1_rd_data_f = Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool->bht_bank1_rd_data_f,
|
||||
io.ifc_fetch_addr_f(0).asBool->bht_bank0_rd_data_p1_f))
|
||||
|
||||
io.ifc_fetch_addr_f(0).asBool->bht_bank0_rd_data_p1_f))
|
||||
|
||||
// Direction containing data of both banks direction
|
||||
bht_dir_f := Cat((bht_force_taken_f(1) | bht_vbank1_rd_data_f(1)) & bht_valid_f(1),
|
||||
(bht_force_taken_f(0) | bht_vbank0_rd_data_f(1)) & bht_valid_f(0))
|
||||
(bht_force_taken_f(0) | bht_vbank0_rd_data_f(1)) & bht_valid_f(0))
|
||||
|
||||
// If the branch is taken then pass btb sel else 0
|
||||
io.ifu_bp_inst_mask_f := (io.ifu_bp_hit_taken_f & btb_sel_f(1)) | !io.ifu_bp_hit_taken_f
|
||||
|
@ -308,11 +292,11 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
|||
|
||||
// pc4: if the branch is pc+4
|
||||
val pc4_raw = Cat(vwayhit_f(1) & btb_vbank1_rd_data_f(PC4),
|
||||
vwayhit_f(0) & btb_vbank0_rd_data_f(PC4))
|
||||
vwayhit_f(0) & btb_vbank0_rd_data_f(PC4))
|
||||
|
||||
// Its a call call or ret branch
|
||||
val pret_raw = Cat(vwayhit_f(1) & !btb_vbank1_rd_data_f(CALL) & btb_vbank1_rd_data_f(RET),
|
||||
vwayhit_f(0) & !btb_vbank0_rd_data_f(CALL) & btb_vbank0_rd_data_f(RET))
|
||||
vwayhit_f(0) & !btb_vbank0_rd_data_f(CALL) & btb_vbank0_rd_data_f(RET))
|
||||
|
||||
// count number of 1's in bht_valid
|
||||
val num_valids = bht_valid_f(1) +& bht_valid_f(0)
|
||||
|
@ -323,8 +307,8 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
|||
val fghr = WireInit(UInt(BHT_GHR_SIZE.W), 0.U)
|
||||
|
||||
val merged_ghr = Mux1H(Seq((num_valids===2.U).asBool->Cat(fghr(BHT_GHR_SIZE-3,0), 0.U, final_h),
|
||||
(num_valids===1.U).asBool->Cat(fghr(BHT_GHR_SIZE-2,0), final_h),
|
||||
(num_valids===0.U).asBool->Cat(fghr(BHT_GHR_SIZE-1,0))))
|
||||
(num_valids===1.U).asBool->Cat(fghr(BHT_GHR_SIZE-2,0), final_h),
|
||||
(num_valids===0.U).asBool->Cat(fghr(BHT_GHR_SIZE-1,0))))
|
||||
|
||||
val exu_flush_ghr = io.exu_bp.exu_mp_fghr
|
||||
val fghr_ns = Wire(UInt(BHT_GHR_SIZE.W))
|
||||
|
@ -333,13 +317,10 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
|||
// If there is a hit and a fetch then use the merged-ghr
|
||||
// If there is no hit or fetch then hold value
|
||||
fghr_ns := Mux1H(Seq(exu_flush_final_d1.asBool->exu_flush_ghr,
|
||||
(!exu_flush_final_d1 & io.ifc_fetch_req_f & io.ic_hit_f & !leak_one_f_d1).asBool -> merged_ghr,
|
||||
(!exu_flush_final_d1 & !(io.ifc_fetch_req_f & io.ic_hit_f & !leak_one_f_d1)).asBool -> fghr))
|
||||
leak_one_f_d1 := rvdffie(leak_one_f,clock,reset.asAsyncReset(),io.scan_mode)
|
||||
//val dec_tlu_way_wb_f = withClock(io.active_clk) {RegNext(dec_tlu_way_wb, init = 0.U)
|
||||
exu_mp_way_f := rvdffie(exu_mp_way,clock,reset.asAsyncReset(),io.scan_mode)
|
||||
exu_flush_final_d1 := rvdffie(io.exu_flush_final,clock,reset.asAsyncReset(),io.scan_mode)
|
||||
fghr := rvdffie(fghr_ns,clock,reset.asAsyncReset(),io.scan_mode)
|
||||
(!exu_flush_final_d1 & io.ifc_fetch_req_f & io.ic_hit_f & !leak_one_f_d1).asBool -> merged_ghr,
|
||||
(!exu_flush_final_d1 & !(io.ifc_fetch_req_f & io.ic_hit_f & !leak_one_f_d1)).asBool -> fghr))
|
||||
|
||||
fghr := withClock(io.active_clk) {RegNext(fghr_ns, init = 0.U)}
|
||||
|
||||
io.ifu_bp_fghr_f := fghr
|
||||
io.ifu_bp_hist1_f := hist1_raw
|
||||
|
@ -351,27 +332,31 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
|||
|
||||
// block fetch to calculate if there is a hit with fetch request and a taken branch then compute the branch offset
|
||||
val bloc_f = Cat((bht_dir_f(0) & !fetch_start_f(0)) | (!bht_dir_f(0) & fetch_start_f(0)),
|
||||
(bht_dir_f(0) & fetch_start_f(0)) | (!bht_dir_f(0) & !fetch_start_f(0)))
|
||||
(bht_dir_f(0) & fetch_start_f(0)) | (!bht_dir_f(0) & !fetch_start_f(0)))
|
||||
|
||||
val use_fa_plus = !bht_dir_f(0) & io.ifc_fetch_addr_f(0) & !btb_rd_pc4_f
|
||||
|
||||
val btb_fg_crossing_f = fetch_start_f(0) & btb_sel_f(0) & btb_rd_pc4_f
|
||||
val bp_total_branch_offset_f = bloc_f(1)^btb_rd_pc4_f
|
||||
val ifc_fetch_adder_prior = rvdfflie_UInt(io.ifc_fetch_addr_f(30,1), clock,reset.asAsyncReset,(io.ifc_fetch_req_f & !io.ifu_bp_hit_taken_f & io.ic_hit_f).asBool,io.scan_mode,WIDTH =30, LEFT =19 )
|
||||
|
||||
val ifc_fetch_adder_prior = rvdffe(io.ifc_fetch_addr_f(30,1), (io.ifc_fetch_req_f & !io.ifu_bp_hit_taken_f & io.ic_hit_f).asBool, clock, io.scan_mode)
|
||||
|
||||
io.ifu_bp_poffset_f := btb_rd_tgt_f
|
||||
|
||||
val adder_pc_in_f = Mux1H(Seq(use_fa_plus.asBool -> fetch_addr_p1_f,
|
||||
btb_fg_crossing_f.asBool -> ifc_fetch_adder_prior,
|
||||
(!btb_fg_crossing_f & !use_fa_plus).asBool-> io.ifc_fetch_addr_f(30,1)))
|
||||
btb_fg_crossing_f.asBool -> ifc_fetch_adder_prior,
|
||||
(!btb_fg_crossing_f & !use_fa_plus).asBool-> io.ifc_fetch_addr_f(30,1)))
|
||||
|
||||
// Calculate the branch target by adding the offset
|
||||
val bp_btb_target_adder_f = rvbradder(Cat(adder_pc_in_f(29,0),bp_total_branch_offset_f, 0.U), Cat(btb_rd_tgt_f,0.U))
|
||||
|
||||
val rets_out = Wire(Vec(RET_STACK_SIZE, UInt(32.W)))
|
||||
rets_out := (0 until RET_STACK_SIZE).map(i=>0.U)
|
||||
|
||||
// Final target if its a RET then pop else take the target pc
|
||||
io.ifu_bp_btb_target_f := ((Fill(31,(btb_rd_ret_f & !btb_rd_call_f & rets_out(0)(0) & io.ifu_bp_hit_taken_f)) & rets_out(0)(31,1)) |
|
||||
(Fill(31,(!(btb_rd_ret_f & !btb_rd_call_f & rets_out(0)(0)) & io.ifu_bp_hit_taken_f)) & bp_btb_target_adder_f(31,1)))
|
||||
io.ifu_bp_btb_target_f := Mux((btb_rd_ret_f & !btb_rd_call_f & rets_out(0)(0)).asBool,
|
||||
rets_out(0)(31,1),bp_btb_target_adder_f(31,1))
|
||||
|
||||
// Return stack
|
||||
val bp_rs_call_target_f = rvbradder(Cat(adder_pc_in_f(29,0),bp_total_branch_offset_f, 0.U), Cat(Fill(11, 0.U),~btb_rd_pc4_f, 0.U))
|
||||
|
||||
|
@ -380,13 +365,14 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
|||
val rs_hold = !rs_push & !rs_pop
|
||||
|
||||
val rsenable = (0 until RET_STACK_SIZE).map(i=> if(i==0) !rs_hold else if(i==RET_STACK_SIZE-1) rs_push else rs_push | rs_pop)
|
||||
|
||||
// Make the input of the RAS
|
||||
val rets_in = (0 until RET_STACK_SIZE).map(i=> if(i==0)
|
||||
Mux1H(Seq(rs_push.asBool -> Cat(bp_rs_call_target_f(31,1),1.U),
|
||||
rs_pop.asBool -> rets_out(1)))
|
||||
else if(i==RET_STACK_SIZE-1) rets_out(i-1)
|
||||
else Mux1H(Seq(rs_push.asBool->rets_out(i-1),
|
||||
rs_pop.asBool ->rets_out(i+1))))
|
||||
rs_pop.asBool -> rets_out(1)))
|
||||
else if(i==RET_STACK_SIZE-1) rets_out(i-1)
|
||||
else Mux1H(Seq(rs_push.asBool->rets_out(i-1),
|
||||
rs_pop.asBool ->rets_out(i+1))))
|
||||
|
||||
// Make flops for poping the data
|
||||
rets_out := (0 until RET_STACK_SIZE).map(i=>rvdffe(rets_in(i), rsenable(i).asBool, clock, io.scan_mode))
|
||||
|
@ -396,7 +382,14 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
|||
|
||||
// Making the data to write into the BTB according the structure discribed above
|
||||
val btb_wr_data = Cat(btb_wr_tag, exu_mp_tgt, exu_mp_pc4, exu_mp_boffset, exu_mp_call | exu_mp_ja, exu_mp_ret | exu_mp_ja, btb_valid)
|
||||
val exu_mp_valid_write = exu_mp_valid & exu_mp_ataken & !io.exu_bp.exu_mp_pkt.valid
|
||||
val exu_mp_valid_write = exu_mp_valid & exu_mp_ataken
|
||||
|
||||
// Enable for write on each way
|
||||
val btb_wr_en_way0 = ((!exu_mp_way) & exu_mp_valid_write & (!dec_tlu_error_wb)) | ((!dec_tlu_way_wb) & dec_tlu_error_wb)
|
||||
val btb_wr_en_way1 = (exu_mp_way & exu_mp_valid_write & (!dec_tlu_error_wb)) | (dec_tlu_way_wb & dec_tlu_error_wb)
|
||||
|
||||
// Writing is always done from dec or exu check if the dec have a valid data
|
||||
val btb_wr_addr = Mux(dec_tlu_error_wb.asBool , btb_error_addr_wb, exu_mp_addr)
|
||||
val middle_of_bank = exu_mp_pc4 ^ exu_mp_boffset
|
||||
|
||||
// Enable the clk enable according to the exu misprediction where it is not a RAS
|
||||
|
@ -415,121 +408,50 @@ class ifu_bp_ctl extends Module with lib with RequireAsyncReset {
|
|||
val bht_wr_addr2 = br0_hashed_wb
|
||||
val bht_rd_addr_f = bht_rd_addr_hashed_f
|
||||
val bht_rd_addr_p1_f = bht_rd_addr_hashed_p1_f
|
||||
val btb_bank0_rd_data_way0_out = Wire(Vec(LRU_SIZE,UInt(BTB_DWIDTH.W)))
|
||||
val btb_bank0_rd_data_way1_out = Wire(Vec(LRU_SIZE,UInt(BTB_DWIDTH.W)))
|
||||
|
||||
// BTB
|
||||
// Entry -> Tag[BTB-BTAG-SIZE], toffset[12], pc4, boffset, call, ret, valid
|
||||
if(!BTB_FULLYA) {
|
||||
// Enable for write on each way
|
||||
val btb_wr_en_way0 = ((!exu_mp_way) & exu_mp_valid_write & (!dec_tlu_error_wb)) | ((!dec_tlu_way_wb) & dec_tlu_error_wb)
|
||||
val btb_wr_en_way1 = (exu_mp_way & exu_mp_valid_write & (!dec_tlu_error_wb)) | (dec_tlu_way_wb & dec_tlu_error_wb)
|
||||
|
||||
// Writing is always done from dec or exu check if the dec have a valid data
|
||||
val btb_wr_addr = Mux(dec_tlu_error_wb.asBool, btb_error_addr_wb, exu_mp_addr)
|
||||
val btb_bank0_rd_data_way0_out = (0 until LRU_SIZE).map(i=>rvdffe(btb_wr_data, ((btb_wr_addr===i.U) & btb_wr_en_way0).asBool, clock, io.scan_mode))
|
||||
val btb_bank0_rd_data_way1_out = (0 until LRU_SIZE).map(i=>rvdffe(btb_wr_data, ((btb_wr_addr===i.U) & btb_wr_en_way1).asBool, clock, io.scan_mode))
|
||||
|
||||
vwayhit_f := Mux1H(Seq(!io.ifc_fetch_addr_f(0).asBool->wayhit_f,
|
||||
io.ifc_fetch_addr_f(0).asBool->Cat(wayhit_p1_f(0), wayhit_f(1)))) & Cat(eoc_mask, 1.U(1.W))
|
||||
btb_bank0_rd_data_way0_f := Mux1H((0 until LRU_SIZE).map(i=>(btb_rd_addr_f===i.U).asBool->btb_bank0_rd_data_way0_out(i)))
|
||||
btb_bank0_rd_data_way1_f := Mux1H((0 until LRU_SIZE).map(i=>(btb_rd_addr_f===i.U).asBool->btb_bank0_rd_data_way1_out(i)))
|
||||
|
||||
btb_bank0_rd_data_way0_out := (0 until LRU_SIZE).map(i => rvdffe(btb_wr_data, ((btb_wr_addr === i.U) & btb_wr_en_way0).asBool, clock, io.scan_mode))
|
||||
btb_bank0_rd_data_way1_out := (0 until LRU_SIZE).map(i => rvdffe(btb_wr_data, ((btb_wr_addr === i.U) & btb_wr_en_way1).asBool, clock, io.scan_mode))
|
||||
btb_bank0_rd_data_way0_f := Mux1H((0 until LRU_SIZE).map(i => (btb_rd_addr_f === i.U).asBool -> btb_bank0_rd_data_way0_out(i)))
|
||||
btb_bank0_rd_data_way1_f := Mux1H((0 until LRU_SIZE).map(i => (btb_rd_addr_f === i.U).asBool -> btb_bank0_rd_data_way1_out(i)))
|
||||
// BTB read muxing
|
||||
btb_bank0_rd_data_way0_p1_f := Mux1H((0 until LRU_SIZE).map(i => (btb_rd_addr_p1_f === i.U).asBool -> btb_bank0_rd_data_way0_out(i)))
|
||||
btb_bank0_rd_data_way1_p1_f := Mux1H((0 until LRU_SIZE).map(i => (btb_rd_addr_p1_f === i.U).asBool -> btb_bank0_rd_data_way1_out(i)))
|
||||
}
|
||||
// if(BTB_FULLYA){
|
||||
// val fetch_mp_collision_f = WireInit(Bool(),init = false.B)
|
||||
// val fetch_mp_collision_p1_f = WireInit(Bool() ,init = false.B)
|
||||
//
|
||||
// // Fully Associative tag hash uses bits 31:3. Bits 2:1 are the offset bits used for the 4 tag comp banks
|
||||
// // Full tag used to speed up lookup. There is one 31:3 cmp per entry, and 4 2:1 cmps per entry.
|
||||
// val ifc_fetch_addr_p1_f = io.ifc_fetch_addr_f(FA_CMP_LOWER-1,1) + 1.U
|
||||
//
|
||||
//
|
||||
// // val fetch_mp_collision_f = ((io.exu_bp.exu_mp_btag(BTB_BTAG_SIZE-1,0) === io.ifc_fetch_addr_f) & exu_mp_valid & io.ifc_fetch_req_f & ~io.exu_bp.exu_mp_pkt.bits.way)
|
||||
// // val fetch_mp_collision_p1_f = ( (io.exu_bp.exu_mp_btag(BTB_BTAG_SIZE-1,0) === Cat(io.ifc_fetch_addr_f(30,FA_CMP_LOWER), ifc_fetch_addr_p1_f(FA_CMP_LOWER-1,1))) & exu_mp_valid & io.ifc_fetch_req_f & ~io.exu_bp.exu_mp_pkt.bits.way)
|
||||
// // val btb_upper_hit = Wire(Vec(BTB_SIZE,Bool()))
|
||||
// val btb_offset_0 = WireInit(UInt(BTB_SIZE.W) ,init = 0.U)
|
||||
// val btb_used = WireInit(UInt(BTB_SIZE.W) ,init = 0.U)
|
||||
// val btb_offset_1 = WireInit(UInt(BTB_SIZE.W) ,init = 0.U)
|
||||
// val wr0_en = WireInit(UInt(BTB_SIZE.W) ,init = 0.U)
|
||||
// val btbdata = Wire(Vec(BTB_SIZE,UInt(BTB_DWIDTH.W)))
|
||||
// btbdata := btbdata.map(i=> 0.U)
|
||||
// val hit0 = WireInit(UInt(1.W) ,init = 0.U)
|
||||
// val hit1 = WireInit(UInt(1.W) ,init = 0.U)
|
||||
//
|
||||
// // btb_upper_hit := (0 until BTB_SIZE).map(i=> ((btbdata(i)(BTB_DWIDTH_TOP,FA_TAG_END_UPPER) === io.ifc_fetch_addr_f(30,FA_CMP_LOWER)) & btbdata(i)(0) & ~wr0_en(i)))
|
||||
// // val btb_offset_0 = (0 until BTB_SIZE).map(i=> (btbdata(i)(FA_TAG_START_LOWER,FA_TAG_END_LOWER) === io.ifc_fetch_addr_f(FA_CMP_LOWER-1,1)) & btb_upper_hit(i))
|
||||
// // val btb_offset_1 = (0 until BTB_SIZE).map(i=> (btbdata(i)(FA_TAG_START_LOWER,FA_TAG_END_LOWER) === ifc_fetch_addr_p1_f(FA_CMP_LOWER-1,1)) & btb_upper_hit(i))
|
||||
//
|
||||
// // hit unless we are also writing this entry at the same time
|
||||
// val hit0_index = MuxCase(1.U, (0 until BTB_SIZE).map(i=> btb_offset_0(i) -> i.U))
|
||||
// val hit1_index = MuxCase(1.U, (0 until BTB_SIZE).map(i=> btb_offset_1(i) -> i.U))
|
||||
// // Mux out the 2 potential branches
|
||||
// btb_vbank0_rd_data_f := (0 until BTB_SIZE ).map(i=> if(btb_offset_1(i) == 1) Mux(fetch_mp_collision_f,btb_wr_data,btbdata(i)) else 0.U ).reverse.reduce(Cat(_,_))
|
||||
// btb_vbank1_rd_data_f :=(0 until BTB_SIZE).map(i=> if(btb_offset_1(i) == 1) Mux(fetch_mp_collision_p1_f,btb_wr_data,btbdata(i)) else 0.U).reverse.reduce(Cat(_,_))
|
||||
// val btb_fa_wr_addr0 = MuxCase(1.U, (0 until BTB_SIZE).map(i=> !btb_used(i) -> i.U))
|
||||
//
|
||||
// vwayhit_f := Cat(hit1,hit0) & Cat(eoc_mask,1.U)
|
||||
// way_raw := vwayhit_f | Cat(fetch_mp_collision_p1_f, fetch_mp_collision_f)
|
||||
// wr0_en := (0 until BTB_SIZE).map(i=> ((btb_fa_wr_addr0(BTB_FA_INDEX,0) === i.asUInt()) & (exu_mp_valid_write & ~io.exu_bp.exu_mp_pkt.bits.way)) |
|
||||
// ((io.dec_fa_error_index === i.asUInt()) & dec_tlu_error_wb)).reverse.reduce(Cat(_,_))
|
||||
// btbdata := (0 until BTB_SIZE).map(i=> rvdffe(btb_wr_data,wr0_en(i),clock,io.scan_mode))
|
||||
//
|
||||
// io.ifu_bp_fa_index_f(1) := Mux(hit1,hit1_index,0.U)
|
||||
// io.ifu_bp_fa_index_f(0) := Mux(hit0,hit0_index,0.U)
|
||||
//
|
||||
// val btb_used_reset = btb_used.andR()
|
||||
// val btb_used_ns = Mux1H(Seq(
|
||||
// vwayhit_f(1).asBool -> (1.U(32.W) << hit1_index(BTB_FA_INDEX,0)),
|
||||
// vwayhit_f(0).asBool() -> (1.U(32.W) << hit0_index(BTB_FA_INDEX,0)),
|
||||
// (exu_mp_valid_write & !io.exu_bp.exu_mp_pkt.bits.way & !dec_tlu_error_wb).asBool() -> (1.U(32.W) << btb_fa_wr_addr0(BTB_FA_INDEX,0)),
|
||||
// btb_used_reset.asBool -> Fill(BTB_SIZE,0.U),
|
||||
// (!btb_used_reset & dec_tlu_error_wb ).asBool -> (btb_used & ~(1.U(32.W) << io.dec_fa_error_index(BTB_FA_INDEX,0))),
|
||||
// !(btb_used_reset | dec_tlu_error_wb ).asBool() -> btb_used
|
||||
// ))
|
||||
// val write_used = btb_used_reset | io.ifu_bp_hit_taken_f | exu_mp_valid_write | dec_tlu_error_wb
|
||||
// btb_used := rvdffe(btb_used_ns,write_used.asBool(),clock,io.scan_mode)
|
||||
// }
|
||||
// BTB read muxing
|
||||
btb_bank0_rd_data_way0_p1_f := Mux1H((0 until LRU_SIZE).map(i=>(btb_rd_addr_p1_f===i.U).asBool->btb_bank0_rd_data_way0_out(i)))
|
||||
btb_bank0_rd_data_way1_p1_f := Mux1H((0 until LRU_SIZE).map(i=>(btb_rd_addr_p1_f===i.U).asBool->btb_bank0_rd_data_way1_out(i)))
|
||||
|
||||
val bht_bank_clken = Wire(Vec(2, Vec(BHT_ARRAY_DEPTH/NUM_BHT_LOOP, Bool())))
|
||||
|
||||
val bht_bank_clk = Wire(Vec(2, Vec(BHT_ARRAY_DEPTH/NUM_BHT_LOOP, Clock())))
|
||||
if(RV_FPGA_OPTIMIZE) {
|
||||
for(i<-0 until 2; k<- 0 until (BHT_ARRAY_DEPTH/NUM_BHT_LOOP)) bht_bank_clk(i)(k) := rvclkhdr(clock, bht_bank_clken(i)(k), io.scan_mode)
|
||||
// (0 until 2).map(i=>(0 until (BHT_ARRAY_DEPTH/NUM_BHT_LOOP)).map(k=>rvclkhdr(clock, bht_bank_clken(i)(k), io.scan_mode)))
|
||||
|
||||
}
|
||||
val bht_bank_clk = (0 until 2).map(i=>(0 until (BHT_ARRAY_DEPTH/NUM_BHT_LOOP)).map(k=>rvclkhdr(clock, bht_bank_clken(i)(k), io.scan_mode)))
|
||||
for(i<-0 until 2; k<- 0 until (BHT_ARRAY_DEPTH/NUM_BHT_LOOP)){
|
||||
// Checking if there is a write enable with address for the BHT
|
||||
// Checking if there is a write enable with address for the BHT
|
||||
bht_bank_clken(i)(k) := (bht_wr_en0(i) & ((bht_wr_addr0(BHT_ADDR_HI-BHT_ADDR_LO,NUM_BHT_LOOP_OUTER_LO-2)===k.U) | BHT_NO_ADDR_MATCH.B)) |
|
||||
(bht_wr_en2(i) & ((bht_wr_addr2(BHT_ADDR_HI-BHT_ADDR_LO,NUM_BHT_LOOP_OUTER_LO-2)===k.U) | BHT_NO_ADDR_MATCH.B))
|
||||
(bht_wr_en2(i) & ((bht_wr_addr2(BHT_ADDR_HI-BHT_ADDR_LO,NUM_BHT_LOOP_OUTER_LO-2)===k.U) | BHT_NO_ADDR_MATCH.B))
|
||||
}
|
||||
|
||||
// Writing data into the BHT (DEC-side) or (EXU-side)
|
||||
val bht_bank_wr_data = (0 until 2).map(i=>(0 until BHT_ARRAY_DEPTH/NUM_BHT_LOOP).map(k=>(0 until NUM_BHT_LOOP).map(j=>
|
||||
Mux((bht_wr_en2(i)&(bht_wr_addr2(NUM_BHT_LOOP_INNER_HI-BHT_ADDR_LO,0)===j.U)&((bht_wr_addr2(BHT_ADDR_HI-BHT_ADDR_LO,NUM_BHT_LOOP_OUTER_LO-BHT_ADDR_LO)===k.U)|BHT_NO_ADDR_MATCH.B)).asBool, bht_wr_data2, bht_wr_data0))))
|
||||
Mux((bht_wr_en2(i)&(bht_wr_addr2(NUM_BHT_LOOP_INNER_HI-BHT_ADDR_LO,0)===j.U)&(bht_wr_addr2(BHT_ADDR_HI-BHT_ADDR_LO,NUM_BHT_LOOP_OUTER_LO-BHT_ADDR_LO)===k.U)|BHT_NO_ADDR_MATCH.B).asBool, bht_wr_data2, bht_wr_data0))))
|
||||
|
||||
val bht_bank_sel = Wire(Vec(2, Vec(BHT_ARRAY_DEPTH/NUM_BHT_LOOP, Vec(NUM_BHT_LOOP, Bool()))))
|
||||
|
||||
// We have a 2 way bht with BHT_ARRAY_DEPTH/NUM_BHT_LOOP blocks and NUM_BHT_LOOP->offset in each block
|
||||
// Make enables of each flop according to the address dividing the address in 2-blocks upper block for BHT-Block and
|
||||
// the lower block for the offset and run this on both of the ways
|
||||
|
||||
// the lower block for the offset and run this on both of the ways
|
||||
for(i<-0 until 2; k<-0 until BHT_ARRAY_DEPTH/NUM_BHT_LOOP; j<- 0 until NUM_BHT_LOOP){
|
||||
bht_bank_sel(i)(k)(j) := (bht_wr_en0(i) & (bht_wr_addr0(NUM_BHT_LOOP_INNER_HI-BHT_ADDR_LO,0)===j.asUInt) & ((bht_wr_addr0(BHT_ADDR_HI-BHT_ADDR_LO, NUM_BHT_LOOP_OUTER_LO-BHT_ADDR_LO)===k.asUInt) | BHT_NO_ADDR_MATCH.B)) |
|
||||
(bht_wr_en2(i) & (bht_wr_addr2(NUM_BHT_LOOP_INNER_HI-BHT_ADDR_LO,0)===j.asUInt) & ((bht_wr_addr2(BHT_ADDR_HI-BHT_ADDR_LO, NUM_BHT_LOOP_OUTER_LO-BHT_ADDR_LO)===k.asUInt) | BHT_NO_ADDR_MATCH.B))
|
||||
}
|
||||
|
||||
// Reading the BHT with i->way, k->block and the j->offset
|
||||
val bht_bank_rd_data_out = Wire(Vec(2, Vec(BHT_ARRAY_DEPTH, UInt(2.W))))
|
||||
for(i<-0 until 2; k<-0 until BHT_ARRAY_DEPTH/NUM_BHT_LOOP; j<-0 until NUM_BHT_LOOP){
|
||||
bht_bank_rd_data_out(i)((16*k)+j) := rvdffs_fpga(bht_bank_wr_data(i)(k)(j), bht_bank_sel(i)(k)(j),bht_bank_clk(i)(k),bht_bank_sel(i)(k)(j),clock)}
|
||||
bht_bank_rd_data_out(i)((16*k)+j) := withClock(bht_bank_clk(i)(k)){RegEnable(bht_bank_wr_data(i)(k)(j), 0.U, bht_bank_sel(i)(k)(j))}
|
||||
}
|
||||
|
||||
// Make the final read mux
|
||||
bht_bank0_rd_data_f := Mux1H((0 until BHT_ARRAY_DEPTH).map(i=>(bht_rd_addr_f===i.U).asBool->bht_bank_rd_data_out(0)(i)))
|
||||
bht_bank1_rd_data_f := Mux1H((0 until BHT_ARRAY_DEPTH).map(i=>(bht_rd_addr_f===i.U).asBool->bht_bank_rd_data_out(1)(i)))
|
||||
bht_bank0_rd_data_p1_f := Mux1H((0 until BHT_ARRAY_DEPTH).map(i=>(bht_rd_addr_p1_f===i.U).asBool->bht_bank_rd_data_out(0)(i)))
|
||||
}
|
||||
//object bp_MAIN extends App {
|
||||
// println((new chisel3.stage.ChiselStage).emitVerilog(new ifu_bp_ctl()))
|
||||
//}
|
|
@ -23,7 +23,7 @@ class ifu_compress_ctl extends Module with lib{
|
|||
out(13) := pat(List(15, -14, -13, 11, -10, 0)) | pat(List(15, -14, -13, 11, 6, 0)) | (io.din(14)&(!io.din(0)))
|
||||
|
||||
out(12) := pat(List(15, -14, -13, 6, 5, 0)) | pat(List(15, -14, -13, -11, 0)) | pat(List(15, -14, -13, -10, 0)) |
|
||||
pat(List(-15, -14, 1)) | pat(List(15, 14, 13))
|
||||
pat(List(-15, -14, 1)) | pat(List(15, 14, 13))
|
||||
|
||||
out(6) := (pat(List(15, -14, -6, -5, -4, -3, -2)) & !io.din(0)) | pat(List(-14, 13)) | pat(List(15, 14, 0))
|
||||
|
||||
|
@ -54,7 +54,7 @@ class ifu_compress_ctl extends Module with lib{
|
|||
|
||||
val rdrd = pat(List(-14,6,1)) | pat(List(-15,14,11,0)) | pat(List(-14,5,1)) | pat(List(-15,14,10,0)) |
|
||||
pat(List(-14,4,1)) | pat(List(-15,14,9,0)) | pat(List(-14,3,1)) | pat(List(-15,14,-8,0)) |
|
||||
pat(List(-14,2,1)) | pat(List(-15,14,7,0)) | pat(List(-15,1)) | pat(List(-15,-13,0))
|
||||
pat(List(-14,2,1)) | pat(List(-15,14,7,0)) | pat(List(-15,1)) | pat(List(-15,-13,0))
|
||||
|
||||
val rdrs1 = pat(List(-14,12,11,1)) | pat(List(-14,12,10,1)) | pat(List(-14,12,9,1)) |
|
||||
pat(List(-14,12,8,1)) | pat(List(-14,12,7,1)) | pat(List(-14,-12,-6,-5,-4,-3,-2,1)) |
|
||||
|
@ -104,7 +104,7 @@ class ifu_compress_ctl extends Module with lib{
|
|||
val l1_6 = Cat(out(6),out(5),out(4),out(3),out(2),out(1),out(0)).asUInt()
|
||||
|
||||
val l1_11 = Cat(out(11),out(10),out(9),out(8),out(7)).asUInt | Mux1H(Seq(rdrd.asBool->rdd,
|
||||
rdprd.asBool->rdpd, rs2prd.asBool->rs2pd, rdeq1.asBool->1.U(5.W), rdeq2.asBool->2.U(5.W)))
|
||||
rdprd.asBool->rdpd, rs2prd.asBool->rs2pd, rdeq1.asBool->1.U(5.W), rdeq2.asBool->2.U(5.W)))
|
||||
|
||||
val l1_14 = Cat(out(14),out(13),out(12))
|
||||
|
||||
|
@ -132,16 +132,16 @@ class ifu_compress_ctl extends Module with lib{
|
|||
|
||||
val l2_31 = l1(31,20) |
|
||||
Mux1H(Seq(simm5_0.asBool->Cat(repl(7, simm5d(5)), simm5d(4,0)),
|
||||
uimm9_2.asBool->Cat(0.U(2.W), uimm9d, 0.U(2.W)),
|
||||
simm9_4.asBool->Cat(repl(3, simm9d(5)), simm9d(4,0), 0.U(4.W)),
|
||||
ulwimm6_2.asBool->Cat(0.U(5.W), ulwimm6d, 0.U(2.W)),
|
||||
ulwspimm7_2.asBool->Cat(0.U(4.W), ulwspimm7d, 0.U(2.W)),
|
||||
uimm5_0.asBool->Cat(0.U(6.W), uimm5d),
|
||||
sjaloffset11_1.asBool->Cat(sjald(19), sjald(9,0), sjald(10)),
|
||||
sluimm17_12.asBool->sluimmd(19,8)))
|
||||
uimm9_2.asBool->Cat(0.U(2.W), uimm9d, 0.U(2.W)),
|
||||
simm9_4.asBool->Cat(repl(3, simm9d(5)), simm9d(4,0), 0.U(4.W)),
|
||||
ulwimm6_2.asBool->Cat(0.U(5.W), ulwimm6d, 0.U(2.W)),
|
||||
ulwspimm7_2.asBool->Cat(0.U(4.W), ulwspimm7d, 0.U(2.W)),
|
||||
uimm5_0.asBool->Cat(0.U(6.W), uimm5d),
|
||||
sjaloffset11_1.asBool->Cat(sjald(19), sjald(9,0), sjald(10)),
|
||||
sluimm17_12.asBool->sluimmd(19,8)))
|
||||
|
||||
val l2_19 = l1(19,12) | Mux1H(Seq(sjaloffset11_1.asBool->sjald(19,12),
|
||||
sluimm17_12.asBool->sluimmd(7,0)))
|
||||
sluimm17_12.asBool->sluimmd(7,0)))
|
||||
val l2 = Cat(l2_31, l2_19, l1(11,0))
|
||||
|
||||
val sbr8d = Cat(io.din(12),io.din(6),io.din(5),io.din(2),io.din(11),io.din(10),io.din(4),io.din(3),0.U)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue