Initialized Quasar 1.0 branch

This commit is contained in:
komaljaved-lm 2021-03-31 18:32:05 +05:00
parent d533ec413e
commit 31c8526ffe
578 changed files with 36526 additions and 73225 deletions

View File

@ -1,6 +1,6 @@
# Quasar RISC-V Core 2.0 from Lampro Mellon
# Quasar RISC-V Core 1.0 from Lampro Mellon
This repository contains the Quasar Core design in CHISEL.
This repository contains the SweRV-EL2 Core written in CHISEL named "Quasar".
## License
@ -40,22 +40,18 @@ Quasar is a Chiselified version of EL2 SweRV RISC-V Core.
├── generated_rtl # Quasar wrapper
├── testbench
│ ├── asm # Example assembly files
│ ├── hex # Canned demo hex files
│ └── tests # Example tests
│ └── hex # Canned demo hex files
├── tools # Scripts/Makefiles
├── tracer_logs # generated log files
└── verif
├── LEC
├── formality_work
└── formality_log # LEC log files
└── setup_files # user_match files
└── 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)
```
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.

6
RELEASE-NOTE.md Normal file
View File

@ -0,0 +1,6 @@
# Quasar RISC-V Core 1.0 from Lampro Mellon
## Release Notes
~~~
Initial release DATE
~~~

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -1 +1 @@
2024296794
-1641150927

File diff suppressed because one or more lines are too long

View File

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

File diff suppressed because one or more lines are too long

View File

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

File diff suppressed because one or more lines are too long

View File

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

View File

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

File diff suppressed because one or more lines are too long

View File

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
//********************************************************************************
// SPDX-License-Identifier: Apache-2.0
// Copyright 2020 Western Digital Corporation or its affiliates.
// Copyright 2020 Western Digital Corporation or it's affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -20,38 +20,29 @@
//********************************************************************************
module ifu_iccm_mem
//`include "parameter.sv"
#(
parameter ICCM_BITS,
parameter ICCM_BANK_INDEX_LO,
parameter ICCM_INDEX_BITS,
parameter ICCM_BANK_HI,
parameter ICCM_NUM_BANKS,
// parameter ICCM_ENABLE= 'b1,
parameter ICCM_BANK_BITS
parameter ICCM_BANK_BITS )(
input logic clk,
input logic rst_l,
input logic clk_override,
)
(
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
input logic rst_l, // reset, active low
input logic clk_override, // Override non-functional clock gating
input logic iccm_wren, // ICCM write enable
input logic iccm_rden, // ICCM read enable
input logic [ICCM_BITS-1:1] iccm_rw_addr, // ICCM read/write address
input logic iccm_wren,
input logic iccm_rden,
input logic [ICCM_BITS-1:1] iccm_rw_addr,
input logic iccm_buf_correct_ecc, // ICCM is doing a single bit error correct cycle
input logic iccm_correction_state, // ICCM under a correction - This is needed to guard replacements when hit
input logic [2:0] iccm_wr_size, // ICCM write size
input logic [77:0] iccm_wr_data, // ICCM write data
input iccm_ext_in_pkt_t [ICCM_NUM_BANKS-1:0] iccm_ext_in_pkt, // External packet
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,
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,12 +238,12 @@ module ifu_iccm_mem
((addr_bank_inc[ICCM_BITS-1:2]== redundant_address[0][ICCM_BITS-1:2]) & (addr_bank_inc[3:2] == i))));
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]));
@ -400,6 +253,7 @@ module ifu_iccm_mem
({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
// 2x 39 bit data values with address[hi:2] and a valid bit is needed to CAM and sub out the reads/writes to the particular locations
@ -410,31 +264,31 @@ module ifu_iccm_mem
assign redundant_lru_in = iccm_buf_correct_ecc ? ~redundant_lru : (|sel_red0[ICCM_NUM_BANKS-1:0]) ? 1'b1 : 1'b0;
rvdffs #() red_lru (.*, // LRU flop for the redundant replacements
.clk(active_clk),
.clk(clk),
.en(redundant_lru_en),
.din(redundant_lru_in),
.dout(redundant_lru));
rvdffs #(ICCM_BITS-2) r0_address (.*, // Redundant Row 0 address
.clk(active_clk),
.clk(clk),
.en(r0_addr_en),
.din(iccm_rw_addr[ICCM_BITS-1:2]),
.dout(redundant_address[0][ICCM_BITS-1:2]));
rvdffs #(ICCM_BITS-2) r1_address (.*, // Redundant Row 0 address
.clk(active_clk),
.clk(clk),
.en(r1_addr_en),
.din(iccm_rw_addr[ICCM_BITS-1:2]),
.dout(redundant_address[1][ICCM_BITS-1:2]));
rvdffs #(1) r0_valid (.*,
.clk(active_clk), // Redundant Row 0 Valid
.clk(clk), // Redundant Row 0 Valid
.en(r0_addr_en),
.din(1'b1),
.dout(redundant_valid[0]));
rvdffs #(1) r1_valid (.*, // Redundant Row 1 Valid
.clk(active_clk),
.clk(clk),
.en(r1_addr_en),
.din(1'b1),
.dout(redundant_valid[1]));
@ -451,7 +305,7 @@ module ifu_iccm_mem
assign redundant_data0_in[38:0] = (((iccm_rw_addr[2] == redundant_address[0][2]) & iccm_rw_addr[2]) | (redundant_address[0][2] & (iccm_wr_size[1:0] == 2'b11))) ? iccm_wr_data[77:39] : iccm_wr_data[38:0];
rvdffs #(39) r0_data (.*, // Redundant Row 1 data
.clk(active_clk),
.clk(clk),
.en(redundant_data0_en),
.din(redundant_data0_in[38:0]),
.dout(redundant_data[0][38:0]));
@ -462,18 +316,18 @@ module ifu_iccm_mem
assign redundant_data1_in[38:0] = (((iccm_rw_addr[2] == redundant_address[1][2]) & iccm_rw_addr[2]) | (redundant_address[1][2] & (iccm_wr_size[1:0] == 2'b11))) ? iccm_wr_data[77:39] : iccm_wr_data[38:0];
rvdffs #(39) r1_data (.*, // Redundant Row 1 data
.clk(active_clk),
.clk(clk),
.en(redundant_data1_en),
.din(redundant_data1_in[38:0]),
.dout(redundant_data[1][38:0]));
rvdffs #(ICCM_BANK_HI) rd_addr_lo_ff (.*, .clk(active_clk), .din(iccm_rw_addr [ICCM_BANK_HI:1]), .dout(iccm_rd_addr_lo_q[ICCM_BANK_HI:1]), .en(1'b1)); // bit 0 of address is always 0
rvdffs #(ICCM_BANK_BITS) rd_addr_hi_ff (.*, .clk(active_clk), .din(addr_bank_inc[ICCM_BANK_HI:2]), .dout(iccm_rd_addr_hi_q[ICCM_BANK_HI:2]), .en(1'b1));
rvdffs #(ICCM_BANK_HI) rd_addr_lo_ff (.*, .din(iccm_rw_addr [ICCM_BANK_HI:1]), .dout(iccm_rd_addr_lo_q[ICCM_BANK_HI:1]), .en(1'b1)); // bit 0 of address is always 0
rvdffs #(ICCM_BANK_BITS) rd_addr_hi_ff (.*, .din(addr_bank_inc[ICCM_BANK_HI:2]), .dout(iccm_rd_addr_hi_q[ICCM_BANK_HI:2]), .en(1'b1));
assign iccm_rd_data_pre[63:0] = {iccm_bank_dout_fn[iccm_rd_addr_hi_q][31:0], iccm_bank_dout_fn[iccm_rd_addr_lo_q[ICCM_BANK_HI:2]][31:0]};
assign iccm_data[63:0] = 64'({16'b0, (iccm_rd_data_pre[63:0] >> (16*iccm_rd_addr_lo_q[1]))});
assign iccm_rd_data[63:0] = {iccm_data[63:0]};
assign iccm_rd_data_ecc[77:0] = {iccm_bank_dout_fn[iccm_rd_addr_hi_q][38:0], iccm_bank_dout_fn[iccm_rd_addr_lo_q[ICCM_BANK_HI:2]][38:0]};
endmodule // ifu_iccm_mem
endmodule // el2_ifu_iccm_mem

View File

@ -1,5 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2020 Western Digital Corporation or its affiliates.
// Copyright 2020 Western Digital Corporation or it's affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -27,37 +27,17 @@
// //********************************************************************************
`define LOCAL_DCCM_RAM_TEST_PORTS .TEST1(dccm_ext_in_pkt[i].TEST1), \
.RME(dccm_ext_in_pkt[i].RME), \
.RM(dccm_ext_in_pkt[i].RM), \
.LS(dccm_ext_in_pkt[i].LS), \
.DS(dccm_ext_in_pkt[i].DS), \
.SD(dccm_ext_in_pkt[i].SD), \
.TEST_RNM(dccm_ext_in_pkt[i].TEST_RNM), \
.BC1(dccm_ext_in_pkt[i].BC1), \
.BC2(dccm_ext_in_pkt[i].BC2), \
module lsu_dccm_mem
//`include "parameter.sv"
#(
parameter DCCM_BYTE_WIDTH,
parameter DCCM_BITS,
parameter DCCM_NUM_BANKS,
parameter DCCM_ENABLE= 'b1,
parameter DCCM_BANK_BITS,
parameter DCCM_SIZE,
parameter DCCM_FDATA_WIDTH,
parameter DCCM_WIDTH_BITS
)
(
input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
input logic rst_l, // reset, active low
input logic clk_override, // Override non-functional clock gating
parameter DCCM_FDATA_WIDTH )(
input logic clk, // clock
input logic rst_l,
input logic clk_override, // clock override
input logic dccm_wren, // write enable
input logic dccm_rden, // read enable
@ -67,7 +47,6 @@ module lsu_dccm_mem
input logic [DCCM_BITS-1:0] dccm_rd_addr_hi, // read address for the upper bank in case of a misaligned access
input logic [DCCM_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,7 +101,6 @@ module lsu_dccm_mem
// end clock gating section
`ifdef VERILATOR
el2_ram #(DCCM_INDEX_DEPTH,39) ram (
// Primary ports
.ME(dccm_clken[i]),
@ -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,9 +122,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
@ -161,9 +134,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
@ -176,9 +146,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
@ -191,9 +158,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
@ -206,9 +170,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
@ -221,9 +182,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
@ -236,9 +194,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
@ -251,9 +206,6 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
@ -266,37 +218,18 @@ module lsu_dccm_mem
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
else if (DCCM_INDEX_DEPTH == 128) begin : dccm
ram_128x39 dccm_bank (
// Primary ports
.ME(dccm_clken[i]),
.CLK(clk),
.WE(wren_bank[i]),
.ADR(addr_bank[i]),
.D(wr_data_bank[i][DCCM_FDATA_WIDTH-1:0]),
.Q(dccm_bank_dout[i][DCCM_FDATA_WIDTH-1:0]),
.ROP ( ),
// These are used by SoC
`LOCAL_DCCM_RAM_TEST_PORTS
.*
);
end
`endif
`endif // VERILATOR
end : mem_bank
// Flops
rvdff #(DCCM_BANK_BITS) rd_addr_lo_ff (.*, .din(dccm_rd_addr_lo[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_lo_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .clk(active_clk));
rvdff #(DCCM_BANK_BITS) rd_addr_hi_ff (.*, .din(dccm_rd_addr_hi[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .clk(active_clk));
rvdffs #(DCCM_BANK_BITS) rd_addr_lo_ff (.*, .din(dccm_rd_addr_lo[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_lo_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .en(1'b1));
rvdffs #(DCCM_BANK_BITS) rd_addr_hi_ff (.*, .din(dccm_rd_addr_hi[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .dout(dccm_rd_addr_hi_q[DCCM_WIDTH_BITS+:DCCM_BANK_BITS]), .en(1'b1));
`undef LOCAL_DCCM_RAM_TEST_PORTS
`undef EL2_LOCAL_DCCM_RAM_TEST_PORTS
endmodule // lsu_dccm_mem
endmodule // el2_lsu_dccm_mem

View File

@ -1,71 +1,5 @@
//********************************************************************************
// SPDX-License-Identifier: Apache-2.0
// Copyright 2020 Western Digital Corporation or its affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//********************************************************************************
typedef struct packed {
logic TEST1;
logic RME;
logic [3:0] RM;
logic LS;
logic DS;
logic SD;
logic TEST_RNM;
logic BC1;
logic BC2;
} iccm_ext_in_pkt_t;
typedef struct packed {
logic TEST1;
logic RME;
logic [3:0] RM;
logic LS;
logic DS;
logic SD;
logic TEST_RNM;
logic BC1;
logic BC2;
} dccm_ext_in_pkt_t;
typedef struct packed {
logic TEST1;
logic RME;
logic [3:0] RM;
logic LS;
logic DS;
logic SD;
logic TEST_RNM;
logic BC1;
logic BC2;
} ic_data_ext_in_pkt_t;
typedef struct packed {
logic TEST1;
logic RME;
logic [3:0] RM;
logic LS;
logic DS;
logic SD;
logic TEST_RNM;
logic BC1;
logic BC2;
} ic_tag_ext_in_pkt_t;
module mem#(
module mem #(
parameter ICACHE_BEAT_BITS,
parameter ICCM_BITS,
parameter ICACHE_NUM_WAYS,
@ -95,17 +29,7 @@ module mem#(
parameter DCCM_SIZE,
parameter DCCM_FDATA_WIDTH,
parameter ICACHE_TAG_INDEX_LO,
parameter ICACHE_DATA_DEPTH,
parameter DCCM_WIDTH_BITS,
parameter ICACHE_NUM_BYPASS,
parameter ICACHE_TAG_NUM_BYPASS,
parameter ICACHE_TAG_NUM_BYPASS_WIDTH,
parameter ICACHE_TAG_BYPASS_ENABLE,
parameter ICACHE_NUM_BYPASS_WIDTH,
parameter ICACHE_BYPASS_ENABLE,
parameter ICACHE_LN_SZ
)
parameter ICACHE_DATA_DEPTH)
(
input logic clk,
input logic rst_l,
@ -128,89 +52,10 @@ module mem#(
output logic [DCCM_FDATA_WIDTH-1:0] dccm_rd_data_hi,
//`ifdef DCCM_ENABLE
//input dccm_ext_in_pkt_t [DCCM_NUM_BANKS-1:0] dccm_ext_in_pkt,
input logic dccm_ext_in_pkt_TEST1_0,
input logic dccm_ext_in_pkt_RME_0,
input logic [3:0] dccm_ext_in_pkt_RM_0,
input logic dccm_ext_in_pkt_LS_0,
input logic dccm_ext_in_pkt_DS_0,
input logic dccm_ext_in_pkt_SD_0,
input logic dccm_ext_in_pkt_TEST_RNM_0,
input logic dccm_ext_in_pkt_BC1_0,
input logic dccm_ext_in_pkt_BC2_0,
input logic dccm_ext_in_pkt_TEST1_1,
input logic dccm_ext_in_pkt_RME_1,
input logic [3:0] dccm_ext_in_pkt_RM_1,
input logic dccm_ext_in_pkt_LS_1,
input logic dccm_ext_in_pkt_DS_1,
input logic dccm_ext_in_pkt_SD_1,
input logic dccm_ext_in_pkt_TEST_RNM_1,
input logic dccm_ext_in_pkt_BC1_1,
input logic dccm_ext_in_pkt_BC2_1,
input logic dccm_ext_in_pkt_TEST1_2,
input logic dccm_ext_in_pkt_RME_2,
input logic [3:0] dccm_ext_in_pkt_RM_2,
input logic dccm_ext_in_pkt_LS_2,
input logic dccm_ext_in_pkt_DS_2,
input logic dccm_ext_in_pkt_SD_2,
input logic dccm_ext_in_pkt_TEST_RNM_2,
input logic dccm_ext_in_pkt_BC1_2,
input logic dccm_ext_in_pkt_BC2_2,
input logic dccm_ext_in_pkt_TEST1_3,
input logic dccm_ext_in_pkt_RME_3,
input logic [3:0] dccm_ext_in_pkt_RM_3,
input logic dccm_ext_in_pkt_LS_3,
input logic dccm_ext_in_pkt_DS_3,
input logic dccm_ext_in_pkt_SD_3,
input logic dccm_ext_in_pkt_TEST_RNM_3,
input logic dccm_ext_in_pkt_BC1_3,
input logic dccm_ext_in_pkt_BC2_3,
//`endif
//ICCM ports
input logic iccm_ext_in_pkt_TEST1_0,
input logic iccm_ext_in_pkt_RME_0,
input logic [3:0] iccm_ext_in_pkt_RM_0,
input logic iccm_ext_in_pkt_LS_0,
input logic iccm_ext_in_pkt_DS_0,
input logic iccm_ext_in_pkt_SD_0,
input logic iccm_ext_in_pkt_TEST_RNM_0,
input logic iccm_ext_in_pkt_BC1_0,
input logic iccm_ext_in_pkt_BC2_0,
input logic iccm_ext_in_pkt_TEST1_1,
input logic iccm_ext_in_pkt_RME_1,
input logic [3:0] iccm_ext_in_pkt_RM_1,
input logic iccm_ext_in_pkt_LS_1,
input logic iccm_ext_in_pkt_DS_1,
input logic iccm_ext_in_pkt_SD_1,
input logic iccm_ext_in_pkt_TEST_RNM_1,
input logic iccm_ext_in_pkt_BC1_1,
input logic iccm_ext_in_pkt_BC2_1,
input logic iccm_ext_in_pkt_TEST1_2,
input logic iccm_ext_in_pkt_RME_2,
input logic [3:0] iccm_ext_in_pkt_RM_2,
input logic iccm_ext_in_pkt_LS_2,
input logic iccm_ext_in_pkt_DS_2,
input logic iccm_ext_in_pkt_SD_2,
input logic iccm_ext_in_pkt_TEST_RNM_2,
input logic iccm_ext_in_pkt_BC1_2,
input logic iccm_ext_in_pkt_BC2_2,
input logic iccm_ext_in_pkt_TEST1_3,
input logic iccm_ext_in_pkt_RME_3,
input logic [3:0] iccm_ext_in_pkt_RM_3,
input logic iccm_ext_in_pkt_LS_3,
input logic iccm_ext_in_pkt_DS_3,
input logic iccm_ext_in_pkt_SD_3,
input logic iccm_ext_in_pkt_TEST_RNM_3,
input logic iccm_ext_in_pkt_BC1_3,
input logic iccm_ext_in_pkt_BC2_3,
input logic [ICCM_BITS-1:1] iccm_rw_addr,
input logic iccm_buf_correct_ecc, // ICCM is doing a single bit error correct cycle
@ -231,70 +76,9 @@ 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_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.
@ -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),
.*
);
@ -546,4 +171,3 @@ end
endmodule

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,20 +2,24 @@ 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 {
@ -49,13 +53,12 @@ class dbg extends Module with lib with RequireAsyncReset {
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 dbg_rst_l = Input(Bool())
val clk_override = Input(Bool())
val scan_mode = Input(Bool())
})
@ -72,7 +75,6 @@ class dbg extends Module with lib with RequireAsyncReset {
val sbaddress0_reg_wren1 = WireInit(false.B)
val 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)
@ -89,64 +91,51 @@ class dbg extends Module with lib with RequireAsyncReset {
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_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_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_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_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))))
dontTouch(dbg_dm_rst_l)
val rst_temp = (dbg_dm_rst_l.asBool() & reset.asBool()).asAsyncReset()
dontTouch(rst_temp)
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
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
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
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
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
RegEnable(sbcs_sberror_din(2, 0), 0.U, sbcs_sberror_wren)
} // sbcs_error_reg
sbcs_reg := Cat(1.U(3.W), 0.U(6.W), temp_sbcs_22, temp_sbcs_21, temp_sbcs_20, temp_sbcs_19_15, temp_sbcs_14_12, "h20".U(7.W), "b01111".U(5.W))
sbcs_reg := Cat(1.U(3.W), 0.U(6.W), temp_sbcs_22, temp_sbcs_21, temp_sbcs_20, temp_sbcs_19_15(4), ~temp_sbcs_19_15(3),
temp_sbcs_19_15(2,0), temp_sbcs_14_12, "h20".U(7.W), "b01111".U(5.W))
val sbcs_unaligned = (sbcs_reg(19, 17) === 1.U(3.W)) & sbaddress0_reg(0) |
(sbcs_reg(19, 17) === 2.U(3.W)) & sbaddress0_reg(1, 0).orR |
(sbcs_reg(19, 17) === 3.U(3.W)) & sbaddress0_reg(2, 0).orR
val sbcs_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
@ -154,137 +143,120 @@ class dbg extends Module with lib with RequireAsyncReset {
val sbdata1_reg_wren0 = io.dmi_reg_en & io.dmi_reg_wr_en & (io.dmi_reg_addr === "h3d".U)
val sbdata1_reg_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 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 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 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
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.asAsyncReset()) {
RegEnable(io.dmi_reg_wdata(0), 0.U, dmcontrol_wren)
} // dmcontrol_dmactive_ff
val temp = Cat(dm_temp(3, 2), 0.U, dm_temp(1), 0.U(26.W), dm_temp(0), dm_temp_0)
dmcontrol_reg := temp
dmcontrol_wren_Q := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegNext(dmcontrol_wren, 0.U)} // dmcontrol_wrenff
val dmcontrol_wren_Q = withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegNext(dmcontrol_wren, 0.U)
} // dmcontrol_wrenff
dmstatus_reg := Cat(0.U(12.W), Fill(2, dmstatus_havereset), Fill(2, dmstatus_resumeack), 0.U(2.W), Fill(2, dmstatus_unavail),
Fill(2, dmstatus_running), Fill(2, dmstatus_halted), 1.U(1.W), 0.U(3.W), 2.U(4.W))
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 dmstatus_resumeack_wren = (dbg_state === state_t.resuming) & io.dec_tlu_resume_ack | dmstatus_resumeack & resumereq & dmstatus_halted
val dmstatus_resumeack_wren = (dbg_state === state_t.resuming) & io.dec_tlu_resume_ack | dmstatus_resumeack & !dmcontrol_reg(30)
val dmstatus_resumeack_din = (dbg_state === state_t.resuming) & io.dec_tlu_resume_ack
val dmstatus_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
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
RegEnable(dmstatus_resumeack_din, 0.U, dmstatus_resumeack_wren)
} // 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
RegNext(io.dec_tlu_dbg_halted & !io.dec_tlu_mpc_halted_only, 0.U)
} // dmstatus_halted_reg
dmstatus_havereset := withClockAndReset(dbg_free_clk, dbg_dm_rst_l) {
RegNext(Mux(dmstatus_havereset_wren, true.B, dmstatus_havereset) & !dmstatus_havereset_rst, false.B)
} // dmstatus_havereset_reg
val haltsum0_reg = Cat(0.U(31.W), dmstatus_halted)
val abstractcs_reg = WireInit(2.U(32.W))
val abstractcs_error_sel0 = abstractcs_reg(12) & ~(abstractcs_reg(10,8).orR) & io.dmi_reg_en & ((io.dmi_reg_wr_en & ((io.dmi_reg_addr === "h16".U(7.W)) |
(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
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))
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
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))
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
@ -293,126 +265,74 @@ class dbg extends Module with lib with RequireAsyncReset {
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
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_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))
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)).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_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 := 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()
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_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, Cat("b0".U, (command_reg(15, 12) === "b0".U)))
io.dbg_dec_dma.dbg_ib.dbg_cmd_type := Mux((command_reg(31, 24) === "h2".U), "b10".U(2.W), Cat("b0".U, (command_reg(15, 12) === "b0".U)))
io.dbg_cmd_size := command_reg(21, 20)
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_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,7 +345,7 @@ 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
@ -433,23 +353,22 @@ class dbg extends Module with lib with RequireAsyncReset {
}
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_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))
}
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_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_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
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.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 := 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.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.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.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_abmem_cmd_arvalid | sb_cmd_arvalid
io.sb_axi.ar.bits.addr := sb_axi_addr
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 := 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.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 := 1.U(2.W)
io.sb_axi.ar.bits.burst := "b01".U(2.W)
io.sb_axi.ar.bits.qos := 0.U
io.sb_axi.ar.bits.lock := false.B
io.sb_axi.b.ready := true.B
io.sb_axi.r.ready := true.B
sb_bus_rdata := Fill(64, (sbcs_reg(19, 17) === "h0".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 8.U * sbaddress0_reg(2, 0)) & "hff".U(64.W)) |
Fill(64, (sbcs_reg(19, 17) === "h1".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 16.U * sbaddress0_reg(2, 1)) & "hffff".U(64.W)) |
Fill(64, (sbcs_reg(19, 17) === "h2".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 32.U * sbaddress0_reg(2)) & "hffff_ffff".U(64.W)) |
Fill(64, (sbcs_reg(19, 17) === "h3".U)) & io.sb_axi.r.bits.data(63, 0)
sb_bus_rdata := Fill(64, (sb_axi_size === "h0".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 8.U * sb_axi_addr(2, 0)) & "hff".U(64.W)) |
Fill(64, (sb_axi_size === "h1".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 16.U * sb_axi_addr(2, 1)) & "hffff".U(64.W)) |
Fill(64, (sb_axi_size === "h2".U)) & ((io.sb_axi.r.bits.data(63, 0) >> 32.U * sb_axi_addr(2)) & "hffff_ffff".U(64.W)) |
Fill(64, (sb_axi_size === "h3".U)) & io.sb_axi.r.bits.data(63, 0)
// io.dbg_dma.dbg_ib.dbg_cmd_addr := io.dbg_dec_dma.dbg_ib.dbg_cmd_addr
// io.dbg_dma.dbg_dctl.dbg_cmd_wrdata := io.dbg_dec_dma.dbg_dctl.dbg_cmd_wrdata
// io.dbg_dma.dbg_ib.dbg_cmd_valid := io.dbg_dec_dma.dbg_ib.dbg_cmd_valid
// io.dbg_dma.dbg_ib.dbg_cmd_write := io.dbg_dec_dma.dbg_ib.dbg_cmd_write
// io.dbg_dma.dbg_ib.dbg_cmd_type := io.dbg_dec_dma.dbg_ib.dbg_cmd_type
}
object debug extends App {
(new chisel3.stage.ChiselStage).emitVerilog(new dbg)
}

View File

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

View File

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

View File

@ -17,17 +17,10 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val dctl_dma = new dctl_dma //connection with dma
val dec_aln = Flipped(new aln_dec) //connection with aligner
val dbg_dctl = new dbg_dctl() //connection with dbg
val dec_tlu_trace_disable = Input(Bool())
val dec_debug_valid_d = Input(Bool())
val dec_tlu_flush_extint = Input(Bool())
val dec_tlu_force_halt = Input(Bool()) // invalidate nonblock load cam on a force halt event
val dec_i0_inst_wb = Output(UInt(32.W)) // 32b instruction at wb+1 for trace encoder
val dec_i0_pc_wb = Output(UInt(31.W)) // 31b pc at wb+1 for trace encoder
val dec_i0_inst_wb1 = Output(UInt(32.W)) // 32b instruction at wb+1 for trace encoder
val dec_i0_pc_wb1 = Output(UInt(31.W)) // 31b pc at wb+1 for trace encoder
val dec_i0_trigger_match_d = Input(UInt(4.W)) // i0 decode trigger matches
val dec_tlu_wr_pause_r = Input(Bool()) // pause instruction at r
val dec_tlu_pipelining_disable = Input(Bool()) // pipeline disable - presync, i0 decode only
@ -37,19 +30,14 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val dec_tlu_flush_leak_one_r = Input(Bool()) // leak1 instruction
val dec_debug_fence_d = Input(Bool()) // debug fence instruction
val dec_i0_icaf_d = Input(Bool()) // icache access fault
val dec_i0_icaf_second_d = Input(Bool()) // i0 instruction access fault at decode for f1 fetch group
val dec_i0_icaf_f1_d = Input(Bool()) // i0 instruction access fault at decode for f1 fetch group
val dec_i0_icaf_type_d = Input(UInt(2.W)) // i0 instruction access fault type
val dec_i0_dbecc_d = Input(Bool()) // icache/iccm double-bit error
val dec_i0_brp = Flipped(Valid(new br_pkt_t)) // branch packet
val dec_i0_bp_index = Input(UInt(((BTB_ADDR_HI-BTB_ADDR_LO)+1).W)) // i0 branch index
val dec_i0_bp_fghr = Input(UInt(BHT_GHR_SIZE.W)) // BP FGHR
val dec_i0_bp_btag = Input(UInt(BTB_BTAG_SIZE.W)) // BP tag
val dec_i0_bp_fa_index = Input(UInt(log2Ceil(BTB_SIZE).W)) // Fully associt btb index
// val dec_i0_pc_d = Input(UInt(31.W)) // pc
val dec_i0_pc_d = Input(UInt(31.W)) // pc
val lsu_idle_any = Input(Bool()) // lsu idle: if fence instr & !!!!!!!!!!!!!!!!!!!!!!!!!lsu_idle then stall decode
val lsu_load_stall_any = Input(Bool()) // stall any load at decode
val lsu_store_stall_any = Input(Bool()) // stall any store at decode6
@ -69,21 +57,14 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val exu_flush_final = Input(Bool()) // lower flush or i0 flush at X or D
val dec_i0_instr_d = Input(UInt(32.W)) // inst at decode
val dec_ib0_valid_d = Input(Bool()) // inst valid at decode
val active_clk = Input(Clock()) // Clock only while core active. Through two clock headers. For flops without second clock header built in.
val free_l2clk = Input(Clock()) // Clock always. Through one clock header. For flops with second header built in.
val clk_override = Input(Bool()) // Override non-functional clock gating
val free_clk = Input(Clock())
val active_clk = Input(Clock()) // clk except for halt / pause
val clk_override = Input(Bool()) // test stuff
val dec_i0_rs1_d = Output(UInt(5.W)) // rs1 logical source
val dec_i0_rs2_d = Output(UInt(5.W))
val dec_i0_waddr_r = Output(UInt(5.W)) // i0 logical source to write to gpr's
val dec_i0_wen_r = Output(Bool()) // i0 write enable
val dec_i0_wdata_r = Output(UInt(32.W)) // i0 write data
// val dec_i0_branch_d = Output(Bool()) // Branch in D-stage
// val dec_i0_result_r = Output(UInt(32.W)) // Result R-stage
// val dec_qual_lsu_d = Output(Bool())// LSU instruction at D. Use to quiet LSU operands
val lsu_p = Valid(new lsu_pkt_t) // load/store packet
val div_waddr_wb = Output(UInt(5.W)) // DIV write address to GPR
val dec_lsu_valid_raw_d = Output(Bool())
@ -99,9 +80,6 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val dec_tlu_packet_r = Output(new trap_pkt_t) // trap packet
val dec_tlu_i0_pc_r = Output(UInt(31.W)) // i0 trap pc
val dec_illegal_inst = Output(UInt(32.W)) // illegal inst
val dec_fa_error_index = Output(UInt(log2Ceil(BTB_SIZE).W)) // Fully associt btb error index
val dec_pmu_instr_decoded = Output(Bool()) // number of instructions decode this cycle encoded
val dec_pmu_decode_stall = Output(Bool()) // decode is stalled
val dec_pmu_presync_stall = Output(Bool()) // decode has presync stall
@ -112,8 +90,7 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val dec_pause_state_cg = Output(Bool()) // pause state for clock-gating
val dec_div_active = Output(Bool()) // non-block divide is active
val scan_mode = Input(Bool())
val dec_i0_decode_d = Output(Bool())
})
})
//packets zero initialization
io.decode_exu.mul_p := 0.U.asTypeOf(io.decode_exu.mul_p)
// Vals defined
@ -196,32 +173,23 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
val i0_immed_d = WireInit(UInt(32.W), 0.U)
val i0_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
val data_gate_clk = rvclkhdr(clock,data_gate_en.asBool(),io.scan_mode)
// End - Data gating
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
@ -236,48 +204,23 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
// 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_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
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
if(BTB_FULLYA){
io.dec_fa_error_index := withClock(io.active_clk){RegNext(fa_error_index_ns,0.U)}
val btb_error_found_f = withClock(io.active_clk){RegNext(btb_error_found,0.B)}
btb_error_found := (i0_br_error_all | btb_error_found_f) & ~io.dec_tlu_flush_lower_r
fa_error_index_ns := Mux(i0_br_error_all & ~btb_error_found_f, io.dec_i0_bp_fa_index , io.dec_fa_error_index)
}else{
io.dec_fa_error_index := 0.U
}
}else{
io.decode_exu.dec_i0_predict_p_d := 0.U
io.decode_exu.dec_i0_predict_p_d.bits.pcall := i0_pcall // don't mark as pcall if branch error
io.decode_exu.dec_i0_predict_p_d.bits.pja := i0_pja
io.decode_exu.dec_i0_predict_p_d.bits.pret := i0_pret
io.decode_exu.dec_i0_predict_p_d.bits.pc4 := io.dec_i0_pc4_d
i0_br_error_all := 0.U
io.decode_exu.i0_predict_index_d := 0.U
io.decode_exu.i0_predict_btag_d := 0.U
io.decode_exu.i0_predict_fghr_d := 0.U
i0_brp_valid := 0.U
}
// end
// 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,7 +244,6 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
io.decode_exu.i0_ap.predict_nt := i0_predict_nt
io.decode_exu.i0_ap.predict_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
@ -316,31 +258,6 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
io.decode_exu.i0_ap.bne := i0_dp.bne
io.decode_exu.i0_ap.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
@ -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,11 +764,20 @@ class dec_decode_ctl extends Module with lib with RequireAsyncReset{
i0_rs2bypass := Cat((i0_rs2_depth_d(0) & (i0_rs2_class_d.alu | i0_rs2_class_d.mul)),(i0_rs2_depth_d(0) & (i0_rs2_class_d.load)),(i0_rs2_depth_d(1) & (i0_rs2_class_d.alu | i0_rs2_class_d.mul | i0_rs2_class_d.load)))
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),

View File

@ -10,8 +10,6 @@ class dec_ib_ctl_IO extends Bundle with param{
val ifu_ib = Flipped(new aln_ib)
val ib_exu = Flipped(new ib_exu)
val dbg_ib = new dbg_ib
val dec_debug_valid_d =Output(UInt(1.W))
val dec_ib0_valid_d =Output(UInt(1.W)) // ib0 valid
val dec_i0_icaf_type_d =Output(UInt(2.W)) // i0 instruction access fault type
val dec_i0_instr_d =Output(UInt(32.W)) // i0 inst at decode
@ -20,18 +18,15 @@ class dec_ib_ctl_IO extends Bundle with param{
val dec_i0_bp_index =Output(UInt(((BTB_ADDR_HI-BTB_ADDR_LO)+1).W)) // i0 branch index
val dec_i0_bp_fghr =Output(UInt(BHT_GHR_SIZE.W)) // BP FGHR
val dec_i0_bp_btag =Output(UInt(BTB_BTAG_SIZE.W)) // BP tag
val ifu_i0_fa_index =Input(UInt(log2Ceil(BTB_SIZE).W))
val dec_i0_bp_fa_index =Output(UInt(log2Ceil(BTB_SIZE).W))
val dec_i0_icaf_d =Output(UInt(1.W)) // i0 instruction access fault at decode
val dec_i0_icaf_second_d =Output(UInt(1.W)) // i0 instruction access fault at decode for f1 fetch group
val dec_i0_icaf_f1_d =Output(UInt(1.W)) // i0 instruction access fault at decode for f1 fetch group
val dec_i0_dbecc_d =Output(UInt(1.W)) // i0 double-bit error at decode
val dec_debug_fence_d =Output(UInt(1.W)) // debug fence inst
}
class dec_ib_ctl extends Module with param{
val io=IO(new dec_ib_ctl_IO)
io.dec_i0_icaf_second_d :=io.ifu_ib.ifu_i0_icaf_second
io.dec_i0_icaf_f1_d :=io.ifu_ib.ifu_i0_icaf_f1
io.dec_i0_dbecc_d :=io.ifu_ib.ifu_i0_dbecc
io.dec_i0_icaf_d :=io.ifu_ib.ifu_i0_icaf
io.ib_exu.dec_i0_pc_d :=io.ifu_ib.ifu_i0_pc
@ -41,7 +36,6 @@ class dec_ib_ctl extends Module with param{
io.dec_i0_bp_index :=io.ifu_ib.ifu_i0_bp_index
io.dec_i0_bp_fghr :=io.ifu_ib.ifu_i0_bp_fghr
io.dec_i0_bp_btag :=io.ifu_ib.ifu_i0_bp_btag
io.dec_i0_bp_fa_index := io.ifu_i0_fa_index
// GPR accesses
// put reg to read on rs1
@ -58,7 +52,7 @@ class dec_ib_ctl extends Module with param{
val debug_valid =io.dbg_ib.dbg_cmd_valid & (io.dbg_ib.dbg_cmd_type =/= 2.U)
val debug_read =debug_valid & !io.dbg_ib.dbg_cmd_write
val debug_write =debug_valid & io.dbg_ib.dbg_cmd_write
io.dec_debug_valid_d := debug_valid
val debug_read_gpr = debug_read & (io.dbg_ib.dbg_cmd_type===0.U)
val debug_write_gpr = debug_write & (io.dbg_ib.dbg_cmd_type===0.U)
val debug_read_csr = debug_read & (io.dbg_ib.dbg_cmd_type===1.U)
@ -83,4 +77,5 @@ class dec_ib_ctl extends Module with param{
io.dec_ib0_valid_d := io.ifu_ib.ifu_i0_valid | debug_valid
io.dec_i0_instr_d := Mux(debug_valid.asBool,ib0_debug_in,io.ifu_ib.ifu_i0_instr)
}

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
import chisel3._
import chisel3.util._
import include._
//import dbg._
import dbg._
import scala.collection._
import lib._
@ -12,89 +12,127 @@ class dma_ctrl extends Module with lib with RequireAsyncReset {
val dma_bus_clk_en = Input(Bool()) // slave bus clock enable
val clk_override = Input(Bool())
val scan_mode = Input(Bool())
val dbg_cmd_size = Input(UInt(2.W))
val dbg_cmd_size = Input(UInt(2.W)) // size of the abstract mem access debug command
val dma_dbg_rddata = Output(UInt(32.W))
val dma_dbg_cmd_done = Output(Bool())
val dma_dbg_cmd_fail = Output(Bool())
val dma_dbg_rddata = Output(UInt(32.W))
val iccm_dma_rvalid = Input(Bool())
val iccm_dma_ecc_error = Input(Bool())
val iccm_dma_rtag = Input(UInt(3.W))
val iccm_dma_rdata = Input(UInt(64.W))
val dma_active = Output(Bool())
val iccm_ready = Input(Bool())
val dbg_dec_dma = new dec_dbg()
val dbg_dma = new dbg_dma()
val dec_dma = Flipped(new dec_dma())
val lsu_dma = Flipped(new lsu_dma)
val ifu_dma = Flipped(new ifu_dma)// AXI Write Channel
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)
})
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 | dma_alignment_error | dma_dbg_cmd_error)
val RdPtrEn = (io.lsu_dma.dma_lsc_ctl.dma_dccm_req | io.ifu_dma.dma_mem_ctl.dma_iccm_req | (dma_address_error.asBool | dma_alignment_error.asBool | dma_dbg_cmd_error))
val RspPtrEn = (io.dma_dbg_cmd_done | (bus_rsp_sent | bus_posted_write_done) & io.dma_bus_clk_en)
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)
}
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 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)
// 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.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
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))
// 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)
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.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
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.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
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_rst = wrbuf_cmd_sent.asBool & !wrbuf_en
val wrbuf_data_rst = wrbuf_cmd_sent.asBool & !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)
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_cmd_sent = bus_cmd_sent & !bus_cmd_write
val rdbuf_rst = rdbuf_cmd_sent.asBool & !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)
rdbuf_vld := withClock(dma_bus_clk) {RegNext(Mux(rdbuf_en, 1.U, rdbuf_vld) & !rdbuf_rst, 0.U)}
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)
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_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, wrbuf_addr, rdbuf_addr)
bus_cmd_sz := Mux(axi_mstr_sel, wrbuf_sz, rdbuf_sz)
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, wrbuf_tag, rdbuf_tag)
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) )
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 := rvdffs_fpga(axi_mstr_prty_in.asUInt(),axi_mstr_prty_en,dma_bus_clk,io.dma_bus_clk_en,clock)
val axi_rsp_valid = fifo_valid(RspPtr) & ~fifo_dbg(RspPtr) & fifo_done_bus(RspPtr)
axi_mstr_priority := withClock(dma_bus_clk) {
RegEnable(axi_mstr_prty_in, 0.U, axi_mstr_prty_en.asBool)
}
val axi_rsp_valid = fifo_valid(RspPtr) & !fifo_dbg(RspPtr) & fifo_done_bus(RspPtr)
val axi_rsp_rdata = fifo_data(RspPtr)
val axi_rsp_write = fifo_write(RspPtr)
val axi_rsp_error = Mux(fifo_error(RspPtr)(0), 2.U,Mux(fifo_error(RspPtr)(1), 3.U, 0.U))
val axi_rsp_error = Mux(fifo_error(RspPtr)(0), 2.U, Mux(fifo_error(RspPtr)(1), 3.U, 0.U));
val axi_rsp_tag = fifo_tag(RspPtr)
// 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.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.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.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_sent := ((io.dma_axi.b.valid & io.dma_axi.b.ready) | (io.dma_axi.r.valid & io.dma_axi.r.ready))
io.lsu_dma.dma_dccm_ctl.dma_mem_addr := io.lsu_dma.dma_lsc_ctl.dma_mem_addr
io.lsu_dma.dma_dccm_ctl.dma_mem_wdata := io.lsu_dma.dma_lsc_ctl.dma_mem_wdata
io.ifu_dma.dma_mem_ctl.dma_mem_sz := io.lsu_dma.dma_lsc_ctl.dma_mem_sz
io.ifu_dma.dma_mem_ctl.dma_mem_addr := io.lsu_dma.dma_lsc_ctl.dma_mem_addr
io.ifu_dma.dma_mem_ctl.dma_mem_wdata := io.lsu_dma.dma_lsc_ctl.dma_mem_wdata
io.ifu_dma.dma_mem_ctl.dma_mem_write := io.lsu_dma.dma_lsc_ctl.dma_mem_write
io.ifu_dma.dma_mem_ctl.dma_mem_tag := io.lsu_dma.dma_mem_tag
}

View File

@ -21,12 +21,11 @@ class exu extends Module with lib with RequireAsyncReset{
val exu_div_wren = Output(UInt(1.W)) // Divide write enable to GPR
//debug
val dbg_cmd_wrdata = Input(UInt(32.W)) // Debug data to primary I0 RS1
val dec_csr_rddata_d = Input(UInt(32.W))
val lsu_nonblock_load_data = Input(UInt(32.W))
//lsu
val lsu_exu = Flipped(new lsu_exu())
//ifu_ifc
val exu_flush_path_final = Output(UInt(31.W)) // Target for the oldest flush source
})
val PREDPIPESIZE = BTB_ADDR_HI - BTB_ADDR_LO + BHT_GHR_SIZE + BTB_BTAG_SIZE +1
@ -36,7 +35,9 @@ class exu extends Module with lib with RequireAsyncReset{
val i0_taken_d = Wire(UInt(1.W))
val mul_valid_x = Wire(UInt(1.W))
val i0_valid_d = Wire(UInt(1.W))
val i0_branch_x = Wire(UInt(1.W))
val flush_lower_ff = Wire(UInt(1.W))
val data_gate_en = Wire(UInt(1.W))
val csr_rs1_in_d = Wire(UInt(32.W))
val i0_predict_newp_d = Wire(Valid(new predict_pkt_t()))
val i0_flush_path_d = Wire(UInt(31.W))
val i0_predict_p_d = Wire(Valid(new predict_pkt_t()))
@ -53,47 +54,52 @@ 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 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 :=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)
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)
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)
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(
@ -102,7 +108,6 @@ class exu extends Module with lib with RequireAsyncReset{
(!i0_rs1_bypass_en_d & io.dec_exu.ib_exu.dec_debug_wdata_rs1_d).asBool -> io.dbg_cmd_wrdata,
(!i0_rs1_bypass_en_d & !io.dec_exu.ib_exu.dec_debug_wdata_rs1_d & 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(
(!i0_rs2_bypass_en_d & io.dec_exu.decode_exu.dec_i0_rs2_en_d).asBool -> io.dec_exu.gpr_exu.gpr_i0_rs2_d,
@ -112,14 +117,14 @@ class exu extends Module with lib with RequireAsyncReset{
dontTouch(i0_rs2_d)
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(
@ -127,14 +132,21 @@ class exu extends Module with lib with RequireAsyncReset{
(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.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
@ -150,16 +162,16 @@ class exu extends Module with lib with RequireAsyncReset{
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.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.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
@ -176,33 +188,33 @@ 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),
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)
ghr_x_ns:=Mux(i0_valid_x===1.U, Cat(ghr_x(BHT_GHR_SIZE-2,0),i0_taken_x), 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_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_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)
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)
val after_flush_eghr = Mux((i0_flush_upper_x===1.U & !(io.dec_exu.tlu_exu.dec_tlu_flush_lower_r===1.U)), ghr_d, ghr_x)
val after_flush_eghr = Mux((i0_flush_upper_x === 1.U & !(io.dec_exu.tlu_exu.dec_tlu_flush_lower_r === 1.U)), ghr_d, ghr_x)
io.exu_bp.exu_mp_pkt.valid := final_predict_mp.valid
io.exu_bp.exu_mp_pkt.bits.way := final_predict_mp.bits.way
io.exu_bp.exu_mp_pkt.bits.misp := final_predict_mp.bits.misp
io.exu_bp.exu_mp_pkt.bits.pcall := final_predict_mp.bits.pcall
@ -211,38 +223,13 @@ class exu extends Module with lib with RequireAsyncReset{
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_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 {
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_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()))
}

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