RISC_V_LAB hinzugefügt
This commit is contained in:
commit
3c0ec38544
BIN
.cleanup_lukas.sh.swp
Normal file
BIN
.cleanup_lukas.sh.swp
Normal file
Binary file not shown.
BIN
Documents/A Quick Start to the Oasys-RTL Tool.pdf
Normal file
BIN
Documents/A Quick Start to the Oasys-RTL Tool.pdf
Normal file
Binary file not shown.
33963
Documents/Oasys-RTL™ Command Reference Manual.pdf
Normal file
33963
Documents/Oasys-RTL™ Command Reference Manual.pdf
Normal file
File diff suppressed because one or more lines are too long
16
cleanup.sh
Executable file
16
cleanup.sh
Executable file
@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
rm -rf oasys.cmd*
|
||||||
|
rm -rf oasys.dbg*
|
||||||
|
rm -rf oasys.log*
|
||||||
|
rm -rf output
|
||||||
|
mkdir output
|
||||||
|
mkdir output/odb
|
||||||
|
mkdir output/db
|
||||||
|
mkdir output/logs
|
||||||
|
rm -rf `find . -type f -name "oasys.*"`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
echo "\n-------------------------------------"
|
||||||
|
echo "\nCleanup Complete"
|
||||||
|
echo "\n-------------------------------------\n"
|
||||||
7
commands_help.txt
Normal file
7
commands_help.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
To find the address:
|
||||||
|
$which tool_name
|
||||||
|
|
||||||
|
|
||||||
|
To run a script:
|
||||||
|
|
||||||
|
$source scripts_counter/1_read_design.tcl
|
||||||
BIN
constraints/.riscv.sdc.swp
Normal file
BIN
constraints/.riscv.sdc.swp
Normal file
Binary file not shown.
29
constraints/define_regions.def
Executable file
29
constraints/define_regions.def
Executable file
@ -0,0 +1,29 @@
|
|||||||
|
#
|
||||||
|
# Created by Oasys-RTL -- (c) Mentor Graphics Corporation
|
||||||
|
#
|
||||||
|
VERSION 5.8 ;
|
||||||
|
NAMESCASESENSITIVE ON ;
|
||||||
|
DIVIDERCHAR "/" ;
|
||||||
|
BUSBITCHARS "[]" ;
|
||||||
|
DESIGN demo_chip ;
|
||||||
|
UNITS DISTANCE MICRONS 2000 ;
|
||||||
|
|
||||||
|
PROPERTYDEFINITIONS
|
||||||
|
END PROPERTYDEFINITIONS
|
||||||
|
|
||||||
|
DIEAREA ( 0 0 ) ( 2834850 2834850 ) ;
|
||||||
|
|
||||||
|
REGIONS 2 ;
|
||||||
|
- __r__6 ( 64840 50430 ) ( 1549550 1203580 ) ;
|
||||||
|
- __r__7 ( 1254060 1513530 ) ( 2803620 2767590 ) ;
|
||||||
|
END REGIONS
|
||||||
|
COMPONENTS 352 ;
|
||||||
|
- i_cpu_sys cpu_sys
|
||||||
|
+ REGION __r__6
|
||||||
|
;
|
||||||
|
- i_usbf usb_sys
|
||||||
|
+ REGION __r__7
|
||||||
|
;
|
||||||
|
END COMPONENTS
|
||||||
|
|
||||||
|
END DESIGN
|
||||||
76
constraints/riscv.sdc
Normal file
76
constraints/riscv.sdc
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# Constraints File: cpu.sdc
|
||||||
|
# Project: BCDC Microtec Academy - RISC-V CPU
|
||||||
|
# Top Module: cpu
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# 1. Primary Clock - 25 MHz input clock
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
create_clock -name clk_25mhz \
|
||||||
|
-period 40.000 \
|
||||||
|
-waveform {0 20} \
|
||||||
|
[get_ports clk_25mhz]
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# 2. Generated Clock - 12.5 MHz (divided by 2 inside always_ff)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
#create_generated_clock -name clk_12p5 \
|
||||||
|
-source [get_ports clk_25mhz] \
|
||||||
|
-divide_by 2 \
|
||||||
|
[get_pins thePC/clk]
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# 3. Clock Uncertainty & Transition
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
set_clock_uncertainty -setup 0.5 [get_clocks clk_25mhz]
|
||||||
|
set_clock_uncertainty -hold 0.2 [get_clocks clk_25mhz]
|
||||||
|
|
||||||
|
set_clock_transition 0.1 [get_clocks clk_25mhz]
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# 4. Input Delays (btn pins - relative to clk_25mhz)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
set_input_delay -clock clk_25mhz -max 2.0 [get_ports {btn[*]}]
|
||||||
|
set_input_delay -clock clk_25mhz -min 0.5 [get_ports {btn[*]}]
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# 5. Output Delays (led pins)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
set_output_delay -clock clk_25mhz -max 2.0 [get_ports {led[*]}]
|
||||||
|
set_output_delay -clock clk_25mhz -min 0.5 [get_ports {led[*]}]
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# 6. False Paths
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Reset is async and driven from a button - no timing analysis needed
|
||||||
|
set_false_path -from [get_ports {btn[0]}]
|
||||||
|
|
||||||
|
# LED outputs driven from combinational/slow logic - relax if needed
|
||||||
|
# set_false_path -to [get_ports {led[*]}]
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# 7. Clock Domain Crossing
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# clk12p5 is derived from clk_25mhz via FF division - set as async crossing
|
||||||
|
# to prevent hold violations across the two domains
|
||||||
|
#set_clock_groups -asynchronous \
|
||||||
|
-group [get_clocks clk_25mhz] \
|
||||||
|
-group [get_clocks clk_12p5]
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# 8. Drive Strength & Load (adjust to your target technology)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
#set_driving_cell -lib_cell <YOUR_INPUT_BUF> [get_ports {btn[*]}]
|
||||||
|
|
||||||
|
set_driving_cell -lib_cell BUF_X1_HVT -library NangateOpenCellLibrary_45nm_HVT_0p85 [get_ports {btn[*]}]
|
||||||
|
|
||||||
|
set_load 0.05 [get_ports {led[*]}]
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# 9. Max Fanout & Transition
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
set_max_fanout 20 [current_design]
|
||||||
|
set_max_transition 0.5 [current_design]
|
||||||
|
|
||||||
|
|
||||||
16
docs/LICENSE_Nangate.txt
Executable file
16
docs/LICENSE_Nangate.txt
Executable file
@ -0,0 +1,16 @@
|
|||||||
|
The Open Cell Library is intended for use by universities, other research activities, educational programs and Si2.org members.
|
||||||
|
However allowed, the Open Cell Library is not intended for commercial use. If you use the Open Cell Library for demonstration of commercial EDA tools
|
||||||
|
it is required to mention, indicate that the library was developped by Nangate.
|
||||||
|
|
||||||
|
If you have questions or concerns then please contact us at openlibrary@nangate.com
|
||||||
|
|
||||||
|
The Open Cell Library is provided by Nangate under the following License:
|
||||||
|
|
||||||
|
Nangate Open Cell Library License, Version 1.0. February 20, 2008
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the Open Cell Library and accompanying documentation (the "Library") covered by this license to use, reproduce, display, distribute, execute, and transmit the Library, and to prepare derivative works of the Library, and to permit third-parties to whom the Library is furnished to do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Library and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Library, in whole or in part, and all derivative works of the Library, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. The library has been generated using a non-optimized open PDK and is not suited for any commercial purpose. Measuring or benchmarking the Library against any other library or standard cell set is prohibited. Any meaningful library benchmarking must be done in collaboration with Nangate or other providers of optimized and production-ready PDKs.
|
||||||
|
|
||||||
|
THE LIBRARY IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE LIBRARY BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE LIBRARY OR THE USE OR OTHER DEALINGS IN THE LIBRARY.
|
||||||
|
|
||||||
BIN
libs/.MemGen_16_10.memlib.swp
Normal file
BIN
libs/.MemGen_16_10.memlib.swp
Normal file
Binary file not shown.
35
libs/MemGen_16_10.memlib
Normal file
35
libs/MemGen_16_10.memlib
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
Core (MemGen_16_10) {
|
||||||
|
Memory {
|
||||||
|
Port (clock) {
|
||||||
|
Function = Clock;
|
||||||
|
}
|
||||||
|
Port (chip_en) {
|
||||||
|
Function = Select;
|
||||||
|
Polarity = activeHigh;
|
||||||
|
}
|
||||||
|
Port (rd_en) {
|
||||||
|
Function = ReadEnable;
|
||||||
|
Polarity = activeHigh;
|
||||||
|
}
|
||||||
|
Port (wr_en) {
|
||||||
|
Function = WriteEnable;
|
||||||
|
Polarity = activeHigh;
|
||||||
|
}
|
||||||
|
Port (addr[9:0]) {
|
||||||
|
Function = Address;
|
||||||
|
}
|
||||||
|
Port (wr_data[15:0]) {
|
||||||
|
Function = Data;
|
||||||
|
Direction = Input;
|
||||||
|
}
|
||||||
|
Port (rd_data[15:0]) {
|
||||||
|
Function = Data;
|
||||||
|
Direction = Output;
|
||||||
|
}
|
||||||
|
AddressCounter {
|
||||||
|
Function (address) {
|
||||||
|
CountRange = [0 1023];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6777
libs/NCSU_FreePDK_45nm.ptf
Executable file
6777
libs/NCSU_FreePDK_45nm.ptf
Executable file
File diff suppressed because it is too large
Load Diff
43
libs/fastscan/IO.fslib
Executable file
43
libs/fastscan/IO.fslib
Executable file
@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
library_format_version = 9;
|
||||||
|
|
||||||
|
array_delimiter = "[]";
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// ***********************************************************************
|
||||||
|
// *********** Models holding Liberty information ******************
|
||||||
|
// ***********************************************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
model PADBID
|
||||||
|
(C, I, OEN, PAD)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = pad;
|
||||||
|
|
||||||
|
input (I) ( pad_to_pad; )
|
||||||
|
input (OEN) ( pad_enable_low; )
|
||||||
|
inout (PAD) ( pad_pad_io; )
|
||||||
|
output (C) ( pad_from_pad; )
|
||||||
|
(
|
||||||
|
primitive = _buf (PAD, C);
|
||||||
|
primitive = _tsl (I, OEN, PAD);
|
||||||
|
)
|
||||||
|
) // end model PADBID
|
||||||
|
|
||||||
|
|
||||||
|
model PADCLK
|
||||||
|
(C, PAD)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = pad;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (PAD) ( pad_from_io; )
|
||||||
|
output (C) ( pad_from_pad; )
|
||||||
|
(
|
||||||
|
primitive = _buf (PAD, C);
|
||||||
|
)
|
||||||
|
) // end model PADCLK
|
||||||
583
libs/fastscan/LowPowerOpenCellLibrary_low_temp_ccs.fslib
Executable file
583
libs/fastscan/LowPowerOpenCellLibrary_low_temp_ccs.fslib
Executable file
@ -0,0 +1,583 @@
|
|||||||
|
//
|
||||||
|
// ***********************************************************************
|
||||||
|
// Copyright Mentor Graphics Corporation
|
||||||
|
// All Rights Reserved
|
||||||
|
// For use only with Mentor Graphics Tessent tools
|
||||||
|
// ***********************************************************************
|
||||||
|
// File Type: Tessent Cell Library
|
||||||
|
// Generated by: Tessent Shell -- write_cell_library
|
||||||
|
// Tool Version: 2019.4
|
||||||
|
// Tool Build Date: Wed Nov 20 21:14:16 GMT 2019
|
||||||
|
// ***********************************************************************
|
||||||
|
// Library Created : Local Time = Tue Jun 30 00:33:32 2020
|
||||||
|
// GMT = Tue Jun 30 07:33:32 2020
|
||||||
|
|
||||||
|
|
||||||
|
library_format_version = 9;
|
||||||
|
|
||||||
|
array_delimiter = "[]";
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// ***********************************************************************
|
||||||
|
// *********** Models holding Liberty information ******************
|
||||||
|
// ***********************************************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
model AON_BUF_X1
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_BUF_X1
|
||||||
|
|
||||||
|
|
||||||
|
model AON_BUF_X2
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_BUF_X2
|
||||||
|
|
||||||
|
|
||||||
|
model AON_BUF_X4
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_BUF_X4
|
||||||
|
|
||||||
|
|
||||||
|
model AON_INV_X1
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = inverter;
|
||||||
|
simulation_function = inverter;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_INV_X1
|
||||||
|
|
||||||
|
|
||||||
|
model AON_INV_X2
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = inverter;
|
||||||
|
simulation_function = inverter;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_INV_X2
|
||||||
|
|
||||||
|
|
||||||
|
model AON_INV_X4
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = inverter;
|
||||||
|
simulation_function = inverter;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_INV_X4
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_OE_X1
|
||||||
|
(SLEEP, SLEEPOUT)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
output (SLEEPOUT) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (SLEEP, SLEEPOUT);
|
||||||
|
)
|
||||||
|
) // end model HEADER_OE_X1
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_OE_X2
|
||||||
|
(SLEEP, SLEEPOUT)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
output (SLEEPOUT) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (SLEEP, SLEEPOUT);
|
||||||
|
)
|
||||||
|
) // end model HEADER_OE_X2
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_OE_X4
|
||||||
|
(SLEEP, SLEEPOUT)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
output (SLEEPOUT) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (SLEEP, SLEEPOUT);
|
||||||
|
)
|
||||||
|
) // end model HEADER_OE_X4
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_X1
|
||||||
|
(SLEEP)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
(
|
||||||
|
// Empty Model
|
||||||
|
)
|
||||||
|
) // end model HEADER_X1
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_X2
|
||||||
|
(SLEEP)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
(
|
||||||
|
// Empty Model
|
||||||
|
)
|
||||||
|
) // end model HEADER_X2
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_X4
|
||||||
|
(SLEEP)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
(
|
||||||
|
// Empty Model
|
||||||
|
)
|
||||||
|
) // end model HEADER_X4
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0N_X1
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0N_X1
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0N_X2
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0N_X2
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0N_X4
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0N_X4
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0_X1
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nor;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _or (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0_X1
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0_X2
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nor;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _or (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0_X2
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0_X4
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nor;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _or (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0_X4
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1N_X1
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nand;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _and (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1N_X1
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1N_X2
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nand;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _and (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1N_X2
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1N_X4
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nand;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _and (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1N_X4
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1_X1
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = or;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _or (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1_X1
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1_X2
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = or;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _or (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1_X2
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1_X4
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = or;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _or (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1_X4
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HLEN_X1
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HLEN_X1
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HLEN_X2
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HLEN_X2
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HLEN_X4
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HLEN_X4
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HL_X1
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HL_X1
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HL_X2
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HL_X2
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HL_X4
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HL_X4
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LHEN_X1
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LHEN_X1
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LHEN_X2
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LHEN_X2
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LHEN_X4
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LHEN_X4
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LH_X1
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LH_X1
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LH_X2
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LH_X2
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LH_X4
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LH_X4
|
||||||
583
libs/fastscan/LowPowerOpenCellLibrary_worst_low_ccs.fslib
Executable file
583
libs/fastscan/LowPowerOpenCellLibrary_worst_low_ccs.fslib
Executable file
@ -0,0 +1,583 @@
|
|||||||
|
//
|
||||||
|
// ***********************************************************************
|
||||||
|
// Copyright Mentor Graphics Corporation
|
||||||
|
// All Rights Reserved
|
||||||
|
// For use only with Mentor Graphics Tessent tools
|
||||||
|
// ***********************************************************************
|
||||||
|
// File Type: Tessent Cell Library
|
||||||
|
// Generated by: Tessent Shell -- write_cell_library
|
||||||
|
// Tool Version: 2019.4
|
||||||
|
// Tool Build Date: Wed Nov 20 21:14:16 GMT 2019
|
||||||
|
// ***********************************************************************
|
||||||
|
// Library Created : Local Time = Tue Jun 30 00:33:32 2020
|
||||||
|
// GMT = Tue Jun 30 07:33:32 2020
|
||||||
|
|
||||||
|
|
||||||
|
library_format_version = 9;
|
||||||
|
|
||||||
|
array_delimiter = "[]";
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// ***********************************************************************
|
||||||
|
// *********** Models holding Liberty information ******************
|
||||||
|
// ***********************************************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
model AON_BUF_X1
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_BUF_X1
|
||||||
|
|
||||||
|
|
||||||
|
model AON_BUF_X2
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_BUF_X2
|
||||||
|
|
||||||
|
|
||||||
|
model AON_BUF_X4
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_BUF_X4
|
||||||
|
|
||||||
|
|
||||||
|
model AON_INV_X1
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = inverter;
|
||||||
|
simulation_function = inverter;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_INV_X1
|
||||||
|
|
||||||
|
|
||||||
|
model AON_INV_X2
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = inverter;
|
||||||
|
simulation_function = inverter;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_INV_X2
|
||||||
|
|
||||||
|
|
||||||
|
model AON_INV_X4
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = inverter;
|
||||||
|
simulation_function = inverter;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_INV_X4
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_OE_X1
|
||||||
|
(SLEEP, SLEEPOUT)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
output (SLEEPOUT) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (SLEEP, SLEEPOUT);
|
||||||
|
)
|
||||||
|
) // end model HEADER_OE_X1
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_OE_X2
|
||||||
|
(SLEEP, SLEEPOUT)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
output (SLEEPOUT) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (SLEEP, SLEEPOUT);
|
||||||
|
)
|
||||||
|
) // end model HEADER_OE_X2
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_OE_X4
|
||||||
|
(SLEEP, SLEEPOUT)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
output (SLEEPOUT) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (SLEEP, SLEEPOUT);
|
||||||
|
)
|
||||||
|
) // end model HEADER_OE_X4
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_X1
|
||||||
|
(SLEEP)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
(
|
||||||
|
// Empty Model
|
||||||
|
)
|
||||||
|
) // end model HEADER_X1
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_X2
|
||||||
|
(SLEEP)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
(
|
||||||
|
// Empty Model
|
||||||
|
)
|
||||||
|
) // end model HEADER_X2
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_X4
|
||||||
|
(SLEEP)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
(
|
||||||
|
// Empty Model
|
||||||
|
)
|
||||||
|
) // end model HEADER_X4
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0N_X1
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0N_X1
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0N_X2
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0N_X2
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0N_X4
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0N_X4
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0_X1
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nor;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _or (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0_X1
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0_X2
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nor;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _or (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0_X2
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0_X4
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nor;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _or (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0_X4
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1N_X1
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nand;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _and (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1N_X1
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1N_X2
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nand;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _and (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1N_X2
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1N_X4
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nand;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _and (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1N_X4
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1_X1
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = or;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _or (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1_X1
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1_X2
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = or;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _or (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1_X2
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1_X4
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = or;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _or (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1_X4
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HLEN_X1
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HLEN_X1
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HLEN_X2
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HLEN_X2
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HLEN_X4
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HLEN_X4
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HL_X1
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HL_X1
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HL_X2
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HL_X2
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HL_X4
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HL_X4
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LHEN_X1
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LHEN_X1
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LHEN_X2
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LHEN_X2
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LHEN_X4
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LHEN_X4
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LH_X1
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LH_X1
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LH_X2
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LH_X2
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LH_X4
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LH_X4
|
||||||
583
libs/fastscan/LowPowerOpenCellLibrary_worst_low_ccs_0.85v.fslib
Executable file
583
libs/fastscan/LowPowerOpenCellLibrary_worst_low_ccs_0.85v.fslib
Executable file
@ -0,0 +1,583 @@
|
|||||||
|
//
|
||||||
|
// ***********************************************************************
|
||||||
|
// Copyright Mentor Graphics Corporation
|
||||||
|
// All Rights Reserved
|
||||||
|
// For use only with Mentor Graphics Tessent tools
|
||||||
|
// ***********************************************************************
|
||||||
|
// File Type: Tessent Cell Library
|
||||||
|
// Generated by: Tessent Shell -- write_cell_library
|
||||||
|
// Tool Version: 2019.4
|
||||||
|
// Tool Build Date: Wed Nov 20 21:14:16 GMT 2019
|
||||||
|
// ***********************************************************************
|
||||||
|
// Library Created : Local Time = Tue Jun 30 00:33:33 2020
|
||||||
|
// GMT = Tue Jun 30 07:33:33 2020
|
||||||
|
|
||||||
|
|
||||||
|
library_format_version = 9;
|
||||||
|
|
||||||
|
array_delimiter = "[]";
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// ***********************************************************************
|
||||||
|
// *********** Models holding Liberty information ******************
|
||||||
|
// ***********************************************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
model AON_BUF_X1
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_BUF_X1
|
||||||
|
|
||||||
|
|
||||||
|
model AON_BUF_X2
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_BUF_X2
|
||||||
|
|
||||||
|
|
||||||
|
model AON_BUF_X4
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_BUF_X4
|
||||||
|
|
||||||
|
|
||||||
|
model AON_INV_X1
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = inverter;
|
||||||
|
simulation_function = inverter;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_INV_X1
|
||||||
|
|
||||||
|
|
||||||
|
model AON_INV_X2
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = inverter;
|
||||||
|
simulation_function = inverter;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_INV_X2
|
||||||
|
|
||||||
|
|
||||||
|
model AON_INV_X4
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = inverter;
|
||||||
|
simulation_function = inverter;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (A, Z);
|
||||||
|
)
|
||||||
|
) // end model AON_INV_X4
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_OE_X1
|
||||||
|
(SLEEP, SLEEPOUT)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
output (SLEEPOUT) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (SLEEP, SLEEPOUT);
|
||||||
|
)
|
||||||
|
) // end model HEADER_OE_X1
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_OE_X2
|
||||||
|
(SLEEP, SLEEPOUT)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
output (SLEEPOUT) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (SLEEP, SLEEPOUT);
|
||||||
|
)
|
||||||
|
) // end model HEADER_OE_X2
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_OE_X4
|
||||||
|
(SLEEP, SLEEPOUT)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
output (SLEEPOUT) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (SLEEP, SLEEPOUT);
|
||||||
|
)
|
||||||
|
) // end model HEADER_OE_X4
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_X1
|
||||||
|
(SLEEP)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
(
|
||||||
|
// Empty Model
|
||||||
|
)
|
||||||
|
) // end model HEADER_X1
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_X2
|
||||||
|
(SLEEP)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
(
|
||||||
|
// Empty Model
|
||||||
|
)
|
||||||
|
) // end model HEADER_X2
|
||||||
|
|
||||||
|
|
||||||
|
model HEADER_X4
|
||||||
|
(SLEEP)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
|
||||||
|
input (SLEEP) ( )
|
||||||
|
(
|
||||||
|
// Empty Model
|
||||||
|
)
|
||||||
|
) // end model HEADER_X4
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0N_X1
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0N_X1
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0N_X2
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0N_X2
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0N_X4
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0N_X4
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0_X1
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nor;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _or (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0_X1
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0_X2
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nor;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _or (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0_X2
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE0_X4
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nor;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _or (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE0_X4
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1N_X1
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nand;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _and (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1N_X1
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1N_X2
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nand;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _and (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1N_X2
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1N_X4
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = nand;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _inv (net_0, Z);
|
||||||
|
primitive = _and (A, EN, net_0);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1N_X4
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1_X1
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = or;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _or (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1_X1
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1_X2
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = or;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _or (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1_X2
|
||||||
|
|
||||||
|
|
||||||
|
model ISO_FENCE1_X4
|
||||||
|
(A, EN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
simulation_function = or;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (EN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _or (A, EN, Z);
|
||||||
|
)
|
||||||
|
) // end model ISO_FENCE1_X4
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HLEN_X1
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HLEN_X1
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HLEN_X2
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HLEN_X2
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HLEN_X4
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HLEN_X4
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HL_X1
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HL_X1
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HL_X2
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HL_X2
|
||||||
|
|
||||||
|
|
||||||
|
model LS_HL_X4
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_HL_X4
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LHEN_X1
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LHEN_X1
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LHEN_X2
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LHEN_X2
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LHEN_X4
|
||||||
|
(A, ISOLN, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = and;
|
||||||
|
simulation_function = and;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
input (ISOLN) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _and (A, ISOLN, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LHEN_X4
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LH_X1
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LH_X1
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LH_X2
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LH_X2
|
||||||
|
|
||||||
|
|
||||||
|
model LS_LH_X4
|
||||||
|
(A, Z)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = buffer;
|
||||||
|
simulation_function = buffer;
|
||||||
|
|
||||||
|
input (A) ( )
|
||||||
|
output (Z) ( )
|
||||||
|
(
|
||||||
|
primitive = _buf (A, Z);
|
||||||
|
)
|
||||||
|
) // end model LS_LH_X4
|
||||||
2665
libs/fastscan/NangateOpenCellLibrary_45nm_HVT_worst_low_0p85V_conditional_nldm.fslib
Executable file
2665
libs/fastscan/NangateOpenCellLibrary_45nm_HVT_worst_low_0p85V_conditional_nldm.fslib
Executable file
File diff suppressed because it is too large
Load Diff
2665
libs/fastscan/NangateOpenCellLibrary_45nm_HVT_worst_low_conditional_nldm.fslib
Executable file
2665
libs/fastscan/NangateOpenCellLibrary_45nm_HVT_worst_low_conditional_nldm.fslib
Executable file
File diff suppressed because it is too large
Load Diff
2665
libs/fastscan/NangateOpenCellLibrary_45nm_LVT_slow_0p85V_conditional_nldm.fslib
Executable file
2665
libs/fastscan/NangateOpenCellLibrary_45nm_LVT_slow_0p85V_conditional_nldm.fslib
Executable file
File diff suppressed because it is too large
Load Diff
2665
libs/fastscan/NangateOpenCellLibrary_45nm_LVT_worst_low_conditional_nldm.fslib
Executable file
2665
libs/fastscan/NangateOpenCellLibrary_45nm_LVT_worst_low_conditional_nldm.fslib
Executable file
File diff suppressed because it is too large
Load Diff
2665
libs/fastscan/NangateOpenCellLibrary_45nm_SVT_slow_0p85V_conditional_nldm.fslib
Executable file
2665
libs/fastscan/NangateOpenCellLibrary_45nm_SVT_slow_0p85V_conditional_nldm.fslib
Executable file
File diff suppressed because it is too large
Load Diff
2665
libs/fastscan/NangateOpenCellLibrary_45nm_SVT_worst_low_conditional_nldm.fslib
Executable file
2665
libs/fastscan/NangateOpenCellLibrary_45nm_SVT_worst_low_conditional_nldm.fslib
Executable file
File diff suppressed because it is too large
Load Diff
2633
libs/fastscan/NangateOpenCellLibrary_low_temp_ccs.fslib
Executable file
2633
libs/fastscan/NangateOpenCellLibrary_low_temp_ccs.fslib
Executable file
File diff suppressed because it is too large
Load Diff
2633
libs/fastscan/NangateOpenCellLibrary_worst_low_ccs_0.85v.fslib
Executable file
2633
libs/fastscan/NangateOpenCellLibrary_worst_low_ccs_0.85v.fslib
Executable file
File diff suppressed because it is too large
Load Diff
57
libs/fastscan/PLL.fslib
Executable file
57
libs/fastscan/PLL.fslib
Executable file
@ -0,0 +1,57 @@
|
|||||||
|
|
||||||
|
|
||||||
|
library_format_version = 9;
|
||||||
|
|
||||||
|
array_delimiter = "[]";
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// ***********************************************************************
|
||||||
|
// *********** Models holding Liberty information ******************
|
||||||
|
// ***********************************************************************
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
model PLL
|
||||||
|
(BYPASS, DIVF0, DIVF1, DIVF2,
|
||||||
|
DIVF3, DIVF4, DIVF5, DIVF6,
|
||||||
|
DIVF7, DIVQ0, DIVQ1, DIVQ2,
|
||||||
|
DIVR0, DIVR1, DIVR2, DIVR3,
|
||||||
|
DIVR4, DIVR5, FB, FSE,
|
||||||
|
LOCK, PLLOUT, RANGE0, RANGE1,
|
||||||
|
RANGE2, REF, RESET)
|
||||||
|
(
|
||||||
|
model_source = liberty_cell;
|
||||||
|
cell_type = prohibited;
|
||||||
|
|
||||||
|
input (BYPASS) ( )
|
||||||
|
input (DIVF0) ( )
|
||||||
|
input (DIVF1) ( )
|
||||||
|
input (DIVF2) ( )
|
||||||
|
input (DIVF3) ( )
|
||||||
|
input (DIVF4) ( )
|
||||||
|
input (DIVF5) ( )
|
||||||
|
input (DIVF6) ( )
|
||||||
|
input (DIVF7) ( )
|
||||||
|
input (DIVQ0) ( )
|
||||||
|
input (DIVQ1) ( )
|
||||||
|
input (DIVQ2) ( )
|
||||||
|
input (DIVR0) ( )
|
||||||
|
input (DIVR1) ( )
|
||||||
|
input (DIVR2) ( )
|
||||||
|
input (DIVR3) ( )
|
||||||
|
input (DIVR4) ( )
|
||||||
|
input (DIVR5) ( )
|
||||||
|
input (FB) ( )
|
||||||
|
input (FSE) ( )
|
||||||
|
input (RANGE0) ( )
|
||||||
|
input (RANGE1) ( )
|
||||||
|
input (RANGE2) ( )
|
||||||
|
input (REF) ( )
|
||||||
|
input (RESET) ( )
|
||||||
|
output (LOCK) ( )
|
||||||
|
output (PLLOUT) ( )
|
||||||
|
(
|
||||||
|
// Empty Model
|
||||||
|
)
|
||||||
|
) // end model PLL
|
||||||
BIN
libs/nangate_mvt.odb
Normal file
BIN
libs/nangate_mvt.odb
Normal file
Binary file not shown.
276
riscv_rtl/README.md
Normal file
276
riscv_rtl/README.md
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
# [RISC-V Desgin in an Open_Source Design Flow](https://microtec-academy.de/produkt/risc-v-design-in-an-open-source-design-flow/)
|
||||||
|
|
||||||
|
A RISC-V design course, where you learn about the the RISC-V theory and then use it to build your own RISC-V processor.
|
||||||
|
|
||||||
|
This project has the full solution for the course exercises. It is able to simulate the Decoder or CPU as DUTs (device under tests). The simulation executes a SW test from a designated Hex file on the DUT.
|
||||||
|
|
||||||
|
In this README you will learn about ...
|
||||||
|
|
||||||
|
* what **prerequisites** you need to get this project running
|
||||||
|
* how the project is **organised**
|
||||||
|
* how to **run simulations**
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
This course is a part of the initiative [*Bavarian Chip Design Center (BCDC)*](https://www.iis.fraunhofer.de/en/ff/sse/bavarian-chip-design-center.html), which aims to develop and improve the IC-Design workforce in Bavaria.
|
||||||
|
|
||||||
|
This course is an adaptation of the code-base developed at [Lund University](https://www.lth.se/) by Per Andersson as part of the effort to develop and improve education in Digital System Design. You can find the original source-code under [this repository](https://github.com/PalePrime/single_cycle).
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
Bash Shell Terminal
|
||||||
|
|
||||||
|
* Windows: you need to install gitbash or use something similar
|
||||||
|
* MacOS/Linux: bash is preinstalled
|
||||||
|
|
||||||
|
GCC Compiler
|
||||||
|
|
||||||
|
* Installation details [here](https://gcc.gnu.org/install/)
|
||||||
|
|
||||||
|
Verilator
|
||||||
|
|
||||||
|
* If not installed, you can find the installation [here](https://verilator.org/guide/latest/install.html). It is highly recommended to install through a package manager for all operating systems.
|
||||||
|
* For Linux use apt package manager. Info under [verilator install guide](https://verilator.org/guide/latest/install.html#package-manager-quick-install).
|
||||||
|
* For MacOS the package manager is [homebrew](https://brew.sh/).
|
||||||
|
* For Windows an package manager option is [pacman](https://gist.github.com/AndreSteenveld/cb6662c93c8323795c5fd347defb8976) (untested).
|
||||||
|
* Export the *VERILATOR* environment variable. Make sure to use your Verilator install directory -> `export VERILATOR=</path/to/verilator>/bin/verilator`
|
||||||
|
|
||||||
|
Surfer Waveform Viewer
|
||||||
|
|
||||||
|
* If not installed, you can find the installation [here](https://surfer-project.org/)
|
||||||
|
* Export the *WAVE_VIEWER* environment variables. Make sure to use your Surfer install directory -> `export WAVE_VIEWER=</path/to/surfer>/surfer`
|
||||||
|
|
||||||
|
IDE (optional)
|
||||||
|
|
||||||
|
* Any IDE of your choosing will make it easy to view and manage the files
|
||||||
|
|
||||||
|
## Project Organisation
|
||||||
|
|
||||||
|
### Resources
|
||||||
|
|
||||||
|
Path: `doc`
|
||||||
|
|
||||||
|
* Module diagrams
|
||||||
|
* RISC-V Cards
|
||||||
|
* RISC-V ISM
|
||||||
|
* RISC-V ASM
|
||||||
|
|
||||||
|
### RTL source code
|
||||||
|
|
||||||
|
Path: `hw/rtl`
|
||||||
|
|
||||||
|
### File lists of SV code
|
||||||
|
|
||||||
|
Path: `hw/file_lists`
|
||||||
|
|
||||||
|
* RTL file list
|
||||||
|
* Testbench file list
|
||||||
|
|
||||||
|
### Verification source code
|
||||||
|
|
||||||
|
#### SV testbenches used in EDA playground
|
||||||
|
|
||||||
|
Path: `hw/dv/rtl`
|
||||||
|
|
||||||
|
#### Verilator environment
|
||||||
|
|
||||||
|
Path: `hw/dv/verilator/`
|
||||||
|
|
||||||
|
* SV Toplevel harnesses
|
||||||
|
* Decoder
|
||||||
|
* CPU
|
||||||
|
* C++ testbenches
|
||||||
|
* Decoder
|
||||||
|
* CPU
|
||||||
|
* Makefile
|
||||||
|
|
||||||
|
### Software and Hex programs used for testing
|
||||||
|
|
||||||
|
Path: `sw/risc-v`
|
||||||
|
|
||||||
|
* Main Memory: Hex code
|
||||||
|
* Decoder:
|
||||||
|
* Assembly code
|
||||||
|
* Hex code from assembeled assembly code
|
||||||
|
* Fibonacci Series/Hello World/Prime Factors:
|
||||||
|
* C Code
|
||||||
|
* Assembly code from compiled C code
|
||||||
|
* Simplified assembly code from assembly code (not available for Fibonacci Series)
|
||||||
|
* Hex code from assembeled assembly or simplified assembly code
|
||||||
|
|
||||||
|
## Running Simulations
|
||||||
|
|
||||||
|
### Quick start
|
||||||
|
|
||||||
|
Run the two commands below
|
||||||
|
|
||||||
|
```
|
||||||
|
cd hw/dv/verilator
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
make clean all run wave
|
||||||
|
```
|
||||||
|
|
||||||
|
This will convert the RTL into C++, compile the model, create the simulation binary, run the simulation, and start the waveform viewer. The output of the simulation should be the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
*** Running simulation...
|
||||||
|
|
||||||
|
Creating model...
|
||||||
|
Registered DPI-C functions:
|
||||||
|
scopesDump:
|
||||||
|
SCOPE 0x55616d28b940: TOP.cpu_harness
|
||||||
|
DPI-EXPORT 0x556136cc8f77: enable
|
||||||
|
DPI-EXPORT 0x556136cc8f89: getLed
|
||||||
|
DPI-EXPORT 0x556136cc8fda: getMem
|
||||||
|
DPI-EXPORT 0x556136cc9006: getReg
|
||||||
|
DPI-EXPORT 0x556136cc9242: loadRAM
|
||||||
|
DPI-EXPORT 0x556136cdcc19: printMem
|
||||||
|
DPI-EXPORT 0x556136cdcd88: printReg
|
||||||
|
DPI-EXPORT 0x556136cc8fab: setBtn
|
||||||
|
DPI-EXPORT 0x556136cc8f68: setClk
|
||||||
|
DPI-EXPORT 0x556136cc8f78: setInitial
|
||||||
|
DPI-EXPORT 0x556136cc8fea: setMem
|
||||||
|
DPI-EXPORT 0x556136cc8fc9: setReset
|
||||||
|
|
||||||
|
Initializing SRAM memory from ../../../sw/risc-v/hello_world/helloWorld.hex
|
||||||
|
program set to helloWorld
|
||||||
|
|
||||||
|
Starting model...
|
||||||
|
|
||||||
|
Resetting...
|
||||||
|
Starting CPU...
|
||||||
|
Running for 500 clock cycles...
|
||||||
|
|
||||||
|
Printing evaluation for helloWorld program!
|
||||||
|
|
||||||
|
T=3960: Hex ASCII
|
||||||
|
Value at RAM[1024]: 0x68000000 : h
|
||||||
|
Value at RAM[1025]: 0x00000000 :
|
||||||
|
Value at RAM[1026]: 0x00000000 :
|
||||||
|
Value at RAM[1027]: 0x00000000 :
|
||||||
|
|
||||||
|
|
||||||
|
T=6840: Hex ASCII
|
||||||
|
Value at RAM[1024]: 0x68650000 : he
|
||||||
|
Value at RAM[1025]: 0x00000000 :
|
||||||
|
Value at RAM[1026]: 0x00000000 :
|
||||||
|
Value at RAM[1027]: 0x00000000 :
|
||||||
|
|
||||||
|
|
||||||
|
T=9720: Hex ASCII
|
||||||
|
Value at RAM[1024]: 0x68656c00 : hel
|
||||||
|
Value at RAM[1025]: 0x00000000 :
|
||||||
|
Value at RAM[1026]: 0x00000000 :
|
||||||
|
Value at RAM[1027]: 0x00000000 :
|
||||||
|
|
||||||
|
|
||||||
|
T=12600: Hex ASCII
|
||||||
|
Value at RAM[1024]: 0x68656c6c : hell
|
||||||
|
Value at RAM[1025]: 0x00000000 :
|
||||||
|
Value at RAM[1026]: 0x00000000 :
|
||||||
|
Value at RAM[1027]: 0x00000000 :
|
||||||
|
|
||||||
|
|
||||||
|
T=15480: Hex ASCII
|
||||||
|
Value at RAM[1024]: 0x68656c6c : hell
|
||||||
|
Value at RAM[1025]: 0x6f000000 : o
|
||||||
|
Value at RAM[1026]: 0x00000000 :
|
||||||
|
Value at RAM[1027]: 0x00000000 :
|
||||||
|
|
||||||
|
|
||||||
|
T=18360: Hex ASCII
|
||||||
|
Value at RAM[1024]: 0x68656c6c : hell
|
||||||
|
Value at RAM[1025]: 0x6f200000 : o
|
||||||
|
Value at RAM[1026]: 0x00000000 :
|
||||||
|
Value at RAM[1027]: 0x00000000 :
|
||||||
|
|
||||||
|
|
||||||
|
T=21240: Hex ASCII
|
||||||
|
Value at RAM[1024]: 0x68656c6c : hell
|
||||||
|
Value at RAM[1025]: 0x6f207700 : o w
|
||||||
|
Value at RAM[1026]: 0x00000000 :
|
||||||
|
Value at RAM[1027]: 0x00000000 :
|
||||||
|
|
||||||
|
|
||||||
|
T=24120: Hex ASCII
|
||||||
|
Value at RAM[1024]: 0x68656c6c : hell
|
||||||
|
Value at RAM[1025]: 0x6f20776f : o wo
|
||||||
|
Value at RAM[1026]: 0x00000000 :
|
||||||
|
Value at RAM[1027]: 0x00000000 :
|
||||||
|
|
||||||
|
|
||||||
|
T=27000: Hex ASCII
|
||||||
|
Value at RAM[1024]: 0x68656c6c : hell
|
||||||
|
Value at RAM[1025]: 0x6f20776f : o wo
|
||||||
|
Value at RAM[1026]: 0x72000000 : r
|
||||||
|
Value at RAM[1027]: 0x00000000 :
|
||||||
|
|
||||||
|
|
||||||
|
T=29880: Hex ASCII
|
||||||
|
Value at RAM[1024]: 0x68656c6c : hell
|
||||||
|
Value at RAM[1025]: 0x6f20776f : o wo
|
||||||
|
Value at RAM[1026]: 0x726c0000 : rl
|
||||||
|
Value at RAM[1027]: 0x00000000 :
|
||||||
|
|
||||||
|
|
||||||
|
T=32760: Hex ASCII
|
||||||
|
Value at RAM[1024]: 0x68656c6c : hell
|
||||||
|
Value at RAM[1025]: 0x6f20776f : o wo
|
||||||
|
Value at RAM[1026]: 0x726c6400 : rld
|
||||||
|
Value at RAM[1027]: 0x00000000 :
|
||||||
|
|
||||||
|
|
||||||
|
T=35640: Hex ASCII
|
||||||
|
Value at RAM[1024]: 0x68656c6c : hell
|
||||||
|
Value at RAM[1025]: 0x6f20776f : o wo
|
||||||
|
Value at RAM[1026]: 0x726c6421 : rld!
|
||||||
|
Value at RAM[1027]: 0x00000000 :
|
||||||
|
|
||||||
|
|
||||||
|
Done, closing simulation.
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important:** The makefile reads the file lists `hw/file_lists/rtl_flist.f` and `hw/file_lists/tb_flist.f`. The make process does not recognize RTL or TB file changes, so it is required to run `make clean` after RTL or TB changes, otherwise the changed files will not be compiled.
|
||||||
|
|
||||||
|
### Makefile details
|
||||||
|
|
||||||
|
By default, the hex-file `sw/risc-v/hello_world.hex` is loaded into the Main Memory before starting the simulation, and the simulation is run for 500 clock cycles. This behavior can by overriden by specifying *PROG* and *NCYCLES* environment variables, which will load the specified hex file and run for the specified number of clock cycles.
|
||||||
|
|
||||||
|
```
|
||||||
|
make run PROG=/path/to/myprog.hex NCYCLES=2000
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also combine the different make targets.
|
||||||
|
|
||||||
|
```
|
||||||
|
make clean all run wave PROG=/path/to/myprog.hex NCYCLES=2000
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important:** If the simulation is not showing the full expected result, make sure that the number of cycles are sufficient for the CPU to finish executing the program (check if the last instruction executed is the *jump to halt* instruction)
|
||||||
|
|
||||||
|
Available Make targets (commands)
|
||||||
|
|
||||||
|
* **make clean** - remove old files
|
||||||
|
* **make** - build and compile the RTL simulator using Verilator and GCC (alias for `make all`)
|
||||||
|
* **make run** - run the simulation (requires built and compiled RTL)
|
||||||
|
* **make wave** - show the waveform in Surfer
|
||||||
|
* **make clean all run wave** - runs all the make targets (order is important)
|
||||||
|
|
||||||
|
It is not necessary to close the Surfer viewer if the simulation is run again. Just reload the Surfer window after the new run.
|
||||||
|
|
||||||
|
### Things you need/can change
|
||||||
|
|
||||||
|
* In the *Makefile*
|
||||||
|
* **PROG** - variable holding the hex file path of the program to be loaded
|
||||||
|
* **NCYCLES** - Variable for the number of cycles the CPU is going to run for
|
||||||
|
* **TOPMODULE** - Variable with the module name of the harness
|
||||||
|
* Int the *tb_flist.f*
|
||||||
|
* Add new harnesses you have created
|
||||||
|
|
||||||
|
### Things you can do
|
||||||
|
|
||||||
|
* You can run the exact same tests you ran on EDA Playground and you should get the same results. However, the test here will be using verilator.
|
||||||
|
* You can create your own harness and C++ testbenches for modules other than Decoder and CPU to get familiar with verilator testbenches
|
||||||
|
* Compare Icarus and Verilator output (uninitialised memory locations are set to 'x' when using Icarus and '0' when using verilator)
|
||||||
131
riscv_rtl/doc/assets/alu.drawio
Normal file
131
riscv_rtl/doc/assets/alu.drawio
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
<mxfile host="65bd71144e">
|
||||||
|
<diagram name="Page-1" id="6TD31-tx4YeMT5SjUeEL">
|
||||||
|
<mxGraphModel dx="796" dy="265" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||||
|
<root>
|
||||||
|
<mxCell id="0"/>
|
||||||
|
<mxCell id="1" parent="0"/>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-1" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||||
|
<mxGeometry x="370" y="345.16" width="152.95000000000005" height="118.00999999999999" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-2" value="" style="group" parent="fx5yl9cXGPLrq4qI7ClV-1" vertex="1" connectable="0">
|
||||||
|
<mxGeometry y="4.839999999999975" width="152.95000000000005" height="113.17000000000002" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-3" style="edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;startArrow=none;startFill=0;endArrow=none;endFill=0;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<mxPoint x="150" y="75.66836734693868" as="targetPoint"/>
|
||||||
|
<mxPoint x="118.95000000000005" y="75.50000000000011" as="sourcePoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-4" value="eqFlag" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="fx5yl9cXGPLrq4qI7ClV-3" vertex="1" connectable="0">
|
||||||
|
<mxGeometry x="-0.8665" relative="1" as="geometry">
|
||||||
|
<mxPoint x="21" y="7" as="offset"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-5" value="" style="shape=image;verticalLabelPosition=bottom;labelBackgroundColor=default;verticalAlign=top;aspect=fixed;imageAspect=0;image=data:image/png,iVBORw0KGgoAAAANSUhEUgAAAE8AAACjCAYAAADLskN/AAAAAXNSR0IArs4c6QAAAIRlWElmTU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAABIAAAAAQAAAEgAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAAE+gAwAEAAAAAQAAAKMAAAAAHJ2haQAAAAlwSFlzAAALEwAACxMBAJqcGAAAB9pJREFUeAHt3clS3EYYB/BhGFPeFxhsfEI8gMFgs93mJYwHigOVSvIIPpixy0tSyUPY46pszp5H4BovcZaqnOGWeDdgBrzgyfdX1K5Bo0atae39qcoItdQt9W96rEb61CoUCgWL/vHUoUBz375931Beq8P8RmdrLi4ubh07duzFgQMHbjNisLbQxLS8vNys1WqvgHjw4MFvqYhKsGLM3NrGEz+AeOPGja3e3t7Vw4cPf8eIuzcK4bZjDsSbN2++AuKRI0e+Z0RvxB1o7gUH8XVfX98aI7YDur08lx3EN0Ck1vgjt8T/IT2xZIlArNfrb8vl8jpB/mQ6osxp13QHcRuI/f39P5uKuCuS30qBSIAvjx8//otpiH4+SuuBeOvWrXenTp16SF2ce6YgKuGobiQQh4eHH9HZ+X7eEVVdAm0nEEdGRh4fPXr0t7wiBkIJurGD2Dx9+vQT+tPvQd4Qg3p0tH0L4tO9e/f+kxfEjjB0MtGJpTk6OvqMLoX9m3VEHQetvEA8c+bMiywjagGEkRmIZ8+eXd2/f//DrLXEMOofShlAHB8fX3MQFwgy9VMoFQ+zkKWlpcwghlnvUMsC4sTExDrdHnhETXAhjc0w1ApHUZiD+JJuDzwmwCtpQoyivpGUib7i5OTkBhCLxeLVNCBGUtEoCwXi1NRU49ChQ09KpdK1JBGjrGekZQNxenp6M0nESCsYR+ECkS6FPe3u7v4izpYYR/1i2QcQq9XqBhD37NnzZRyIsVQszp0AcXZ2thEHYpz1inVfApEuyj7r6en5KoqWGGuFktgZEOfm5rboouxzuhz2NSFaYUEmUZ9E9gnEixcvNsJETKQiSe4UiBQZtomgJt3wuiTrkei+HUSt8LpEK5CGnQNRRIYFDa9Lw/Gn4hiAKCLDqJujFF6XigNP00EIRAQ1+UWGpem4U3UsDqIdGUZn6B+oe1Nxd3FSdcBpPBiBiKCm1vC6LpLE8bpBedlDYGVlpUAXZrcvXLiw2Wg0/mY8DyS/JCAODQ0VGM9PSrK+q6urUJSs42QFAcZTQJJtwngyGYV0xlNAkm3CeDIZhXTGU0CSbcJ4MhmFdMZTQJJtwngyGYV0xlNAkm3CeDIZhXTGU0CSbcJ4MhmFdMZTQJJtwngyGYV0xlNAkm3CeDIZhXTGU0CSbcJ4MhmFdMZTQJJtwngyGYV0Gw+30ngKLlCkMPyPx8bGVi9fvrwdPDvngIBFiHcHBgY28agST/4CZNYWZrGAR5MQSY74DJ7kAl54diuksKrPEV5Fz7++k2c3e40MD4CYLAzpgUc2+avc3lDIp+1ra6u1/qAnaT7AwyDz8/Ov24swN0UJz4G0ECFJY0Vt4FF2nuyYPP+W19oK6fcKAf41MzOzZvoJJUjLazVEt+YjPMNw6dKlt6a2wk7xBKRFz/7fMbVvqIsnEI3sG4aFB0R8lT8zqW8YJh4AMRnTN6S6Bj7b2kJ+P0zoG0aG5+BaeAQJY4nmsW8YNZ5ooBUC/BNDeeSpbxgXHhAtGlzrwzz1DYGH5zDinCq0s6XBwcFC1q9ex/ocBloe4Oivku2sw8Xa2jAeHv+fF5BcnG3zeD2QKKLr56HwPF8DjAKvIq4+56lb4nXlKFQ8/G2LAk257xEWXgUF4Y6b1yeU1zRdPPt6HgaLzuMJwe9D7xiPxmP6BJn5SjIpBJgqeeyz+bUyr/Vkpt5VEXfPTPyKdoyHa3NQznOfzQvHL82v5RnTZ/OD8lovxUOsClaa0mfzwvFL88KrING0PpsflNf6Vjw7Po+CHJ/zCcGLqj3NxuM+WzuMSgrw7BF96I/4gmVZtMyTqgCuJPNwSKparu1ivQzv2ncuFvk5DI2PkfEYT0NAIyu3PMbTENDIyi2P8TQENLJyy2M8DQGNrNzyGE9DQCMrtzzG0xDQyMotj/E0BDSycstjPA0Bjazc8hhPQ0AjK7c8xtMQ0MjKLS8gHuJ3cNuR4hTvIKvKDXLjt0EULKwI7VeaW/TPnoyH2Q1AoDnvPbMcs/ez3fIau47Q3pBQExGxNLfea7l+MRbIq+K1Wu01+TSddz1K0YShVxlGpeFpJUJ7BTTnLaO+aMbjAY1eErwFNBoj5rYACTI3qpWhsg7aJtCcNysH8dqxrTF4QMM7vcNAE4K5xwMa3iYPNOdt8qLu2vPc4gENwelAo87tp9pSHgXkDq8VzYm59qh2OEm5wQNatVrdIBZ8PfFwYeRT5vHw+MP58+fXMTxnT0/P9cjFWnaQWTygYRRJesr8SalUutZSp9h+zRyeg7aaJJr4dDKDB7Rz5869wEDYxWLxqqhAkvPU4wGNxmt+CTSCupIklnvfqcVz0Nbp785HdNAL7gNPw3Lq8LKAJj641OABbXx8fA3jGNDBLYgDTPM8cTygnTx5cgsDWGcFTXygieEJNIzsmDW0xPCAhsGpy+XyH1lFix2P7nk2T5w40ejt7f0962ix4Qk0GjP0QV7QIsfD3XW0NAwLRzuriB3maR76CQNoeHcG3fO8n1c00QBCwxNodGnoXt7RQsOr1+t4Z1qTrnLcpbklCjZh3nHLE2h4L4ZpaKJhBMYjNM+IIVGgSXNlPBEx5A6zMgnLXVdfPIEmC7NyF2jSshRPNczKJCx3XdvwgoZZuQs0adnGwz3PTsOsTMJy11U7zMpdoEnL2mFWJmFxXUMS+A+AHlfjWfSaUAAAAABJRU5ErkJggg==;" parent="fx5yl9cXGPLrq4qI7ClV-2" vertex="1">
|
||||||
|
<mxGeometry x="70" y="10" width="48.95" height="101" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-6" value="<span style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: center; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(251, 251, 251); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; float: none; display: inline !important;">ALU</span>" style="text;whiteSpace=wrap;html=1;" parent="fx5yl9cXGPLrq4qI7ClV-2" vertex="1">
|
||||||
|
<mxGeometry x="88.94999999999999" y="45.5" width="30" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-7" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;verticalAlign=middle;endArrow=none;endFill=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;strokeWidth=2;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<mxPoint x="108.36999999999988" y="8" as="targetPoint"/>
|
||||||
|
<mxPoint x="108.36999999999999" y="29" as="sourcePoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-8" value="aluOp" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="fx5yl9cXGPLrq4qI7ClV-7" vertex="1" connectable="0">
|
||||||
|
<mxGeometry x="0.1579" relative="1" as="geometry">
|
||||||
|
<mxPoint y="-17" as="offset"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-9" value="" style="endArrow=none;html=1;rounded=0;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="104.52000000000002" y="23" as="sourcePoint"/>
|
||||||
|
<mxPoint x="112.52000000000002" y="13" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-10" value="<span style="font-size: 9px;">3</span>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="fx5yl9cXGPLrq4qI7ClV-2" vertex="1">
|
||||||
|
<mxGeometry x="99.99999999999999" y="5" width="30" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-11" style="edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;endArrow=none;endFill=0;strokeWidth=2;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<mxPoint x="148.95000000000016" y="50.70270270270271" as="targetPoint"/>
|
||||||
|
<mxPoint x="118.94999999999999" y="50.625" as="sourcePoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-12" value="result" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="fx5yl9cXGPLrq4qI7ClV-11" vertex="1" connectable="0">
|
||||||
|
<mxGeometry x="0.1333" relative="1" as="geometry">
|
||||||
|
<mxPoint x="2" y="-14" as="offset"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-13" value="" style="endArrow=none;html=1;rounded=0;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="128.95" y="56" as="sourcePoint"/>
|
||||||
|
<mxPoint x="136.95" y="46" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-14" style="edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;endArrow=none;endFill=0;strokeWidth=2;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<mxPoint x="70.00000000000011" y="29.702702702702766" as="targetPoint"/>
|
||||||
|
<mxPoint x="40" y="30.000000000000057" as="sourcePoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-15" value="" style="endArrow=none;html=1;rounded=0;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="50" y="35.00000000000006" as="sourcePoint"/>
|
||||||
|
<mxPoint x="58" y="25.000000000000057" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-16" value="<span style="font-size: 9px;">32</span>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="fx5yl9cXGPLrq4qI7ClV-2" vertex="1">
|
||||||
|
<mxGeometry x="44" y="23.000000000000057" width="30" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-17" value="op1" style="text;strokeColor=none;align=center;fillColor=none;html=1;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="fx5yl9cXGPLrq4qI7ClV-2" vertex="1">
|
||||||
|
<mxGeometry x="5" y="19.500000000000057" width="40" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-18" style="edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;endArrow=none;endFill=0;strokeWidth=2;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<mxPoint x="70.00000000000011" y="89.87270270270272" as="targetPoint"/>
|
||||||
|
<mxPoint x="40" y="90.17000000000002" as="sourcePoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-19" value="" style="endArrow=none;html=1;rounded=0;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="50" y="95.17000000000002" as="sourcePoint"/>
|
||||||
|
<mxPoint x="58" y="85.17000000000002" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-20" value="<span style="font-size: 9px;">32</span>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="fx5yl9cXGPLrq4qI7ClV-2" vertex="1">
|
||||||
|
<mxGeometry x="44" y="83.17000000000002" width="30" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-21" value="op2" style="text;strokeColor=none;align=center;fillColor=none;html=1;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="fx5yl9cXGPLrq4qI7ClV-2" vertex="1">
|
||||||
|
<mxGeometry x="5" y="79.67000000000002" width="40" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-22" value="<font style="font-size: 9px;">32</font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="fx5yl9cXGPLrq4qI7ClV-2" vertex="1">
|
||||||
|
<mxGeometry x="122.95000000000005" y="41.58000000000004" width="30" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="80" style="edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;" edge="1" parent="fx5yl9cXGPLrq4qI7ClV-2">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<mxPoint x="99.94999999999999" y="94.67000000000002" as="targetPoint"/>
|
||||||
|
<mxPoint x="100" y="110" as="sourcePoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="81" value="aluNegAr" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="80">
|
||||||
|
<mxGeometry x="0.0744" relative="1" as="geometry">
|
||||||
|
<mxPoint y="18" as="offset"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-23" style="edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;" parent="fx5yl9cXGPLrq4qI7ClV-1" edge="1">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<mxPoint x="85" as="targetPoint"/>
|
||||||
|
<mxPoint x="85" y="22.840000000000032" as="sourcePoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="fx5yl9cXGPLrq4qI7ClV-24" value="aluBypass" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="fx5yl9cXGPLrq4qI7ClV-23" vertex="1" connectable="0">
|
||||||
|
<mxGeometry x="0.0744" relative="1" as="geometry">
|
||||||
|
<mxPoint y="-21" as="offset"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
</root>
|
||||||
|
</mxGraphModel>
|
||||||
|
</diagram>
|
||||||
|
</mxfile>
|
||||||
77
riscv_rtl/doc/assets/cpu/core.drawio.svg
Normal file
77
riscv_rtl/doc/assets/cpu/core.drawio.svg
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" style="background: transparent; background-color: transparent;" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="573px" height="359px" viewBox="-0.5 -0.5 573 359" content="<mxfile scale="2" border="0"><diagram name="Page-1" id="Dras1X57W6EPz2KZu20U">5Vdtb9sgEP41lrYPqWyIU+djm75sXSdVi9R1nyoaU5vOBg+TxN6v32FwbJKsydp1mzopUriH4+DuHh5kD0/y6lySIv0oYpp5yI8rD594CB0i5OmfH9cGwGhogESy2EBBB0zZd2pB36JzFtPScVRCZIoVLjgTnNOZcjAipVi6bvcic3ctSEI3gOmMZJvoZxar1KAROuzwd5QlabtzMBqbmZy0zjaTMiWxWPYgfOrhiRRCmVFeTWima9fWxaw7+8ns6mCScrXPghPCBqT208uL24vkw4M/u59OBigyYRYkm9uM7WlV3ZZASUZ4oq3jZcoUnRZkpqeW0HDAUpVnYAUwlEIRxQQHczD2AbhnWTYRmZCAcMF1iFJJ8ZW2oIdwhO7waAQz0EJFGKca14s3E7Q5L6hUtOpBNuFzKnKqZA0udhZFoVmyYp9txrLrZcu0tN9GixHLnmQVuSswDGyNf6HeGG+p9yiDbY9jtoBhoprMDVQWhDu9GH2ba7pAqZryHcGkTO7ewGnhOH7797YJAVznalA2N0o7BqioTGwbpN3t03s42DV4TISk7daQndndPRHAzjnXqCLFnMc0tg3cwRZ9Pnvhg2Fr21jBdvK8BEVC36FIEG1SJNpGkfClONJqyyu9k8PAvZNoS8H/6J0cjjbKS2N4BKwppEpFIjjJTjv02GV653MpRGEr/0CVqi3ByVwJty+0YuqmN/6iQx2E1jqpbOTGqFuDQ743faO3Spvdssaqd3WtFHM5o4/plS26IjKhag9h05V7lAWSZsDHhfu8butps/RISlL3HArBuCp7ka800CPX2L3N7e0+29Mf7/BfveZP9EdhuMZXk2HH3lWpnvHI+BsCksMlvs1p/hoUG0drNQ32U+zoxQQk/KsCcuD7rohgPHySjKBdOqKjXFHJoGy7G7pbW/C+2uL/bm15XruDf6vd4Xj8pHYf/jft3q7NGK/pyDh0Q5iU7Ko10jwq02B233XGvfs4xqc/AA==</diagram></mxfile>">
|
||||||
|
<defs/>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M 144 280 L 164 290 L 144 300 Z" fill="none" stroke="#82b366" stroke-width="2" stroke-miterlimit="10" transform="rotate(-90,154,290)" pointer-events="all" style="stroke: light-dark(rgb(130, 179, 102), rgb(68, 110, 44));"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<rect x="74" y="0" width="160" height="300" fill="none" stroke="#000000" stroke-width="2" pointer-events="all" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g transform="translate(-0.5 -0.5)scale(2)">
|
||||||
|
<switch>
|
||||||
|
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 75px; margin-left: 38px;">
|
||||||
|
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; ">
|
||||||
|
<div style="display: inline-block; font-size: 14px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; word-wrap: normal; ">
|
||||||
|
<div>
|
||||||
|
<span style="color: light-dark(rgb(0, 0, 0), rgb(237, 237, 237)); font-size: 12px;">
|
||||||
|
RISC-V Core
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
<text x="77" y="79" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="14px" text-anchor="middle" font-weight="bold">
|
||||||
|
RISC-V Core
|
||||||
|
</text>
|
||||||
|
</switch>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path d="M 404 200 L 424 210 L 404 220 Z" fill="none" stroke="#82b366" stroke-width="2" stroke-miterlimit="10" transform="rotate(-90,414,210)" pointer-events="all" style="stroke: light-dark(rgb(130, 179, 102), rgb(68, 110, 44));"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path d="M 494 140 L 554 140 L 554 340 L 14 340 L 14 150.03 L 61.26 150.01" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/>
|
||||||
|
<path d="M 71.76 150 L 57.77 157.01 L 61.26 150.01 L 57.76 143.01 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<rect x="334" y="60" width="160" height="160" fill="none" stroke="#000000" stroke-width="2" pointer-events="all" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g transform="translate(-0.5 -0.5)scale(2)">
|
||||||
|
<switch>
|
||||||
|
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 70px; margin-left: 168px;">
|
||||||
|
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; ">
|
||||||
|
<div style="display: inline-block; font-size: 14px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; word-wrap: normal; ">
|
||||||
|
main_mem
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
<text x="207" y="74" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="14px" text-anchor="middle" font-weight="bold">
|
||||||
|
main_mem
|
||||||
|
</text>
|
||||||
|
</switch>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path d="M 234.16 100.2 L 284.03 100.23 L 321.26 100.06" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/>
|
||||||
|
<path d="M 331.76 100.01 L 317.8 107.07 L 321.26 100.06 L 317.73 93.07 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path d="M 234.16 179.7 L 284.03 179.61 L 321.26 179.9" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/>
|
||||||
|
<path d="M 331.76 179.98 L 317.71 186.87 L 321.26 179.9 L 317.82 172.87 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<switch>
|
||||||
|
<g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/>
|
||||||
|
<a transform="translate(0,-5)" xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems" target="_blank">
|
||||||
|
<text text-anchor="middle" font-size="10px" x="50%" y="100%">
|
||||||
|
Text is not SVG - cannot display
|
||||||
|
</text>
|
||||||
|
</a>
|
||||||
|
</switch>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 7.3 KiB |
1631
riscv_rtl/doc/assets/cpu/cpu.drawio.svg
Normal file
1631
riscv_rtl/doc/assets/cpu/cpu.drawio.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 136 KiB |
1
riscv_rtl/doc/assets/cpu/cpu_abstracted.drawio.svg
Normal file
1
riscv_rtl/doc/assets/cpu/cpu_abstracted.drawio.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 18 KiB |
1068
riscv_rtl/doc/assets/decoder/decoder.drawio.svg
Normal file
1068
riscv_rtl/doc/assets/decoder/decoder.drawio.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 89 KiB |
1335
riscv_rtl/doc/assets/decoder/decoder_data_flow.drawio.svg
Normal file
1335
riscv_rtl/doc/assets/decoder/decoder_data_flow.drawio.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 144 KiB |
@ -0,0 +1,163 @@
|
|||||||
|
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.2.2 Chrome/134.0.6998.178 Electron/35.1.2 Safari/537.36" version="26.2.2">
|
||||||
|
<diagram name="Page-1" id="vqPtpfTpDl2-zyb6y6Gk">
|
||||||
|
<mxGraphModel dx="2152" dy="1262" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
|
||||||
|
<root>
|
||||||
|
<mxCell id="0" />
|
||||||
|
<mxCell id="1" parent="0" />
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f5f5f5;fontColor=#333333;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="200" y="270" width="680" height="340" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-1" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="250" y="480" width="540" height="80" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-3" value="" style="shape=flexArrow;endArrow=classic;html=1;rounded=0;entryX=0.47;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.683;exitY=0.008;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" edge="1" source="QNMoGRvylN2gnaf27AE2-24">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="650.4" y="435" as="sourcePoint" />
|
||||||
|
<mxPoint x="649.9999999999999" y="355" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-4" value="" style="shape=flexArrow;endArrow=classic;html=1;rounded=0;exitX=0.588;exitY=0.999;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.489;entryY=0.019;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" edge="1" target="QNMoGRvylN2gnaf27AE2-23">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="579.7999999999997" y="354.99999999999994" as="sourcePoint" />
|
||||||
|
<mxPoint x="579.96" y="435.16" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-5" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.118;entryY=0.001;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" edge="1" source="QNMoGRvylN2gnaf27AE2-7">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="299.7999999999998" y="400" as="sourcePoint" />
|
||||||
|
<mxPoint x="299.7999999999998" y="480.0799999999999" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-6" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.118;entryY=0.001;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" edge="1" source="QNMoGRvylN2gnaf27AE2-8">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="370" y="360" as="sourcePoint" />
|
||||||
|
<mxPoint x="369.8" y="480" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-7" value="setClk()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="270" y="325" width="60" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-8" value="setReset()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="340" y="325" width="60" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-9" value="enable()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="410" y="325" width="60" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-10" value="setInitial()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="480" y="325" width="60" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-11" value="setBtn()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="550" y="325" width="60" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-12" value="getLed()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="620" y="325" width="60" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-13" value="loadRAM" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="690" y="325" width="60" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-14" value="dumpRAM()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="760" y="325" width="70" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-15" value="cpu_harness" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="790" y="580" width="90" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-20" value="cpu (device under test)" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="650" y="530" width="140" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-21" value="clk" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="280" y="480" width="40" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-22" value="rst" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="345" y="480" width="40" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-23" value="btn[6:0]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="550" y="480" width="60" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-24" value="led[7:0]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="610" y="480" width="60" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-25" value="DPI-C tasks and functions" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="500" y="295" width="160" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-26" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="200" y="80" width="680" height="160" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-27" value="tb_cpu_harness" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="780" y="210" width="110" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-28" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="610" y="100" width="130" height="110" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-29" value="<b>class cpu</b><div>cpu::tick()</div><div>cpu::setReset()</div><div>cpu::waitClocks()</div><div>cpu::loadRAM()</div><div>...</div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="630" y="110" width="110" height="100" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-30" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.052;exitY=0.966;exitDx=0;exitDy=0;exitPerimeter=0;flowAnimation=0;shadow=0;dashed=1;" parent="1" source="QNMoGRvylN2gnaf27AE2-28" target="QNMoGRvylN2gnaf27AE2-7" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="940" y="260" as="sourcePoint" />
|
||||||
|
<mxPoint x="500" y="400" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-31" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.138;exitY=1.004;exitDx=0;exitDy=0;exitPerimeter=0;dashed=1;" parent="1" source="QNMoGRvylN2gnaf27AE2-28" target="QNMoGRvylN2gnaf27AE2-8" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="557" y="216" as="sourcePoint" />
|
||||||
|
<mxPoint x="310" y="335" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-32" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.834;exitY=1.006;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.603;entryY=0.068;entryDx=0;entryDy=0;entryPerimeter=0;dashed=1;" parent="1" source="QNMoGRvylN2gnaf27AE2-29" target="QNMoGRvylN2gnaf27AE2-14" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="-20" y="450" as="sourcePoint" />
|
||||||
|
<mxPoint x="30" y="400" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-33" value="<b><font style="font-size: 19px;">...</font></b>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="650" y="200" width="40" height="40" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-34" value="<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><b>main()</b><div>create cpu instance</div><div>cpu.loadRam("hexfile");</div><div>cpu.reset(10);</div><div>cpu.start();</div><div>...</div><div>cpu.stop();</div><div>cpu.delete();</div></blockquote>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;align=left;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="260" y="95" width="210" height="130" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-35" value="" style="shape=flexArrow;endArrow=classic;startArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.002;entryY=0.547;entryDx=0;entryDy=0;entryPerimeter=0;fillColor=#bac8d3;strokeColor=default;" parent="1" source="QNMoGRvylN2gnaf27AE2-34" target="QNMoGRvylN2gnaf27AE2-28" edge="1">
|
||||||
|
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||||
|
<mxPoint x="440" y="250" as="sourcePoint" />
|
||||||
|
<mxPoint x="530" y="160" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-36" value="<font style="font-size: 20px;"><b>C++</b></font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;rotation=-90;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="930" y="140" width="60" height="40" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-37" value="<font style="font-size: 20px;"><b>SystemVerilog</b></font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;rotation=-90;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="880" y="394" width="160" height="40" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-39" value="" style="endArrow=none;html=1;rounded=0;" parent="1" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="960" y="120" as="sourcePoint" />
|
||||||
|
<mxPoint x="960" y="80" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-40" value="" style="endArrow=none;html=1;rounded=0;" parent="1" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="959.66" y="240" as="sourcePoint" />
|
||||||
|
<mxPoint x="959.66" y="200" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-41" value="" style="endArrow=none;html=1;rounded=0;exitX=0.996;exitY=0.511;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" source="QNMoGRvylN2gnaf27AE2-37" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="959.66" y="325" as="sourcePoint" />
|
||||||
|
<mxPoint x="959.66" y="285" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-42" value="" style="endArrow=none;html=1;rounded=0;" parent="1" target="QNMoGRvylN2gnaf27AE2-37" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="959.66" y="560" as="sourcePoint" />
|
||||||
|
<mxPoint x="959.66" y="520" as="targetPoint" />
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="CcVjRRQ9gQZcIWVMXx_5-1" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="160" y="40" width="890" height="620" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="CcVjRRQ9gQZcIWVMXx_5-2" value="Text" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="1105" y="548" width="50" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
</root>
|
||||||
|
</mxGraphModel>
|
||||||
|
</diagram>
|
||||||
|
</mxfile>
|
||||||
160
riscv_rtl/doc/assets/verilator/verilator_architecture.drawio
Normal file
160
riscv_rtl/doc/assets/verilator/verilator_architecture.drawio
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
<mxfile host="65bd71144e">
|
||||||
|
<diagram name="Page-1" id="vqPtpfTpDl2-zyb6y6Gk">
|
||||||
|
<mxGraphModel dx="1708" dy="882" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
|
||||||
|
<root>
|
||||||
|
<mxCell id="0"/>
|
||||||
|
<mxCell id="1" parent="0"/>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f5f5f5;fontColor=#333333;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="200" y="270" width="680" height="340" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-1" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="250" y="480" width="540" height="80" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-3" value="" style="shape=flexArrow;endArrow=classic;html=1;rounded=0;entryX=0.47;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.683;exitY=0.008;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" source="QNMoGRvylN2gnaf27AE2-24" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="650.4" y="435" as="sourcePoint"/>
|
||||||
|
<mxPoint x="649.9999999999999" y="355" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-4" value="" style="shape=flexArrow;endArrow=classic;html=1;rounded=0;exitX=0.588;exitY=0.999;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.489;entryY=0.019;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" target="QNMoGRvylN2gnaf27AE2-23" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="579.7999999999997" y="354.99999999999994" as="sourcePoint"/>
|
||||||
|
<mxPoint x="579.96" y="435.16" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-5" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.118;entryY=0.001;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="QNMoGRvylN2gnaf27AE2-7" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="299.7999999999998" y="400" as="sourcePoint"/>
|
||||||
|
<mxPoint x="299.7999999999998" y="480.0799999999999" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-6" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.118;entryY=0.001;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="QNMoGRvylN2gnaf27AE2-8" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="370" y="360" as="sourcePoint"/>
|
||||||
|
<mxPoint x="369.8" y="480" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-7" value="setClk()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="270" y="325" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-8" value="setReset()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="340" y="325" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-9" value="enable()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="410" y="325" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-10" value="setInitial()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="480" y="325" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-11" value="setBtn()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="550" y="325" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-12" value="getLed()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="620" y="325" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-13" value="loadRAM" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="690" y="325" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-14" value="dumpRAM()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="760" y="325" width="70" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-15" value="cpu_harness" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="790" y="580" width="90" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-20" value="cpu (device under test)" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="645" y="530" width="150" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-21" value="clk" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="280" y="480" width="40" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-22" value="rst" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="345" y="480" width="40" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-23" value="btn[6:0]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="550" y="480" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-24" value="led[7:0]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="610" y="480" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-25" value="DPI-C tasks and functions" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="500" y="295" width="160" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-26" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="200" y="80" width="680" height="160" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-27" value="tb_cpu_harness" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="780" y="210" width="110" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-28" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="610" y="100" width="130" height="110" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-29" value="<b>class cpu</b><div>cpu::tick()</div><div>cpu::setReset()</div><div>cpu::waitClocks()</div><div>cpu::loadRAM()</div><div>...</div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="630" y="110" width="110" height="100" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-30" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.052;exitY=0.966;exitDx=0;exitDy=0;exitPerimeter=0;flowAnimation=0;shadow=0;dashed=1;" parent="1" source="QNMoGRvylN2gnaf27AE2-28" target="QNMoGRvylN2gnaf27AE2-7" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="940" y="260" as="sourcePoint"/>
|
||||||
|
<mxPoint x="500" y="400" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-31" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.138;exitY=1.004;exitDx=0;exitDy=0;exitPerimeter=0;dashed=1;" parent="1" source="QNMoGRvylN2gnaf27AE2-28" target="QNMoGRvylN2gnaf27AE2-8" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="557" y="216" as="sourcePoint"/>
|
||||||
|
<mxPoint x="310" y="335" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-32" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.834;exitY=1.006;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.603;entryY=0.068;entryDx=0;entryDy=0;entryPerimeter=0;dashed=1;" parent="1" source="QNMoGRvylN2gnaf27AE2-29" target="QNMoGRvylN2gnaf27AE2-14" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="-20" y="450" as="sourcePoint"/>
|
||||||
|
<mxPoint x="30" y="400" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-33" value="<b><font style="font-size: 19px;">...</font></b>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="650" y="200" width="40" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-34" value="<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><b>main()</b><div>create cpu instance</div><div>cpu.loadRam("hexfile");</div><div>cpu.reset(10);</div><div>cpu.start();</div><div>...</div><div>cpu.stop();</div><div>cpu.delete();</div></blockquote>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;align=left;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="260" y="95" width="210" height="130" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-35" value="" style="shape=flexArrow;endArrow=classic;startArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.002;entryY=0.547;entryDx=0;entryDy=0;entryPerimeter=0;fillColor=#bac8d3;strokeColor=default;" parent="1" source="QNMoGRvylN2gnaf27AE2-34" target="QNMoGRvylN2gnaf27AE2-28" edge="1">
|
||||||
|
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||||
|
<mxPoint x="440" y="250" as="sourcePoint"/>
|
||||||
|
<mxPoint x="530" y="160" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-36" value="<font style="font-size: 20px;"><b>C++</b></font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;rotation=-90;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="930" y="140" width="60" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-37" value="<font style="font-size: 20px;"><b>SystemVerilog</b></font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;rotation=-90;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="880" y="394" width="160" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-39" value="" style="endArrow=none;html=1;rounded=0;" parent="1" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="960" y="120" as="sourcePoint"/>
|
||||||
|
<mxPoint x="960" y="80" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-40" value="" style="endArrow=none;html=1;rounded=0;" parent="1" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="959.66" y="240" as="sourcePoint"/>
|
||||||
|
<mxPoint x="959.66" y="200" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-41" value="" style="endArrow=none;html=1;rounded=0;exitX=0.996;exitY=0.511;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" source="QNMoGRvylN2gnaf27AE2-37" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="959.66" y="325" as="sourcePoint"/>
|
||||||
|
<mxPoint x="959.66" y="285" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="QNMoGRvylN2gnaf27AE2-42" value="" style="endArrow=none;html=1;rounded=0;" parent="1" target="QNMoGRvylN2gnaf27AE2-37" edge="1">
|
||||||
|
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||||
|
<mxPoint x="959.66" y="560" as="sourcePoint"/>
|
||||||
|
<mxPoint x="959.66" y="520" as="targetPoint"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="160" y="40" width="890" height="620" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
</root>
|
||||||
|
</mxGraphModel>
|
||||||
|
</diagram>
|
||||||
|
</mxfile>
|
||||||
BIN
riscv_rtl/doc/assets/verilator/verilator_architecture.drawio.png
Normal file
BIN
riscv_rtl/doc/assets/verilator/verilator_architecture.drawio.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
Binary file not shown.
BIN
riscv_rtl/doc/course_material/RISC-V ASM.pdf
Normal file
BIN
riscv_rtl/doc/course_material/RISC-V ASM.pdf
Normal file
Binary file not shown.
BIN
riscv_rtl/doc/course_material/RISC-V ISA Card - RV32I.pdf
Normal file
BIN
riscv_rtl/doc/course_material/RISC-V ISA Card - RV32I.pdf
Normal file
Binary file not shown.
BIN
riscv_rtl/doc/course_material/RISC-V ISM - Unprivileged.pdf
Normal file
BIN
riscv_rtl/doc/course_material/RISC-V ISM - Unprivileged.pdf
Normal file
Binary file not shown.
25
riscv_rtl/dummz_memgen_16.sv
Normal file
25
riscv_rtl/dummz_memgen_16.sv
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// MemGen_16_10_stub.sv
|
||||||
|
// Behavioral stub - ports matched from MemGen_32_11.sv instantiation
|
||||||
|
module MemGen_16_10 #(
|
||||||
|
parameter ADDR_WIDTH = 10,
|
||||||
|
parameter DATA_WIDTH = 16
|
||||||
|
)(
|
||||||
|
input logic chip_en,
|
||||||
|
input logic clock,
|
||||||
|
input logic [ADDR_WIDTH-1:0] addr,
|
||||||
|
input logic rd_en,
|
||||||
|
output logic [DATA_WIDTH-1:0] rd_data,
|
||||||
|
input logic wr_en,
|
||||||
|
input logic [DATA_WIDTH-1:0] wr_data
|
||||||
|
);
|
||||||
|
logic [DATA_WIDTH-1:0] mem [0:(2**ADDR_WIDTH)-1];
|
||||||
|
|
||||||
|
always_ff @(posedge clock) begin
|
||||||
|
if (chip_en) begin
|
||||||
|
if (wr_en)
|
||||||
|
mem[addr] <= wr_data;
|
||||||
|
else if (rd_en)
|
||||||
|
rd_data <= mem[addr];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
112
riscv_rtl/hw/dv/rtl/alu_tb.sv
Normal file
112
riscv_rtl/hw/dv/rtl/alu_tb.sv
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 15.Oct.2025 by Bomin Kim
|
||||||
|
// Last Modified : 23.Oct.2025 by Bomin Kim [commit 2f8f03d]
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- --------- -------------------------------------------------
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
`timescale 1ns/1ns
|
||||||
|
|
||||||
|
module alu_tb();
|
||||||
|
|
||||||
|
// Local Signals
|
||||||
|
logic[2:0] aluOp;
|
||||||
|
logic aluNegAr;
|
||||||
|
logic aluBypass;
|
||||||
|
logic[31:0] op1;
|
||||||
|
logic[31:0] op2;
|
||||||
|
logic[31:0] result;
|
||||||
|
logic eqFlag;
|
||||||
|
|
||||||
|
// Toplevel instance (DUT)
|
||||||
|
alu u_alu (
|
||||||
|
.aluOp(aluOp),
|
||||||
|
.aluNegAr(aluNegAr),
|
||||||
|
.aluBypass(aluBypass),
|
||||||
|
.op1(op1),
|
||||||
|
.op2(op2),
|
||||||
|
.result(result),
|
||||||
|
.eqFlag(eqFlag)
|
||||||
|
);
|
||||||
|
|
||||||
|
// list of aluOp
|
||||||
|
localparam logic[2:0] f3add = 3'b000;
|
||||||
|
localparam logic[2:0] f3sl = 3'b001;
|
||||||
|
localparam logic[2:0] f3slt = 3'b010;
|
||||||
|
localparam logic[2:0] f3sltU = 3'b011;
|
||||||
|
localparam logic[2:0] f3xor = 3'b100;
|
||||||
|
localparam logic[2:0] f3sr = 3'b101;
|
||||||
|
localparam logic[2:0] f3or = 3'b110;
|
||||||
|
localparam logic[2:0] f3and = 3'b111;
|
||||||
|
|
||||||
|
// Initialize and run simulation
|
||||||
|
initial begin
|
||||||
|
dumpWave("wave.vcd");
|
||||||
|
|
||||||
|
// Initialize inputs
|
||||||
|
aluOp = 0;
|
||||||
|
aluNegAr = 0;
|
||||||
|
aluBypass = 0;
|
||||||
|
op1 = 0;
|
||||||
|
op2 = 0;
|
||||||
|
#10
|
||||||
|
|
||||||
|
// Set op1 and op2
|
||||||
|
op1 = 32'hDEAD_BEEF; op2 = 32'h0000_0001; #70
|
||||||
|
$display("\nTime = %0dns \t : op1 = %h, op2 = %h", $time, op1, op2);
|
||||||
|
|
||||||
|
$display("\nTime = %0dns \t : Is op1 and op2 equal?; eqFlag = %d", $time, eqFlag);
|
||||||
|
|
||||||
|
aluBypass = 1; #70
|
||||||
|
$display("\nTime = %0dns \t : AluBypass is set; result = %h", $time, result);
|
||||||
|
|
||||||
|
aluBypass = 0; aluOp = f3add; #70
|
||||||
|
$display("\nTime = %0dns \t : Alu operates addition; result = %h", $time, result);
|
||||||
|
|
||||||
|
aluNegAr = 1; #70
|
||||||
|
$display("\nTime = %0dns \t : Alu operates subtraction; result = %h", $time, result);
|
||||||
|
|
||||||
|
aluNegAr = 0; aluOp = f3sl; #70
|
||||||
|
$display("\nTime = %0dns \t : Alu operates shift left; result = %h", $time, result);
|
||||||
|
|
||||||
|
aluOp = f3slt; #70
|
||||||
|
$display("\nTime = %0dns \t : Alu operates set less than; result = %h", $time, result);
|
||||||
|
|
||||||
|
aluOp = f3sltU; #70
|
||||||
|
$display("\nTime = %0dns \t : Alu operates set less than (unsigned); result = %h", $time, result);
|
||||||
|
|
||||||
|
aluOp = f3xor; #70
|
||||||
|
$display("\nTime = %0dns \t : Alu operates bit-wise XOR; result = %h", $time, result);
|
||||||
|
|
||||||
|
aluOp = f3sr; aluNegAr = 1; #70
|
||||||
|
$display("\nTime = %0dns \t : Alu operates arithmetic right shift; result = %h", $time, result);
|
||||||
|
|
||||||
|
aluNegAr = 0; #70
|
||||||
|
$display("\nTime = %0dns \t : Alu operates logical right shift; result = %h", $time, result);
|
||||||
|
|
||||||
|
aluOp = f3or; #70
|
||||||
|
$display("\nTime = %0dns \t : Alu operates bit-wise OR; result = %h", $time, result);
|
||||||
|
|
||||||
|
aluOp = f3and; #70
|
||||||
|
$display("\nTime = %0dns \t : Alu operates bit-wise AND; result = %h", $time, result);
|
||||||
|
$finish;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
// Wave Dump Helper Task
|
||||||
|
task dumpWave(string fileName);
|
||||||
|
// Open wave file and dump all signals (2D arrays not included)
|
||||||
|
$display("\nTime = %0dns \t : Opening wave file '%s'", $time, fileName);
|
||||||
|
$dumpfile(fileName);
|
||||||
|
$display("Time = %0dns \t : Dumping all %s signals in wave file (2D arrays not included)", $time, "alu_tb");
|
||||||
|
$dumpvars(0, alu_tb);
|
||||||
|
endtask: dumpWave
|
||||||
|
|
||||||
|
endmodule
|
||||||
164
riscv_rtl/hw/dv/rtl/cpu_tb.sv
Normal file
164
riscv_rtl/hw/dv/rtl/cpu_tb.sv
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 15.Oct.2025 by Hussein Elzomor
|
||||||
|
// Last Modified : 23.Oct.2025 by Hussein Elzomor [commit 2f8f03d]
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- --------- -------------------------------------------------
|
||||||
|
// 15.Oct.2025 H.Elzomor Renamed file and module from soc_tb to cpu_tb
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// `define fibonacci
|
||||||
|
// `define helloWorld
|
||||||
|
// `define primeFactors
|
||||||
|
|
||||||
|
`timescale 1ns/1ns
|
||||||
|
|
||||||
|
module cpu_tb ();
|
||||||
|
|
||||||
|
// local signals
|
||||||
|
logic[7:0] led;
|
||||||
|
logic[6:0] btn;
|
||||||
|
logic reset;
|
||||||
|
logic clk;
|
||||||
|
|
||||||
|
// Toplevel instance (DUT)
|
||||||
|
cpu u_cpu (
|
||||||
|
.led(led),
|
||||||
|
.btn(btn),
|
||||||
|
.clk_25mhz(clk)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Tie reset signal to the reset button
|
||||||
|
assign btn[0] = reset;
|
||||||
|
|
||||||
|
// Clock generation
|
||||||
|
always #20 clk = ~clk;
|
||||||
|
|
||||||
|
// Initialize and run simulation
|
||||||
|
initial begin
|
||||||
|
dumpWave("wave.vcd");
|
||||||
|
`ifdef fibonacci
|
||||||
|
loadMem("fibonacci.hex");
|
||||||
|
`elsif helloWorld
|
||||||
|
loadMem("helloWorld.hex");
|
||||||
|
`elsif primeFactors
|
||||||
|
loadMem("primeFactors.hex");
|
||||||
|
`endif
|
||||||
|
|
||||||
|
clk = 0;
|
||||||
|
$display("\nTime = %0dns \t : Resetting the CPU", $time);
|
||||||
|
reset = 0; #100;
|
||||||
|
$display("\nTime = %0dns \t : Reset released", $time);
|
||||||
|
reset = 1; #500000;
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Fibonacci Program Monitor
|
||||||
|
`ifdef fibonacci
|
||||||
|
localparam int fibonacciStartLoc = 2027;
|
||||||
|
localparam int fibonacciLengthInWords = 10;
|
||||||
|
always_comb begin: Monitor_Fibonacci_Series_Calculation
|
||||||
|
$display("\nTime =%5dns\t\t\t Hex \t Dec", $time);
|
||||||
|
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+0, u_cpu.theMem.RAM[fibonacciStartLoc+0], u_cpu.theMem.RAM[fibonacciStartLoc+0]);
|
||||||
|
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+1, u_cpu.theMem.RAM[fibonacciStartLoc+1], u_cpu.theMem.RAM[fibonacciStartLoc+1]);
|
||||||
|
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+2, u_cpu.theMem.RAM[fibonacciStartLoc+2], u_cpu.theMem.RAM[fibonacciStartLoc+2]);
|
||||||
|
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+3, u_cpu.theMem.RAM[fibonacciStartLoc+3], u_cpu.theMem.RAM[fibonacciStartLoc+3]);
|
||||||
|
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+4, u_cpu.theMem.RAM[fibonacciStartLoc+4], u_cpu.theMem.RAM[fibonacciStartLoc+4]);
|
||||||
|
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+5, u_cpu.theMem.RAM[fibonacciStartLoc+5], u_cpu.theMem.RAM[fibonacciStartLoc+5]);
|
||||||
|
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+6, u_cpu.theMem.RAM[fibonacciStartLoc+6], u_cpu.theMem.RAM[fibonacciStartLoc+6]);
|
||||||
|
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+7, u_cpu.theMem.RAM[fibonacciStartLoc+7], u_cpu.theMem.RAM[fibonacciStartLoc+7]);
|
||||||
|
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+8, u_cpu.theMem.RAM[fibonacciStartLoc+8], u_cpu.theMem.RAM[fibonacciStartLoc+8]);
|
||||||
|
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+9, u_cpu.theMem.RAM[fibonacciStartLoc+9], u_cpu.theMem.RAM[fibonacciStartLoc+9]);
|
||||||
|
$display("");
|
||||||
|
end
|
||||||
|
|
||||||
|
// Hello World Program Monitor
|
||||||
|
`elsif helloWorld
|
||||||
|
localparam int helloWorldStartLoc = 1024;
|
||||||
|
localparam int helloWorldLengthInWords = 4;
|
||||||
|
always_comb begin: Monitor_Hello_World_Printing
|
||||||
|
$display("\nTime =%5dns\t\t Hex \t\t ASCII", $time);
|
||||||
|
$display("Value at RAM[%0d]: 0x%h : %0s", helloWorldStartLoc+0, u_cpu.theMem.RAM[helloWorldStartLoc+0], u_cpu.theMem.RAM[helloWorldStartLoc+0]);
|
||||||
|
$display("Value at RAM[%0d]: 0x%h : %0s", helloWorldStartLoc+1, u_cpu.theMem.RAM[helloWorldStartLoc+1], u_cpu.theMem.RAM[helloWorldStartLoc+1]);
|
||||||
|
$display("Value at RAM[%0d]: 0x%h : %0s", helloWorldStartLoc+2, u_cpu.theMem.RAM[helloWorldStartLoc+2], u_cpu.theMem.RAM[helloWorldStartLoc+2]);
|
||||||
|
$display("Value at RAM[%0d]: 0x%h : %0s", helloWorldStartLoc+3, u_cpu.theMem.RAM[helloWorldStartLoc+3], u_cpu.theMem.RAM[helloWorldStartLoc+3]);
|
||||||
|
$display("");
|
||||||
|
end
|
||||||
|
|
||||||
|
// Prime Factors Program Monitor
|
||||||
|
`elsif primeFactors
|
||||||
|
localparam int primeNumberReg = 16;
|
||||||
|
always_comb begin: Monitor_Factorization_Number
|
||||||
|
if(u_cpu.theRegisters.registers[primeNumberReg] > 1)
|
||||||
|
$display("\nTime =%5dns \t : Register [%0d] updated - Finding the prime factors of %0d", $time,primeNumberReg, u_cpu.theRegisters.registers[primeNumberReg]);
|
||||||
|
end
|
||||||
|
localparam int primeFactorsReg = 17;
|
||||||
|
always_comb begin: Monitor_Prime_Number
|
||||||
|
if(u_cpu.theRegisters.registers[primeFactorsReg] > 1)
|
||||||
|
$display("Time =%5dns \t : Register [%0d] updated - %0d is a prime factor", $time,primeFactorsReg, u_cpu.theRegisters.registers[primeFactorsReg]);
|
||||||
|
end
|
||||||
|
`endif
|
||||||
|
|
||||||
|
// Wave Dump Helper Task
|
||||||
|
int i;
|
||||||
|
task dumpWave(string fileName);
|
||||||
|
// Open wave file and dump all signals (2D arrays not included)
|
||||||
|
$display("\nTime = %0dns \t : Opening wave file '%s'", $time, fileName);
|
||||||
|
$dumpfile(fileName);
|
||||||
|
$display("Time = %0dns \t : Dumping all %s signals in wave file (2D arrays not included)", $time, "cpu_tb");
|
||||||
|
$dumpvars(0, cpu_tb);
|
||||||
|
|
||||||
|
// Dump Memory in wave file
|
||||||
|
$display("\nTime = %0dns \t : Dumping Memory in wave file", $time);
|
||||||
|
for (i = 0; i < 100; i++) begin $dumpvars(0, cpu_tb.u_cpu.theMem.RAM[i]); end // A part of the Instruction Memory
|
||||||
|
for (i = 1024; i < 1124; i++) begin $dumpvars(0, cpu_tb.u_cpu.theMem.RAM[i]); end // A part of the Data Memory
|
||||||
|
for (i = 1968; i < 2048; i++) begin $dumpvars(0, cpu_tb.u_cpu.theMem.RAM[i]); end // A part of the Stack
|
||||||
|
|
||||||
|
// Dump registers in wave file
|
||||||
|
$display("\nTime = %0dns \t : Dumping Registers in wave file", $time);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[1]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[2]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[3]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[4]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[5]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[6]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[7]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[8]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[9]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[10]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[11]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[12]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[13]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[14]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[15]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[16]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[17]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[18]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[19]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[20]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[21]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[22]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[23]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[24]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[25]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[26]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[27]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[28]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[29]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[30]);
|
||||||
|
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[31]);
|
||||||
|
endtask: dumpWave
|
||||||
|
|
||||||
|
// Load hex file into memory
|
||||||
|
task loadMem (string fileName);
|
||||||
|
$display("\nTime = %0dns \t : Loading '%s' into Memory", $time, fileName);
|
||||||
|
$readmemh(fileName, cpu_tb.u_cpu.theMem.RAM);
|
||||||
|
endtask: loadMem
|
||||||
|
|
||||||
|
endmodule
|
||||||
150
riscv_rtl/hw/dv/rtl/decoder_tb.sv
Normal file
150
riscv_rtl/hw/dv/rtl/decoder_tb.sv
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 15.Oct.2025 by Hussein Elzomor
|
||||||
|
// Last Modified : 23.Oct.2025 by Hussein Elzomor [commit 2f8f03d]
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- --------- -------------------------------------------------
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
`timescale 1ns/1ns
|
||||||
|
|
||||||
|
module decoder_tb ();
|
||||||
|
|
||||||
|
// local Parameters
|
||||||
|
localparam MEM_SIZE = 37;
|
||||||
|
localparam REG_FILE_SIZE = 32;
|
||||||
|
|
||||||
|
// local signals
|
||||||
|
logic clk;
|
||||||
|
int counter;
|
||||||
|
logic[31:0] mem [MEM_SIZE-1:0];
|
||||||
|
logic[31:0] regFile [REG_FILE_SIZE-1:0];
|
||||||
|
// PC
|
||||||
|
logic[31:0] CurrentPC;
|
||||||
|
logic[31:0] JumpOrBranchPC;
|
||||||
|
logic JumpOrBranch;
|
||||||
|
logic[31:0] NextPC;
|
||||||
|
// Memory
|
||||||
|
logic[31:0] DAddr;
|
||||||
|
logic[31:0] WData;
|
||||||
|
logic[31:0] RData;
|
||||||
|
logic[31:0] Instruction;
|
||||||
|
logic WrMem;
|
||||||
|
logic[1:0] DWidth;
|
||||||
|
// Register File;
|
||||||
|
logic[4:0] Rs1;
|
||||||
|
logic[4:0] Rs2;
|
||||||
|
logic[4:0] Rd;
|
||||||
|
logic[31:0] RRs1;
|
||||||
|
logic[31:0] RRs2;
|
||||||
|
logic[31:0] WRd;
|
||||||
|
logic WrReg;
|
||||||
|
// Protection
|
||||||
|
logic Illegal;
|
||||||
|
|
||||||
|
// Toplevel instance (DUT)
|
||||||
|
decoder u_decoder (
|
||||||
|
// PC
|
||||||
|
.CurrentPC(CurrentPC),
|
||||||
|
.JumpOrBranchPC(JumpOrBranchPC),
|
||||||
|
.JumpOrBranch(JumpOrBranch),
|
||||||
|
// Memory
|
||||||
|
.DAddr(DAddr),
|
||||||
|
.WData(WData),
|
||||||
|
.RData(RData),
|
||||||
|
.Instruction(Instruction),
|
||||||
|
.WrMem(WrMem),
|
||||||
|
.DWidth(DWidth),
|
||||||
|
// Register File
|
||||||
|
.Rs1(Rs1),
|
||||||
|
.Rs2(Rs2),
|
||||||
|
.Rd(Rd),
|
||||||
|
.RRs1(RRs1),
|
||||||
|
.RRs2(RRs2),
|
||||||
|
.WRd(WRd),
|
||||||
|
.WrReg(WrReg),
|
||||||
|
// Protection
|
||||||
|
.Illegal(Illegal)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Clock generation
|
||||||
|
always begin
|
||||||
|
clk = ~clk; #1;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Load a new instruction every cycle
|
||||||
|
always_ff @(posedge clk) begin: increment_instruction_and_print_info
|
||||||
|
if (counter < MEM_SIZE) begin
|
||||||
|
if (counter > 0) printInfo();
|
||||||
|
Instruction = mem[counter++];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Return the value of the RegFile
|
||||||
|
always_comb begin: reg_file_assignment
|
||||||
|
RRs1 = regFile[Rs1];
|
||||||
|
RRs2 = regFile[Rs2];
|
||||||
|
end
|
||||||
|
|
||||||
|
// Initialize and run simulation
|
||||||
|
initial begin
|
||||||
|
dumpWave("wave.vcd");
|
||||||
|
loadMem("decoder.hex");
|
||||||
|
clk = 1;
|
||||||
|
counter = 0;
|
||||||
|
CurrentPC = 32'hdeadbeef;
|
||||||
|
RData = 32'hbeefdead;
|
||||||
|
for(int i=0; i<REG_FILE_SIZE; i++) begin
|
||||||
|
regFile[i] = i;
|
||||||
|
end
|
||||||
|
while (counter < MEM_SIZE) #1;
|
||||||
|
printInfo();
|
||||||
|
#1 $finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
// Wave Dump Helper Task
|
||||||
|
task dumpWave(string fileName);
|
||||||
|
// Open wave file and dump all signals (2D arrays not included)
|
||||||
|
$display("\nTime = %0dns \t : Opening wave file '%s'", $time, fileName);
|
||||||
|
$dumpfile(fileName);
|
||||||
|
$display("Time = %0dns \t : Dumping all %s signals in wave file (2D arrays not included)", $time, "decoder_tb");
|
||||||
|
$dumpvars(0, decoder_tb);
|
||||||
|
endtask: dumpWave
|
||||||
|
|
||||||
|
// Load hex file into memory
|
||||||
|
task loadMem (string fileName);
|
||||||
|
$display("\nTime = %0dns \t : Loading '%s' into Memory", $time, fileName);
|
||||||
|
$readmemh(fileName, mem);
|
||||||
|
endtask: loadMem
|
||||||
|
|
||||||
|
// Print decoder signals
|
||||||
|
task printInfo();
|
||||||
|
$displayh("\n(cycle %0d) Decoder (I/O) \tDecoder (Internal Signals) \tALU" , counter );
|
||||||
|
$displayh(" -------------------------- \t--------------------------------------------- \t---------------------" );
|
||||||
|
$displayh(" CurrentPC : 0x%h OpCode : 0b%b aluOp : 0b%b" , CurrentPC , u_decoder.theOp , u_decoder.aluOp );
|
||||||
|
$displayh(" JumpOrBranchPC: 0x%h theFunct3: 0b%b aluNegAr : 0b%b" , JumpOrBranchPC, u_decoder.theFunct3, u_decoder.aluNegAr );
|
||||||
|
$displayh(" JumpOrBranch : 0b%b \ttheFunct7: 0b%b aluBypass: 0b%b", JumpOrBranch , u_decoder.theFunct7, u_decoder.aluBypass);
|
||||||
|
$displayh(" DAddr : 0x%h i_imm : 0b%b op1 : 0x%h" , DAddr , u_decoder.i_imm , u_decoder.op1 );
|
||||||
|
$displayh(" WData : 0x%h s_imm : 0b%b op2 : 0x%h" , WData , u_decoder.s_imm , u_decoder.op2 );
|
||||||
|
$displayh(" RData : 0x%h b_imm : 0b%b result : 0x%h" , RData , u_decoder.b_imm , u_decoder.result );
|
||||||
|
$displayh(" Instruction : 0x%h u_imm : 0b%b eqFlag : 0b%b" , Instruction , u_decoder.u_imm , u_decoder.eqFlag );
|
||||||
|
$displayh(" WrMem : 0b%b \tj_imm : 0b%b" , WrMem , u_decoder.j_imm );
|
||||||
|
$displayh(" DWidth : 0b%b" , DWidth );
|
||||||
|
$displayh(" Rs1 : %0d " , Rs1 );
|
||||||
|
$displayh(" Rs2 : %0d " , Rs2 );
|
||||||
|
$displayh(" Rd : 0x%h" , Rd );
|
||||||
|
$displayh(" RRs1 : %0d " , RRs1 );
|
||||||
|
$displayh(" RRs2 : %0d " , RRs2 );
|
||||||
|
$displayh(" WRd : 0x%h" , WRd );
|
||||||
|
$displayh(" WrReg : 0b%b" , WrReg );
|
||||||
|
$displayh(" Illegal : 0b%b" , Illegal );
|
||||||
|
endtask: printInfo
|
||||||
|
|
||||||
|
endmodule
|
||||||
238
riscv_rtl/hw/dv/rtl/main_mem_tb.sv
Normal file
238
riscv_rtl/hw/dv/rtl/main_mem_tb.sv
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 20.Oct.2025 by Aliakbar Merchant
|
||||||
|
// Last Modified : 24.Oct.2025 by Aliakbar Merchant [commit 89a5087]
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- --------- -------------------------------------------------
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
`timescale 1ns/1ns
|
||||||
|
|
||||||
|
module main_mem_tb ();
|
||||||
|
|
||||||
|
// local Parameters
|
||||||
|
localparam string MEM_INIT_FILE = "main_mem.hex";
|
||||||
|
// Helpers for addressing width
|
||||||
|
localparam logic[1:0] _byte = 2'b00; // byte: 8 bits
|
||||||
|
localparam logic[1:0] _half = 2'b01; // half: 16 bits
|
||||||
|
localparam logic[1:0] _word = 2'b10; // word: 32 bits
|
||||||
|
|
||||||
|
// Local Signals
|
||||||
|
// clk and reset
|
||||||
|
logic clk;
|
||||||
|
logic reset;
|
||||||
|
// Memory
|
||||||
|
logic[31:0] DAddr;
|
||||||
|
logic[31:0] IAddr;
|
||||||
|
logic[31:0] DWData;
|
||||||
|
logic[31:0] DRData;
|
||||||
|
logic[31:0] IRData;
|
||||||
|
logic DWE;
|
||||||
|
logic[1:0] DWidth;
|
||||||
|
// Helpers for display results purpose
|
||||||
|
logic[31:0] value_at_0;
|
||||||
|
logic[31:0] value_at_1;
|
||||||
|
logic[31:0] value_at_2;
|
||||||
|
logic[31:0] value_at_3;
|
||||||
|
logic[31:0] value_at_1024;
|
||||||
|
logic[31:0] value_at_1025;
|
||||||
|
logic[31:0] value_at_1026;
|
||||||
|
logic[31:0] value_at_1027;
|
||||||
|
|
||||||
|
// Toplevel instance (DUT)
|
||||||
|
main_mem u_main_mem (
|
||||||
|
.clk (clk ),
|
||||||
|
.reset (reset ),
|
||||||
|
.DAddr (DAddr ),
|
||||||
|
.IAddr (IAddr ),
|
||||||
|
.DWData (DWData ),
|
||||||
|
.DRData (DRData ),
|
||||||
|
.IRData (IRData ),
|
||||||
|
.DWE (DWE ),
|
||||||
|
.DWidth (DWidth )
|
||||||
|
);
|
||||||
|
|
||||||
|
// Clock generation
|
||||||
|
always #1 clk = ~clk;
|
||||||
|
|
||||||
|
// Initialize and run simulation
|
||||||
|
initial begin
|
||||||
|
loadMem(MEM_INIT_FILE);
|
||||||
|
value_at_0 = main_mem_tb.u_main_mem.RAM[0];
|
||||||
|
value_at_1 = main_mem_tb.u_main_mem.RAM[1];
|
||||||
|
value_at_2 = main_mem_tb.u_main_mem.RAM[2];
|
||||||
|
value_at_3 = main_mem_tb.u_main_mem.RAM[3];
|
||||||
|
value_at_1024 = main_mem_tb.u_main_mem.RAM[1024];
|
||||||
|
value_at_1025 = main_mem_tb.u_main_mem.RAM[1025];
|
||||||
|
value_at_1026 = main_mem_tb.u_main_mem.RAM[1026];
|
||||||
|
value_at_1027 = main_mem_tb.u_main_mem.RAM[1027];
|
||||||
|
clk = 0;
|
||||||
|
DAddr = 32'd4096;
|
||||||
|
IAddr = 0;
|
||||||
|
DWData = 0;
|
||||||
|
DWidth = 0;
|
||||||
|
reset = 1; DWE=1; #7;
|
||||||
|
DWE = 0;
|
||||||
|
reset = 0; #2;
|
||||||
|
test_scenario1(); #30;
|
||||||
|
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Test scenario 1
|
||||||
|
task test_scenario1();
|
||||||
|
fork
|
||||||
|
read_inst_mem(15);
|
||||||
|
display_inst_read_results();
|
||||||
|
write_data_mem(4096);
|
||||||
|
join
|
||||||
|
display_write_results();
|
||||||
|
fork
|
||||||
|
display_read_results();
|
||||||
|
read_data_mem(4096);
|
||||||
|
join
|
||||||
|
endtask: test_scenario1
|
||||||
|
|
||||||
|
// Intruction memory read transactions and results display
|
||||||
|
task read_inst_mem(int unsigned n = 1);
|
||||||
|
repeat(n) begin
|
||||||
|
cycles_pe(1);
|
||||||
|
IAddr = IAddr+4;
|
||||||
|
end
|
||||||
|
endtask:read_inst_mem
|
||||||
|
|
||||||
|
task display_inst_read_results();
|
||||||
|
$display("\n----------------------------------------------------------------------------------" );
|
||||||
|
$display("Instruction MEMORY READ RESULTS" );
|
||||||
|
$display("15 instruction are read by testbench starting at adrress 0x0000 i.e at (RAM[0]) but only 4 displyed for simplicity" );
|
||||||
|
$display("----------------------------------------------------------------------------------" );
|
||||||
|
|
||||||
|
cycles_pe(2);
|
||||||
|
$display("Time = %0dns \t : IAddr = 0x0000(RAM[0]): Expected value = 0x%h Actual Value at IRData: 0x%h" , $time, value_at_0, IRData );
|
||||||
|
cycles_pe(1);
|
||||||
|
$display("Time = %0dns \t : IAddr = 0x0004(RAM[1]): Expected value = 0x%h Actual Value at IRData: 0x%h" , $time, value_at_1, IRData );
|
||||||
|
cycles_pe(1);
|
||||||
|
$display("Time = %0dns \t : IAddr = 0x0008(RAM[2]): Expected value = 0x%h Actual Value at IRData: 0x%h" , $time, value_at_2, IRData );
|
||||||
|
cycles_pe(1);
|
||||||
|
$display("Time = %0dns \t : IAddr = 0x000c(RAM[3]): Expected value = 0x%h Actual Value at IRData: 0x%h" , $time, value_at_3, IRData );
|
||||||
|
endtask:display_inst_read_results
|
||||||
|
|
||||||
|
// Data memory write transaction and results display
|
||||||
|
task write_data_mem(logic [31:0] daddr_init=32'd4096);
|
||||||
|
cycles_pe(1);
|
||||||
|
DWE = 1;
|
||||||
|
DWidth = 0;
|
||||||
|
DAddr = daddr_init+0;
|
||||||
|
DWData = 32'hDEADBEEF;
|
||||||
|
cycles_pe(1);
|
||||||
|
DWE = 1;
|
||||||
|
DWidth = 1;
|
||||||
|
DAddr = daddr_init+4;
|
||||||
|
DWData = 32'hDEADBEEF;
|
||||||
|
cycles_pe(1);
|
||||||
|
DWE = 1;
|
||||||
|
DWidth = 2;
|
||||||
|
DAddr = daddr_init+8;
|
||||||
|
DWData = 32'hDEADBEEF;
|
||||||
|
cycles_pe(1);
|
||||||
|
DWE = 1;
|
||||||
|
DWidth = 3;
|
||||||
|
DAddr = daddr_init+12;
|
||||||
|
DWData = 32'hDEADBEEF;
|
||||||
|
cycles_pe(1);
|
||||||
|
DWE = 0;
|
||||||
|
endtask:write_data_mem
|
||||||
|
|
||||||
|
task display_write_results();
|
||||||
|
$display("\n----------------------------------------------------------------------------------" );
|
||||||
|
$display("DATA MEMORY WRITE RESULTS" );
|
||||||
|
$display("4 Write transaction are being done by testbench starting at adrress 0x1000 i.e at (RAM[1024]) with all 4 combination of DWidth" );
|
||||||
|
$display("Data written is always 0xDEADBEEF i.e DWData = DEADBEEF" );
|
||||||
|
$display("----------------------------------------------------------------------------------" );
|
||||||
|
|
||||||
|
$display("Time = %0dns \t : DWidth = 0 DAddr = 0x1000(RAM[1024]): Start value at RAM[1024] = 0x%h Expected value at RAM[1024]= 0xef%h Actual Value at RAM[1024]: 0x%h" , $time, value_at_1024,value_at_1024[23:0], getMem(1024) );
|
||||||
|
$display("Time = %0dns \t : DWidth = 1 DAddr = 0x1004(RAM[1025]): Start value at RAM[1025] = 0x%h Expected value at RAM[1025]= 0xbeef%h Actual Value at RAM[1025]: 0x%h" , $time, value_at_1025,value_at_1025[15:0], getMem(1025) );
|
||||||
|
$display("Time = %0dns \t : DWidth = 2 DAddr = 0x1008(RAM[1026]): Start value at RAM[1026] = 0x%h Expected value at RAM[1026]= 0xdeadbeef Actual Value at RAM[1026]: 0x%h" , $time, value_at_1026, getMem(1026) );
|
||||||
|
$display("Time = %0dns \t : DWidth = 3 DAddr = 0x100c(RAM[1027]): Start value at RAM[1027] = 0x%h Expected value at RAM[1027]= 0x%h Actual Value at RAM[1027]: 0x%h" , $time, value_at_1027,value_at_1027, getMem(1027) );
|
||||||
|
endtask:display_write_results
|
||||||
|
|
||||||
|
// Data Memory read transaction and results display
|
||||||
|
task read_data_mem(logic [31:0] daddr_init=32'd4096);
|
||||||
|
cycles_pe(1);
|
||||||
|
DWidth = 0;
|
||||||
|
DAddr = daddr_init+0;
|
||||||
|
cycles_pe(1);
|
||||||
|
DWidth = 1;
|
||||||
|
DAddr = daddr_init+4;
|
||||||
|
cycles_pe(1);
|
||||||
|
DWidth = 2;
|
||||||
|
DAddr = daddr_init+8;
|
||||||
|
cycles_pe(1);
|
||||||
|
DWidth = 3;
|
||||||
|
DAddr = daddr_init+12;
|
||||||
|
cycles_pe(1);
|
||||||
|
DWidth = 2;
|
||||||
|
DAddr = daddr_init+0;
|
||||||
|
cycles_pe(1);
|
||||||
|
DWidth = 2;
|
||||||
|
DAddr = daddr_init+4;
|
||||||
|
cycles_pe(1);
|
||||||
|
DWidth = 2;
|
||||||
|
DAddr = daddr_init+8;
|
||||||
|
cycles_pe(1);
|
||||||
|
DWidth = 2;
|
||||||
|
DAddr = daddr_init+12;
|
||||||
|
endtask:read_data_mem
|
||||||
|
|
||||||
|
task display_read_results();
|
||||||
|
$display("\n----------------------------------------------------------------------------------" );
|
||||||
|
$display("DATA MEMORY READ RESULTS" );
|
||||||
|
$display("8 Read transaction are being done by testbench starting at adrress 0x1000 i.e at (RAM[1024])" );
|
||||||
|
$display("----------------------------------------------------------------------------------" );
|
||||||
|
|
||||||
|
cycles_pe(2);
|
||||||
|
$display("Time = %0dns \t : DWidth = 0 DAddr = 0x1000(RAM[1024]): Expected value = 0x000000ef Actual Value at DRData: 0x%h" , $time, DRData );
|
||||||
|
cycles_pe(1);
|
||||||
|
$display("Time = %0dns \t : DWidth = 1 DAddr = 0x1004(RAM[1025]): Expected value = 0x0000beef Actual Value at DRData: 0x%h" , $time, DRData );
|
||||||
|
cycles_pe(1);
|
||||||
|
$display("Time = %0dns \t : DWidth = 2 DAddr = 0x1008(RAM[1026]): Expected value = 0xdeadbeef Actual Value at DRData: 0x%h" , $time, DRData );
|
||||||
|
cycles_pe(1);
|
||||||
|
$display("Time = %0dns \t : DWidth = 3 DAddr = 0x100c(RAM[1027]): Expected value = 0xdeadbeef Actual Value at DRData: 0x%h" , $time, DRData );
|
||||||
|
cycles_pe(1);
|
||||||
|
$display("Time = %0dns \t : DWidth = 2 DAddr = 0x1000(RAM[1024]): Expected value = 0xef%h Actual Value at DRData: 0x%h" , $time, value_at_1024[23:0], DRData );
|
||||||
|
cycles_pe(1);
|
||||||
|
$display("Time = %0dns \t : DWidth = 2 DAddr = 0x1004(RAM[1025]): Expected value = 0xbeef%h Actual Value at DRData: 0x%h" , $time, value_at_1025[15:0], DRData );
|
||||||
|
cycles_pe(1);
|
||||||
|
$display("Time = %0dns \t : DWidth = 2 DAddr = 0x1008(RAM[1026]): Expected value = 0xdeadbeef Actual Value at DRData: 0x%h" , $time, DRData );
|
||||||
|
cycles_pe(1);
|
||||||
|
$display("Time = %0dns \t : DWidth = 2 DAddr = 0x100c(RAM[1027]): Expected value = 0x%h Actual Value at DRData: 0x%h" , $time, value_at_1027, DRData );
|
||||||
|
endtask:display_read_results
|
||||||
|
|
||||||
|
|
||||||
|
// Helper tasks
|
||||||
|
// Memory
|
||||||
|
function int getMem(int location);
|
||||||
|
getMem = u_main_mem.RAM[location];
|
||||||
|
endfunction: getMem
|
||||||
|
|
||||||
|
task cycles_pe(int unsigned N = 1);
|
||||||
|
repeat(N) @(posedge clk);
|
||||||
|
endtask: cycles_pe
|
||||||
|
|
||||||
|
task cycles_ne(int unsigned N = 1);
|
||||||
|
repeat(N) @(negedge clk);
|
||||||
|
endtask: cycles_ne
|
||||||
|
|
||||||
|
// Load hex file into memory
|
||||||
|
task loadMem (string fileName);
|
||||||
|
$display("\nTime = %0dns \t : Loading '%s' into Memory", $time, fileName);
|
||||||
|
$readmemh(fileName, main_mem_tb.u_main_mem.RAM);
|
||||||
|
endtask: loadMem
|
||||||
|
|
||||||
|
endmodule
|
||||||
68
riscv_rtl/hw/dv/rtl/pc_tb.sv
Normal file
68
riscv_rtl/hw/dv/rtl/pc_tb.sv
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 15.Oct.2025 by Bomin Kim
|
||||||
|
// Last Modified : 23.Oct.2025 by Bomin Kim [commit 2f8f03d]
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- --------- -------------------------------------------------
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
`timescale 1ns/1ns
|
||||||
|
|
||||||
|
module pc_tb ();
|
||||||
|
|
||||||
|
// Local Signals
|
||||||
|
logic[31:0] CurrentPC;
|
||||||
|
logic[31:0] JumpOrBranchPC;
|
||||||
|
logic JumpOrBranch;
|
||||||
|
logic[31:0] NextPC;
|
||||||
|
logic reset;
|
||||||
|
logic clk;
|
||||||
|
|
||||||
|
// Toplevel instance (DUT)
|
||||||
|
pc u_pc (
|
||||||
|
.CurrentPC(CurrentPC),
|
||||||
|
.JumpOrBranchPC(JumpOrBranchPC),
|
||||||
|
.JumpOrBranch(JumpOrBranch),
|
||||||
|
.NextPC(NextPC),
|
||||||
|
.reset(reset),
|
||||||
|
.clk(clk)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Clock generation
|
||||||
|
always #20 clk = ~clk;
|
||||||
|
|
||||||
|
// Initialization and run simulation
|
||||||
|
initial begin
|
||||||
|
dumpWave("wave.vcd");
|
||||||
|
clk = 0;
|
||||||
|
JumpOrBranchPC = 32'h8;
|
||||||
|
JumpOrBranch = 0;
|
||||||
|
reset = 0; #100;
|
||||||
|
reset = 1; #100;
|
||||||
|
reset = 0; #490;
|
||||||
|
JumpOrBranch = 1; #60;
|
||||||
|
JumpOrBranch = 0; #500;
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
// NextPC Monitor
|
||||||
|
initial begin
|
||||||
|
$monitor("time=%0t clk=%b reset=%b JumpOrBranch=%0h CurrentPC=%0h NextPC=%0h", $time, clk, reset, JumpOrBranch, CurrentPC, NextPC);
|
||||||
|
end
|
||||||
|
|
||||||
|
// Wave Dump Helper Task
|
||||||
|
task dumpWave(string fileName);
|
||||||
|
// Open wave file and dump all signals (2D arrays not included)
|
||||||
|
$display("\nTime = %0dns \t : Opening wave file '%s'", $time, fileName);
|
||||||
|
$dumpfile(fileName);
|
||||||
|
$display("Time = %0dns \t : Dumping all %s signals in wave file (2D arrays not included)", $time, "pc_tb");
|
||||||
|
$dumpvars(0, pc_tb);
|
||||||
|
endtask: dumpWave
|
||||||
|
|
||||||
|
endmodule
|
||||||
137
riscv_rtl/hw/dv/rtl/reg_file_tb.sv
Normal file
137
riscv_rtl/hw/dv/rtl/reg_file_tb.sv
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 15.Oct.2025 by Bomin Kim
|
||||||
|
// Last Modified : 23.Oct.2025 by Bomin Kim [commit 2f8f03d]
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- --------- -------------------------------------------------
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
`timescale 1ns/1ns
|
||||||
|
|
||||||
|
module reg_file_tb ();
|
||||||
|
|
||||||
|
// Local Signals
|
||||||
|
logic[4:0] Rs1;
|
||||||
|
logic[4:0] Rs2;
|
||||||
|
logic[4:0] Rd;
|
||||||
|
logic[31:0] RRs1;
|
||||||
|
logic[31:0] RRs2;
|
||||||
|
logic[31:0] WRd;
|
||||||
|
logic WrReg;
|
||||||
|
logic reset;
|
||||||
|
logic clk;
|
||||||
|
|
||||||
|
// Toplevel instance (DUT)
|
||||||
|
reg_file u_reg_file (
|
||||||
|
.Rs1(Rs1),
|
||||||
|
.Rs2(Rs2),
|
||||||
|
.Rd(Rd),
|
||||||
|
.RRs1(RRs1),
|
||||||
|
.RRs2(RRs2),
|
||||||
|
.WRd(WRd),
|
||||||
|
.WrReg(WrReg),
|
||||||
|
.reset(reset),
|
||||||
|
.clk(clk)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Clock generation
|
||||||
|
always #20 clk = ~clk;
|
||||||
|
|
||||||
|
// Initialization and run simulation
|
||||||
|
initial begin
|
||||||
|
dumpWave("wave.vcd");
|
||||||
|
|
||||||
|
// Initialize inputs
|
||||||
|
clk = 0;
|
||||||
|
Rs1 = 0; Rs2 = 0; Rd = 0;
|
||||||
|
WRd = 0; WrReg = 0; // Read
|
||||||
|
reset = 1;
|
||||||
|
|
||||||
|
#50
|
||||||
|
reset = 0;
|
||||||
|
|
||||||
|
#50 // Write 0xDEADBEEF to reg21
|
||||||
|
Rd = 5'd21;
|
||||||
|
WrReg = 1; // Write
|
||||||
|
WRd = 32'hDEADBEEF;
|
||||||
|
#50; WrReg = 0;
|
||||||
|
|
||||||
|
#50
|
||||||
|
Rs1 = 5'd21; // read reg21 into RRs1
|
||||||
|
Rs2 = 5'd0;
|
||||||
|
|
||||||
|
#50 // Write 0x12345678 to reg5
|
||||||
|
Rd = 5'd5;
|
||||||
|
WrReg = 1; // Write
|
||||||
|
WRd = 32'h12345678;
|
||||||
|
#50; WrReg = 0;
|
||||||
|
|
||||||
|
#50
|
||||||
|
Rs1 = 5'd5; // read reg10 into RRs1
|
||||||
|
|
||||||
|
#50
|
||||||
|
Rs1 = 5'd0; // read zero register
|
||||||
|
|
||||||
|
#50
|
||||||
|
Rd = 5'd0; // attempt to write 0xCAFEBABE to zero register
|
||||||
|
WRd = 32'hCAFEBABE;
|
||||||
|
WrReg = 1; // Write
|
||||||
|
#50; WrReg = 0;
|
||||||
|
|
||||||
|
#50
|
||||||
|
Rs1 = 5'd5; // Read from reg5
|
||||||
|
#200
|
||||||
|
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Wave Dump Helper Task
|
||||||
|
task dumpWave(string fileName);
|
||||||
|
// Open wave file and dump all signals (2D arrays not included)
|
||||||
|
$display("\nTime = %0dns \t : Opening wave file '%s'", $time, fileName);
|
||||||
|
$dumpfile(fileName);
|
||||||
|
$display("Time = %0dns \t : Dumping all %s signals in wave file (2D arrays not included)", $time, "reg_file_tb");
|
||||||
|
$dumpvars(0, reg_file_tb);
|
||||||
|
|
||||||
|
// Dump registers in wave file
|
||||||
|
$display("\nTime = %0dns \t : Dumping Registers in wave file", $time);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[1]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[2]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[3]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[4]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[5]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[6]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[7]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[8]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[9]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[10]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[11]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[12]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[13]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[14]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[15]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[16]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[17]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[18]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[19]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[20]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[21]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[22]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[23]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[24]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[25]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[26]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[27]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[28]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[29]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[30]);
|
||||||
|
$dumpvars(0, reg_file_tb.u_reg_file.registers[31]);
|
||||||
|
endtask: dumpWave
|
||||||
|
|
||||||
|
endmodule
|
||||||
79
riscv_rtl/hw/dv/rtl/transcript
Normal file
79
riscv_rtl/hw/dv/rtl/transcript
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
# OpenFile ./cpu_tb.sv
|
||||||
|
ls
|
||||||
|
# alu_tb.sv decoder_tb.sv pc_tb.sv transcript
|
||||||
|
# cpu_tb.sv main_mem_tb.sv reg_file_tb.sv work
|
||||||
|
vsim compile.tcl
|
||||||
|
# vsim compile.tcl
|
||||||
|
# Start time: 11:01:25 on Nov 28,2025
|
||||||
|
# ** Error (suppressible): (vsim-19) Failed to access library 'compile' at "compile".
|
||||||
|
# No such file or directory. (errno = ENOENT)
|
||||||
|
# Error loading design
|
||||||
|
# End time: 11:01:25 on Nov 28,2025, Elapsed time: 0:00:00
|
||||||
|
# Errors: 1, Warnings: 0
|
||||||
|
ls
|
||||||
|
# alu_tb.sv decoder_tb.sv pc_tb.sv transcript
|
||||||
|
# cpu_tb.sv main_mem_tb.sv reg_file_tb.sv work
|
||||||
|
cd ..
|
||||||
|
ls
|
||||||
|
# rtl verilator wave_configs
|
||||||
|
cd ..
|
||||||
|
pwd
|
||||||
|
# C:/PhD/RISC-V Design Course Material/RISC-V Desgin Course - Complete Source Code/riscv_in3days-public/hw
|
||||||
|
cd ..
|
||||||
|
ls
|
||||||
|
# README.md doc hw sw
|
||||||
|
cd ..
|
||||||
|
ls
|
||||||
|
# riscv_in3days-public
|
||||||
|
cd ..
|
||||||
|
ls
|
||||||
|
# Course Introduction & Closing - Public.pdf
|
||||||
|
# Day 1
|
||||||
|
# Day 2
|
||||||
|
# Day 3
|
||||||
|
# Day 4
|
||||||
|
# RISC-V Desgin Course - Complete Source Code
|
||||||
|
# References
|
||||||
|
cd ..
|
||||||
|
cd ..
|
||||||
|
la
|
||||||
|
# ambiguous command name "la": label labelframe langOf lappend lassign lattice_edition layout
|
||||||
|
ls
|
||||||
|
# Drivers Program Files (x86) inetpub
|
||||||
|
# DumpStack.log Steam_Community_Markt intelFPGA
|
||||||
|
# Lukas Users intelFPGA_lite
|
||||||
|
# PhD Windows vfcompat.dll
|
||||||
|
# ProcLogs appverifUI.dll
|
||||||
|
# Program Files flexlm
|
||||||
|
pwd
|
||||||
|
# C:/
|
||||||
|
ls
|
||||||
|
# Drivers Program Files (x86) inetpub
|
||||||
|
# DumpStack.log Steam_Community_Markt intelFPGA
|
||||||
|
# Lukas Users intelFPGA_lite
|
||||||
|
# PhD Windows vfcompat.dll
|
||||||
|
# ProcLogs appverifUI.dll
|
||||||
|
# Program Files flexlm
|
||||||
|
cd PhD
|
||||||
|
ls
|
||||||
|
# Code compile.tcl
|
||||||
|
# RISC-V Design Course Material
|
||||||
|
cd RISC-V Design Course Material
|
||||||
|
# wrong # args: should be "cd ?dirName?"
|
||||||
|
ls
|
||||||
|
# Code compile.tcl
|
||||||
|
# RISC-V Design Course Material
|
||||||
|
ls
|
||||||
|
# Code compile.tcl
|
||||||
|
# RISC-V Design Course Material
|
||||||
|
cd RISC-V Design Course Material
|
||||||
|
# wrong # args: should be "cd ?dirName?"
|
||||||
|
ls
|
||||||
|
# Code compile.tcl
|
||||||
|
# RISC-V Design Course Material
|
||||||
|
run compile.tcl
|
||||||
|
# No Design Loaded!
|
||||||
|
compile.tcl
|
||||||
|
# couldn't execute ".\compile.tcl": no such file or directory
|
||||||
|
run compile.tcl
|
||||||
|
# No Design Loaded!
|
||||||
10
riscv_rtl/hw/dv/rtl/work/_info
Normal file
10
riscv_rtl/hw/dv/rtl/work/_info
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
m255
|
||||||
|
K4
|
||||||
|
z2
|
||||||
|
13
|
||||||
|
!s112 1.1
|
||||||
|
!i10d 8192
|
||||||
|
!i10e 25
|
||||||
|
!i10f 100
|
||||||
|
cModel Technology
|
||||||
|
dC:/PhD/RISC-V Design Course Material/RISC-V Desgin Course - Complete Source Code/riscv_in3days-public/hw/dv/rtl
|
||||||
BIN
riscv_rtl/hw/dv/rtl/work/_lib.qdb
Normal file
BIN
riscv_rtl/hw/dv/rtl/work/_lib.qdb
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/dv/rtl/work/_lib1_0.qdb
Normal file
BIN
riscv_rtl/hw/dv/rtl/work/_lib1_0.qdb
Normal file
Binary file not shown.
0
riscv_rtl/hw/dv/rtl/work/_lib1_0.qpg
Normal file
0
riscv_rtl/hw/dv/rtl/work/_lib1_0.qpg
Normal file
BIN
riscv_rtl/hw/dv/rtl/work/_lib1_0.qtl
Normal file
BIN
riscv_rtl/hw/dv/rtl/work/_lib1_0.qtl
Normal file
Binary file not shown.
78
riscv_rtl/hw/dv/verilator/Makefile
Normal file
78
riscv_rtl/hw/dv/verilator/Makefile
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
export PRJ_ROOT = ../../..
|
||||||
|
|
||||||
|
|
||||||
|
# directroy containig syrinx application programs
|
||||||
|
SWDIR = $(PRJ_ROOT)/sw/risc-v
|
||||||
|
DVDIR = $(PRJ_ROOT)/hw/dv
|
||||||
|
|
||||||
|
# toplevel syrinx file list
|
||||||
|
RTL_FLIST = $(PRJ_ROOT)/hw/file_lists/rtl_flist.f
|
||||||
|
TB_FLIST = $(PRJ_ROOT)/hw/file_lists/tb_flist.f
|
||||||
|
|
||||||
|
|
||||||
|
# if we have multiple file list, we combine them here
|
||||||
|
FLIST = -f $(RTL_FLIST) -f $(TB_FLIST)
|
||||||
|
|
||||||
|
# Default number of simulation cycles
|
||||||
|
NCYCLES ?= 500
|
||||||
|
|
||||||
|
# Standard boot loader and dummy application to be used if nothing else is specified
|
||||||
|
|
||||||
|
PROG ?= $(SWDIR)/hello_world/helloWorld.hex
|
||||||
|
|
||||||
|
# top module name
|
||||||
|
TOPMODULE = cpu_harness
|
||||||
|
|
||||||
|
# NUmber of GCC parallel threads
|
||||||
|
COMPILE_THREADS = 32
|
||||||
|
|
||||||
|
# Verilator CPU usage, should be adapated to simulation host
|
||||||
|
SIM_THREADS = 4
|
||||||
|
TRACE_THREADS = 1
|
||||||
|
|
||||||
|
|
||||||
|
EXTRA_ARGS += --trace-fst --trace-structs --trace-max-array 2048 --trace-threads $(TRACE_THREADS) --threads $(SIM_THREADS)
|
||||||
|
EXTRA_ARGS += --clk clk --no-timing
|
||||||
|
# EXTRA_ARGS += -O2
|
||||||
|
|
||||||
|
# Used by some code constructs
|
||||||
|
VDEFS = +define+SIMULATION
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
all: ./obj_dir/V$(TOPMODULE)
|
||||||
|
|
||||||
|
wave: wavedump.fst
|
||||||
|
@echo
|
||||||
|
@echo "*** Starting waveform viewer..."
|
||||||
|
$(WAVE_VIEWER) wavedump.fst -s $(DVDIR)/wave_configs/verilator_wave.surf.ron
|
||||||
|
|
||||||
|
run:
|
||||||
|
@echo
|
||||||
|
@echo "*** Running simulation..."
|
||||||
|
@./obj_dir/V$(TOPMODULE) $(NCYCLES) $(PROG)
|
||||||
|
|
||||||
|
./obj_dir/V$(TOPMODULE): .stamp.verilate
|
||||||
|
@echo
|
||||||
|
@echo "*** Building simulator..."
|
||||||
|
make -C obj_dir -f V$(TOPMODULE).mk V$(TOPMODULE) -j $(COMPILE_THREADS)
|
||||||
|
|
||||||
|
.stamp.verilate: src/tb_$(TOPMODULE).cpp
|
||||||
|
@echo "*** Generating C++ model..."
|
||||||
|
$(VERILATOR) --trace $(EXTRA_ARGS) $(VDEFS) -cc $(FLIST) --top-module $(TOPMODULE) --exe src/tb_$(TOPMODULE).cpp
|
||||||
|
@touch .stamp.verilate
|
||||||
|
|
||||||
|
lint:$(VERILOG_SOURCES)
|
||||||
|
$(VERILATOR) --lint-only $(INCLUDES) $(VERILOG_SOURCES) --top-module $(TOPMODULE)
|
||||||
|
|
||||||
|
|
||||||
|
paths:
|
||||||
|
@echo $(PRJ_ROOT)/$(APB)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf .stamp.*;
|
||||||
|
rm -rf ./obj_dir
|
||||||
|
rm -rf wavedump.fst*
|
||||||
|
rm -rf *.dasm
|
||||||
148
riscv_rtl/hw/dv/verilator/rtl/cpu_harness.sv
Normal file
148
riscv_rtl/hw/dv/verilator/rtl/cpu_harness.sv
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Description : Verilator simulation harness
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 12.Aug.2025 by Marcus Bednara
|
||||||
|
// Last Modified : 15.Oct.2025 by Hussein Elzomor [commit d0452cd]
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- --------- -------------------------------------------------
|
||||||
|
// 15.Oct.2025 H.Elzomor Renamed file and module from soc_harness to cpu_harness
|
||||||
|
// 15.Oct.2025 H.Elzomor Added getMem function, setMem task and printMem task
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
timeunit 1ps;
|
||||||
|
timeprecision 1ps;
|
||||||
|
|
||||||
|
module cpu_harness;
|
||||||
|
|
||||||
|
// local signals
|
||||||
|
logic clk,
|
||||||
|
rst;
|
||||||
|
|
||||||
|
logic [7:0] led;
|
||||||
|
|
||||||
|
logic [6:0] btn;
|
||||||
|
|
||||||
|
|
||||||
|
// toplevel instance (DUT)
|
||||||
|
|
||||||
|
cpu u_cpu (
|
||||||
|
.led (led),
|
||||||
|
.btn ({btn[6:1], rst}),
|
||||||
|
.clk_25mhz (clk)
|
||||||
|
); // u_cpu
|
||||||
|
|
||||||
|
|
||||||
|
`ifdef VERILATOR
|
||||||
|
|
||||||
|
// Declare all functions with DPI-C interface to make them accessible from the C++ testbench
|
||||||
|
|
||||||
|
export "DPI-C" task setClk;
|
||||||
|
export "DPI-C" task enable;
|
||||||
|
export "DPI-C" task loadRAM;
|
||||||
|
// export "DPI-C" task dumpSRAM;
|
||||||
|
export "DPI-C" task setInitial;
|
||||||
|
export "DPI-C" function getLed;
|
||||||
|
export "DPI-C" task setBtn;
|
||||||
|
export "DPI-C" task setReset;
|
||||||
|
export "DPI-C" function getMem;
|
||||||
|
export "DPI-C" task setMem;
|
||||||
|
export "DPI-C" task printMem;
|
||||||
|
export "DPI-C" function getReg;
|
||||||
|
export "DPI-C" task printReg;
|
||||||
|
|
||||||
|
|
||||||
|
// Clocking is controlled from C++ testbench
|
||||||
|
task setClk (input logic val);
|
||||||
|
clk = val;
|
||||||
|
endtask: setClk
|
||||||
|
|
||||||
|
`else
|
||||||
|
|
||||||
|
// If not using verilator, generate clock here
|
||||||
|
|
||||||
|
const realtime clk_PERIOD = 1.0ns;
|
||||||
|
|
||||||
|
|
||||||
|
initial begin: clock_driver
|
||||||
|
clk = '1;
|
||||||
|
forever begin
|
||||||
|
#(clk_PERIOD/2.0);
|
||||||
|
clk <= ~clk;
|
||||||
|
end
|
||||||
|
end: clock_driver
|
||||||
|
|
||||||
|
task wait_clk_cycles(int unsigned n);
|
||||||
|
repeat(n) @(posedge clk);
|
||||||
|
endtask
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
// Remaining tasks are identical for Verilator and other simulators
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
task loadRAM (input string fileName);
|
||||||
|
$display ("Initializing SRAM memory from %s", fileName);
|
||||||
|
$readmemh(fileName, u_cpu.theMem.RAM);
|
||||||
|
endtask: loadRAM
|
||||||
|
|
||||||
|
|
||||||
|
/* Some helper stuff */
|
||||||
|
|
||||||
|
task enable(int val);
|
||||||
|
// nothing to do, we have no fetch enable in this design
|
||||||
|
endtask: enable
|
||||||
|
|
||||||
|
task setInitial();
|
||||||
|
btn = 7'b0;
|
||||||
|
rst = 'b0;
|
||||||
|
endtask: setInitial
|
||||||
|
|
||||||
|
function int getLed;
|
||||||
|
getLed = {24'b0, led};
|
||||||
|
endfunction: getLed
|
||||||
|
|
||||||
|
task setBtn(int val);
|
||||||
|
btn[6:1] = val[5:0];
|
||||||
|
endtask: setBtn
|
||||||
|
|
||||||
|
task setReset (input int val);
|
||||||
|
rst = (val==1);
|
||||||
|
endtask: setReset
|
||||||
|
|
||||||
|
function int getMem(int location);
|
||||||
|
getMem = u_cpu.theMem.RAM[location];
|
||||||
|
endfunction: getMem
|
||||||
|
|
||||||
|
task setMem(int location, int value);
|
||||||
|
u_cpu.theMem.RAM[location] = value;
|
||||||
|
endtask: setMem
|
||||||
|
|
||||||
|
task printMem (int location, string prog);
|
||||||
|
case (prog)
|
||||||
|
"fibonacci" :$display("Value at RAM[%0d]: 0x%h : %0d", location, getMem(location), getMem(location));
|
||||||
|
"helloWorld" :$display("Value at RAM[%0d]: 0x%h : %s" , location, getMem(location), getMem(location));
|
||||||
|
default :$display("Value at RAM[%0d]: 0x%h : %0d", location, getMem(location), getMem(location));
|
||||||
|
endcase
|
||||||
|
endtask: printMem
|
||||||
|
|
||||||
|
function int getReg(int location);
|
||||||
|
getReg = u_cpu.theRegisters.registers[location];
|
||||||
|
endfunction: getReg
|
||||||
|
|
||||||
|
task printReg (int location, string prog);
|
||||||
|
case (prog)
|
||||||
|
"primeNumber" :$display("Time =%5dns \t : Register [%0d] updated - Finding the prime factors of %0d", $time, location, getReg(location));
|
||||||
|
"primeFactors":$display("Time =%5dns \t : Register [%0d] updated - %0d is a prime factor", $time, location, getReg(location));
|
||||||
|
default :$display("Time =%5dns \t : Value at Reg[%0d]: 0x%h", $time, location, getReg(location));
|
||||||
|
endcase
|
||||||
|
endtask: printReg
|
||||||
|
|
||||||
|
endmodule: cpu_harness
|
||||||
173
riscv_rtl/hw/dv/verilator/rtl/decoder_harness.sv
Normal file
173
riscv_rtl/hw/dv/verilator/rtl/decoder_harness.sv
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Description : Verilator simulation harness
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 15.Oct.2025 by Hussein Elzomor
|
||||||
|
// Last Modified : 15.Oct.2025 by Hussein Elzomor
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- --------- -------------------------------------------------
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
timeunit 1ps;
|
||||||
|
timeprecision 1ps;
|
||||||
|
|
||||||
|
module decoder_harness;
|
||||||
|
// local Parameters
|
||||||
|
localparam MEM_SIZE = 37;
|
||||||
|
localparam REG_FILE_SIZE = 32;
|
||||||
|
|
||||||
|
// local signals
|
||||||
|
logic clk;
|
||||||
|
int counter;
|
||||||
|
logic[31:0] mem [MEM_SIZE-1:0];
|
||||||
|
logic[31:0] regFile [REG_FILE_SIZE-1:0];
|
||||||
|
// PC
|
||||||
|
logic[31:0] CurrentPC;
|
||||||
|
logic[31:0] JumpOrBranchPC;
|
||||||
|
logic JumpOrBranch;
|
||||||
|
logic[31:0] NextPC;
|
||||||
|
// Memory
|
||||||
|
logic[31:0] DAddr;
|
||||||
|
logic[31:0] WData;
|
||||||
|
logic[31:0] RData;
|
||||||
|
logic[31:0] Instruction;
|
||||||
|
logic WrMem;
|
||||||
|
logic[1:0] DWidth;
|
||||||
|
// Register File;
|
||||||
|
logic[4:0] Rs1;
|
||||||
|
logic[4:0] Rs2;
|
||||||
|
logic[4:0] Rd;
|
||||||
|
logic[31:0] RRs1;
|
||||||
|
logic[31:0] RRs2;
|
||||||
|
logic[31:0] WRd;
|
||||||
|
logic WrReg;
|
||||||
|
// Protection
|
||||||
|
logic Illegal;
|
||||||
|
|
||||||
|
// toplevel instance (DUT)
|
||||||
|
decoder u_decoder (
|
||||||
|
// PC
|
||||||
|
.CurrentPC(CurrentPC),
|
||||||
|
.JumpOrBranchPC(JumpOrBranchPC),
|
||||||
|
.JumpOrBranch(JumpOrBranch),
|
||||||
|
// Memory
|
||||||
|
.DAddr(DAddr),
|
||||||
|
.WData(WData),
|
||||||
|
.RData(RData),
|
||||||
|
.Instruction(Instruction),
|
||||||
|
.WrMem(WrMem),
|
||||||
|
.DWidth(DWidth),
|
||||||
|
// Register File
|
||||||
|
.Rs1(Rs1),
|
||||||
|
.Rs2(Rs2),
|
||||||
|
.Rd(Rd),
|
||||||
|
.RRs1(RRs1),
|
||||||
|
.RRs2(RRs2),
|
||||||
|
.WRd(WRd),
|
||||||
|
.WrReg(WrReg),
|
||||||
|
// Protection
|
||||||
|
.Illegal(Illegal)
|
||||||
|
); // u_decoder
|
||||||
|
|
||||||
|
|
||||||
|
// Special Verilator specific tasks
|
||||||
|
`ifdef VERILATOR
|
||||||
|
|
||||||
|
// Declare all functions with DPI-C interface to make them accessible from the C++ testbench
|
||||||
|
// Setters
|
||||||
|
export "DPI-C" task setClk;
|
||||||
|
export "DPI-C" task enable;
|
||||||
|
export "DPI-C" task loadRAM;
|
||||||
|
export "DPI-C" task setInitial;
|
||||||
|
export "DPI-C" task printInfo;
|
||||||
|
|
||||||
|
// Clocking is controlled from C++ testbench
|
||||||
|
task setClk (input logic val);
|
||||||
|
clk = val;
|
||||||
|
endtask: setClk
|
||||||
|
|
||||||
|
`else
|
||||||
|
|
||||||
|
// If not using verilator, generate clock here
|
||||||
|
const realtime clk_PERIOD = 1.0ns;
|
||||||
|
|
||||||
|
initial begin: clock_driver
|
||||||
|
clk = '1;
|
||||||
|
forever begin
|
||||||
|
#(clk_PERIOD/2.0);
|
||||||
|
clk <= ~clk;
|
||||||
|
end
|
||||||
|
end: clock_driver
|
||||||
|
|
||||||
|
task wait_clk_cycles(int unsigned n);
|
||||||
|
repeat(n) @(posedge clk);
|
||||||
|
endtask
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
|
// Load a new instruction every cycle
|
||||||
|
always_ff @(posedge clk) begin: increment_instruction_and_print_info
|
||||||
|
if (counter < MEM_SIZE) begin
|
||||||
|
if (counter > 0) printInfo();
|
||||||
|
Instruction = mem[counter++];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Return the value of the RegFile
|
||||||
|
always_comb begin: reg_file_assignment
|
||||||
|
RRs1 = regFile[Rs1];
|
||||||
|
RRs2 = regFile[Rs2];
|
||||||
|
end
|
||||||
|
|
||||||
|
// Remaining tasks are identical for Verilator and other simulators
|
||||||
|
task enable(int val);
|
||||||
|
// nothing to do, we have no fetch enable in this design
|
||||||
|
endtask: enable
|
||||||
|
|
||||||
|
// Load data into memory
|
||||||
|
task loadRAM (input string fileName);
|
||||||
|
$display ("Initializing SRAM memory from %s", fileName);
|
||||||
|
$readmemh(fileName, mem);
|
||||||
|
endtask: loadRAM
|
||||||
|
|
||||||
|
// Set initial values
|
||||||
|
task setInitial();
|
||||||
|
Instruction = mem[0];
|
||||||
|
counter = 0;
|
||||||
|
CurrentPC = 32'hdeadbeef;
|
||||||
|
RData = 32'hbeefdead;
|
||||||
|
for(int i=0; i<REG_FILE_SIZE; i++) begin
|
||||||
|
regFile[i] = i;
|
||||||
|
end
|
||||||
|
endtask: setInitial
|
||||||
|
|
||||||
|
// Print decoder signals
|
||||||
|
task printInfo();
|
||||||
|
$displayh("(cycle %0d) Decoder (I/O) \tDecoder (Internal Signals) \tALU" , counter );
|
||||||
|
$displayh(" -------------------------- \t--------------------------------------------- \t---------------------" , );
|
||||||
|
$displayh(" CurrentPC : 0x%h OpCode : 0b%b aluOp : 0b%b" , CurrentPC , u_decoder.theOp , u_decoder.aluOp );
|
||||||
|
$displayh(" JumpOrBranchPC: 0x%h theFunct3: 0b%b aluNegAr : 0b%b", JumpOrBranchPC, u_decoder.theFunct3, u_decoder.aluNegAr );
|
||||||
|
$displayh(" JumpOrBranch : 0b%b \ttheFunct7: 0b%b aluBypass: 0b%b", JumpOrBranch , u_decoder.theFunct7, u_decoder.aluBypass);
|
||||||
|
$displayh(" DAddr : 0x%h i_imm : 0b%b op1 : 0x%h" , DAddr , u_decoder.i_imm , u_decoder.op1 );
|
||||||
|
$displayh(" WData : 0x%h s_imm : 0b%b op2 : 0x%h" , WData , u_decoder.s_imm , u_decoder.op2 );
|
||||||
|
$displayh(" RData : 0x%h b_imm : 0b%b result : 0x%h" , RData , u_decoder.b_imm , u_decoder.result );
|
||||||
|
$displayh(" Instruction : 0x%h u_imm : 0b%b eqFlag : 0b%b" , Instruction , u_decoder.u_imm , u_decoder.eqFlag );
|
||||||
|
$displayh(" WrMem : 0b%b \tj_imm : 0b%b" , WrMem , u_decoder.j_imm );
|
||||||
|
$displayh(" DWidth : 0b%b" , DWidth );
|
||||||
|
$displayh(" Rs1 : %0d " , Rs1 );
|
||||||
|
$displayh(" Rs2 : %0d " , Rs2 );
|
||||||
|
$displayh(" Rd : 0x%h" , Rd );
|
||||||
|
$displayh(" RRs1 : %0d " , RRs1 );
|
||||||
|
$displayh(" RRs2 : %0d " , RRs2 );
|
||||||
|
$displayh(" WRd : 0x%h" , WRd );
|
||||||
|
$displayh(" WrReg : 0b%b" , WrReg );
|
||||||
|
$displayh(" Illegal : 0b%b" , Illegal );
|
||||||
|
$displayh("");
|
||||||
|
endtask: printInfo
|
||||||
|
|
||||||
|
endmodule: decoder_harness
|
||||||
328
riscv_rtl/hw/dv/verilator/src/tb_cpu_harness.cpp
Normal file
328
riscv_rtl/hw/dv/verilator/src/tb_cpu_harness.cpp
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Description : Verilator tb
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 12.Aug.2025 by Marcus Bednara
|
||||||
|
// Last Modified : 15.Oct.2025 by Hussein Elzomor [commit d0452cd]
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- --------- -------------------------------------------------
|
||||||
|
// 15.Oct.2025 H.Elzomor Renamed modules from *soc* to *cpu*
|
||||||
|
// 15.Oct.2025 H.Elzomor Added evalText function
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <verilated.h>
|
||||||
|
#include <verilated_fst_c.h>
|
||||||
|
#include "Vcpu_harness.h"
|
||||||
|
#include "Vcpu_harness__Dpi.h"
|
||||||
|
|
||||||
|
// only required for accessing model internal memory ressources via the rootp pointer.
|
||||||
|
// Bad style, better use systemverilog harness with tasks and functions to do that.
|
||||||
|
// #include "Vcpu_harness___024root.h"
|
||||||
|
// #include "svdpi.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define SOC_CLK_PERIOD 40
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief Simulation environment class for the cpu model.
|
||||||
|
/// Contains a set of high level methods for controlling the model from test environment.
|
||||||
|
class cpu
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Vcpu_harness *dut;
|
||||||
|
VerilatedFstC *mTrace;
|
||||||
|
vluint64_t T;
|
||||||
|
|
||||||
|
uint32_t cpuClkState;
|
||||||
|
|
||||||
|
bool running;
|
||||||
|
|
||||||
|
string program;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief Constructor
|
||||||
|
cpu (int argc, char** argv)
|
||||||
|
{
|
||||||
|
// setup verilator stuff
|
||||||
|
T = 0;
|
||||||
|
dut = new Vcpu_harness();
|
||||||
|
Verilated::commandArgs(argc, argv);
|
||||||
|
Verilated::traceEverOn(true);
|
||||||
|
mTrace = new VerilatedFstC;
|
||||||
|
dut->trace(mTrace, 5);
|
||||||
|
mTrace->open("wavedump.fst");
|
||||||
|
|
||||||
|
cout << "Registered DPI-C functions:\n";
|
||||||
|
Verilated::scopesDump();
|
||||||
|
const svScope scope = svGetScopeFromName("TOP.cpu_harness");
|
||||||
|
assert(scope); // Check for nullptr if scope not found
|
||||||
|
svSetScope(scope);
|
||||||
|
|
||||||
|
running = false;
|
||||||
|
|
||||||
|
// initialize all input signals
|
||||||
|
initSignals();
|
||||||
|
|
||||||
|
} // swirl()
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief simulation tick, advances the simulation time and calls the eval() function of the model on every active clock edge
|
||||||
|
void tick ()
|
||||||
|
{
|
||||||
|
int do_eval;
|
||||||
|
|
||||||
|
if (T%SOC_CLK_PERIOD==0) {
|
||||||
|
dut->setClk(cpuClkState);
|
||||||
|
cpuClkState = 1-cpuClkState;
|
||||||
|
do_eval = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Other clock domains must be generated the same way
|
||||||
|
|
||||||
|
// if (T%OTHER_CLK_PERIOD==0) {
|
||||||
|
// dut->setOtherClk(otherClkState);
|
||||||
|
// otherClkState = 1-otherClkState;
|
||||||
|
// do_eval = 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (do_eval) {
|
||||||
|
dut->eval();
|
||||||
|
// evaluate the LED status in each clock cycle if the CPU is running (i.e., after reset)
|
||||||
|
if (running && program == "unknown") evalLed();
|
||||||
|
// evaluate the Fibonacci Series location in stack (starting at 2027) and print value if it has changed
|
||||||
|
if (running && program == "fibonacci") evalFibonacci();
|
||||||
|
// evaluate the 'hello world!' location in the DataMem in each clock cycle if the CPU is running (i.e., after reset)
|
||||||
|
if (running && program == "helloWorld") evalHelloWorld();
|
||||||
|
// evaluate the Prime Factors location in RegFile (x17) and print value if it has changed
|
||||||
|
if (running && program == "primeFactors") evalPrimeFactors();
|
||||||
|
mTrace->dump(T);
|
||||||
|
do_eval = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
T++;
|
||||||
|
|
||||||
|
} // tick()
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief Initialize all input signals of the hardware model to a defined value
|
||||||
|
void initSignals()
|
||||||
|
{
|
||||||
|
dut->setInitial();
|
||||||
|
} // initSignals()
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief Wait for a number of active edges of clk signal
|
||||||
|
/// @param numEdges number of rising edges
|
||||||
|
/// @param active active 1=rising 0=falling edge
|
||||||
|
void waitClocks (int numEdges=1, int activeEdge=1)
|
||||||
|
{
|
||||||
|
int clk_d;
|
||||||
|
|
||||||
|
for (int j=0; j<numEdges; ++j) {
|
||||||
|
while (1) {
|
||||||
|
clk_d = cpuClkState;
|
||||||
|
tick();
|
||||||
|
if (clk_d==1-activeEdge && cpuClkState==activeEdge) break;
|
||||||
|
}
|
||||||
|
} // for
|
||||||
|
} // waitClocks()
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief Toggle the reset signal active (low)
|
||||||
|
/// @param numEdges number of clock cyles keeping the reset active
|
||||||
|
void reset (int numEdges=1)
|
||||||
|
{
|
||||||
|
dut->setReset(0); // reset is active low
|
||||||
|
waitClocks (numEdges);
|
||||||
|
dut->setReset(1);
|
||||||
|
} // reset();
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief load the cpu memory from vmem formatted file
|
||||||
|
void loadRAM (char* vmemFile)
|
||||||
|
{
|
||||||
|
dut->loadRAM(vmemFile);
|
||||||
|
} // loadRAM()
|
||||||
|
|
||||||
|
/// @brief check the LED status and print value if it has change
|
||||||
|
void evalLed ()
|
||||||
|
{
|
||||||
|
static uint8_t oldLedStatus=0xff;
|
||||||
|
uint8_t currentLedStatus;
|
||||||
|
currentLedStatus=dut->getLed();
|
||||||
|
if (currentLedStatus!=oldLedStatus) {
|
||||||
|
cout << "T=" << T << ": LED=" << std::bitset<8>(currentLedStatus) << endl;
|
||||||
|
oldLedStatus = currentLedStatus;
|
||||||
|
}
|
||||||
|
} // evalLed()
|
||||||
|
|
||||||
|
/// @brief check Fibonacci Series location in stack (starting at 2027) and print value if it has changed
|
||||||
|
void evalFibonacci()
|
||||||
|
{
|
||||||
|
int memStartLoc = 2027;
|
||||||
|
const int memLengthInBytes = 40;
|
||||||
|
const int memLengthInWords = ceil(memLengthInBytes / 4.0);
|
||||||
|
static uint32_t oldValue[memLengthInWords];
|
||||||
|
uint32_t vlaue[memLengthInWords];
|
||||||
|
bool update = 0;
|
||||||
|
for (int i = 0; i < memLengthInWords; i++)
|
||||||
|
{
|
||||||
|
vlaue[i] = dut->getMem(memStartLoc + i);
|
||||||
|
if (oldValue[i] != vlaue[i])
|
||||||
|
update = 1;
|
||||||
|
}
|
||||||
|
if (update)
|
||||||
|
{
|
||||||
|
cout << endl
|
||||||
|
<< "T=" << T << ": \t Hex \t Dec" << endl;
|
||||||
|
for (int i = 0; i < memLengthInWords; i++)
|
||||||
|
{
|
||||||
|
dut->printMem(memStartLoc + i, "fibonacci");
|
||||||
|
oldValue[i] = vlaue[i];
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
} // evalFibonacci()
|
||||||
|
|
||||||
|
/// @brief check 'hello world' location in DataMem (starting at 1024) and print value if it has changed
|
||||||
|
void evalHelloWorld()
|
||||||
|
{
|
||||||
|
int memStartLoc = 1024;
|
||||||
|
const int memLengthInBytes = 13;
|
||||||
|
const int memLengthInWords = ceil(memLengthInBytes / 4.0);
|
||||||
|
static uint32_t oldValue[memLengthInWords];
|
||||||
|
uint32_t vlaue[memLengthInWords];
|
||||||
|
bool update = 0;
|
||||||
|
for (int i = 0; i < memLengthInWords; i++)
|
||||||
|
{
|
||||||
|
vlaue[i] = dut->getMem(memStartLoc + i);
|
||||||
|
if (oldValue[i] != vlaue[i])
|
||||||
|
update = 1;
|
||||||
|
}
|
||||||
|
if (update)
|
||||||
|
{
|
||||||
|
cout << endl
|
||||||
|
<< "T=" << T << ": \t Hex \t ASCII" << endl;
|
||||||
|
for (int i = 0; i < memLengthInWords; i++)
|
||||||
|
{
|
||||||
|
dut->printMem(memStartLoc + i, "helloWorld");
|
||||||
|
oldValue[i] = vlaue[i];
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
} // evalHelloWorld()
|
||||||
|
|
||||||
|
/// @brief check Prime Factors location in RegFile (x17) and print value if it has changed
|
||||||
|
void evalPrimeFactors()
|
||||||
|
{
|
||||||
|
// Number to be factorised
|
||||||
|
int regLoc_Number = 16;
|
||||||
|
static uint32_t oldValue_Number;
|
||||||
|
uint32_t value_Number;
|
||||||
|
value_Number = dut->getReg(regLoc_Number);
|
||||||
|
if (oldValue_Number != value_Number & value_Number > 1) dut->printReg(regLoc_Number, "primeNumber");
|
||||||
|
oldValue_Number = value_Number;
|
||||||
|
|
||||||
|
// Prime Factors
|
||||||
|
int regLoc_PrimeFactor = 17;
|
||||||
|
static uint32_t oldValue_PrimeFactor;
|
||||||
|
uint32_t value_PrimeFactor;
|
||||||
|
value_PrimeFactor = dut->getReg(regLoc_PrimeFactor);
|
||||||
|
if (oldValue_PrimeFactor != value_PrimeFactor & value_PrimeFactor > 1) dut->printReg(regLoc_PrimeFactor, "primeFactors");
|
||||||
|
oldValue_PrimeFactor = value_PrimeFactor;
|
||||||
|
|
||||||
|
} // evalPrimeFactors()
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief start the DUT
|
||||||
|
void start()
|
||||||
|
{
|
||||||
|
running = true;
|
||||||
|
dut->enable(1);
|
||||||
|
} // start()
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief close the trace file and delete the Verilator object
|
||||||
|
void stop()
|
||||||
|
{
|
||||||
|
dut->enable(0);
|
||||||
|
mTrace->close();
|
||||||
|
delete dut;
|
||||||
|
} // stop()
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief Set the program name
|
||||||
|
void setProgram(string prog)
|
||||||
|
{
|
||||||
|
if (prog.find("fibonacci") != string::npos) program = "fibonacci";
|
||||||
|
else if (prog.find("helloWorld") != string::npos) program = "helloWorld";
|
||||||
|
else if (prog.find("primeFactors") != string::npos) program = "primeFactors";
|
||||||
|
else program = "unknown";
|
||||||
|
|
||||||
|
cout << "program set to " << program << endl;
|
||||||
|
} // setProgram()
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief Get the program name
|
||||||
|
string getProgram()
|
||||||
|
{
|
||||||
|
return program;
|
||||||
|
} // getProgram()
|
||||||
|
|
||||||
|
}; // class cpu
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main (int argc, char** argv)
|
||||||
|
{
|
||||||
|
uint32_t nCycles;
|
||||||
|
char* program_path = new char[strlen(argv[2])]();
|
||||||
|
|
||||||
|
// Get number of simulation cycles
|
||||||
|
nCycles = atoi(argv[1]);
|
||||||
|
|
||||||
|
// Get the program
|
||||||
|
program_path = argv[2];
|
||||||
|
string program_path_str = program_path;
|
||||||
|
|
||||||
|
cout << "\nCreating model...\n";
|
||||||
|
cpu *m = new cpu(argc, argv);
|
||||||
|
m->loadRAM(program_path);
|
||||||
|
m->setProgram(program_path_str);
|
||||||
|
|
||||||
|
cout << "\nStarting model...\n";
|
||||||
|
|
||||||
|
cout << "\nResetting...\n";
|
||||||
|
m->reset(10);
|
||||||
|
|
||||||
|
cout << "Starting CPU...\n" << std::flush;
|
||||||
|
m->start();
|
||||||
|
|
||||||
|
cout << "Running for " << nCycles << " clock cycles...\n\n" << std::flush;
|
||||||
|
cout << "Printing evaluation for " << m->getProgram() << " program!\n" << std::flush;
|
||||||
|
m->waitClocks(nCycles);
|
||||||
|
|
||||||
|
cout << "\nDone, closing simulation.\n\n\n" << std::flush;
|
||||||
|
m->stop();
|
||||||
|
delete m;
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
185
riscv_rtl/hw/dv/verilator/src/tb_decoder_harness.cpp
Normal file
185
riscv_rtl/hw/dv/verilator/src/tb_decoder_harness.cpp
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Description : Verilator tb
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 15.Oct.2025 by Hussein Elzomor
|
||||||
|
// Last Modified : 15.Oct.2025 by Hussein Elzomor
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- --------- -------------------------------------------------
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <verilated.h>
|
||||||
|
#include <verilated_fst_c.h>
|
||||||
|
#include "Vdecoder_harness.h"
|
||||||
|
#include "Vdecoder_harness__Dpi.h"
|
||||||
|
|
||||||
|
// only required for accessing model internal memory ressources via the rootp pointer.
|
||||||
|
// Bad style, better use systemverilog harness with tasks and functions to do that.
|
||||||
|
// #include "Vdecoder_harness___024root.h"
|
||||||
|
// #include "svdpi.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define DECODER_CLK_PERIOD 40
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief Simulation environment class for the decoder model.
|
||||||
|
/// Contains a set of high level methods for controlling the model from test environment.
|
||||||
|
class decoder
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Vdecoder_harness *dut;
|
||||||
|
VerilatedFstC *mTrace;
|
||||||
|
vluint64_t T;
|
||||||
|
|
||||||
|
uint32_t decoderClkState;
|
||||||
|
bool running;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief Constructor
|
||||||
|
decoder (int argc, char** argv)
|
||||||
|
{
|
||||||
|
// setup verilator stuff
|
||||||
|
T = 0;
|
||||||
|
dut = new Vdecoder_harness();
|
||||||
|
Verilated::commandArgs(argc, argv);
|
||||||
|
Verilated::traceEverOn(true);
|
||||||
|
mTrace = new VerilatedFstC;
|
||||||
|
dut->trace(mTrace, 5);
|
||||||
|
mTrace->open("wavedump.fst");
|
||||||
|
|
||||||
|
cout << "Registered DPI-C functions:\n";
|
||||||
|
Verilated::scopesDump();
|
||||||
|
const svScope scope = svGetScopeFromName("TOP.decoder_harness");
|
||||||
|
assert(scope); // Check for nullptr if scope not found
|
||||||
|
svSetScope(scope);
|
||||||
|
|
||||||
|
running = false;
|
||||||
|
|
||||||
|
// initialize all input signals
|
||||||
|
initSignals();
|
||||||
|
|
||||||
|
} // swirl()
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief simulation tick, advances the simulation time and calls the eval() function of the model on every active clock edge
|
||||||
|
void tick ()
|
||||||
|
{
|
||||||
|
int do_eval;
|
||||||
|
|
||||||
|
if (T%DECODER_CLK_PERIOD==0) {
|
||||||
|
dut->setClk(decoderClkState);
|
||||||
|
decoderClkState = 1-decoderClkState;
|
||||||
|
do_eval = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (do_eval) {
|
||||||
|
dut->eval();
|
||||||
|
mTrace->dump(T);
|
||||||
|
do_eval = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
T++;
|
||||||
|
|
||||||
|
} // tick()
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief Initialize all input signals of the hardware model to a defined value
|
||||||
|
void initSignals()
|
||||||
|
{
|
||||||
|
dut->setInitial();
|
||||||
|
} // initSignals()
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief Wait for a number of active edges of clk signal
|
||||||
|
/// @param numEdges number of rising edges
|
||||||
|
/// @param active active 1=rising 0=falling edge
|
||||||
|
void waitClocks (int numEdges=1, int activeEdge=1)
|
||||||
|
{
|
||||||
|
int clk_d;
|
||||||
|
|
||||||
|
for (int j=0; j<numEdges; ++j) {
|
||||||
|
while (1) {
|
||||||
|
clk_d = decoderClkState;
|
||||||
|
tick();
|
||||||
|
if (clk_d==1-activeEdge && decoderClkState==activeEdge) break;
|
||||||
|
}
|
||||||
|
} // for
|
||||||
|
} // waitClocks()
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief load the decoder memory from vmem formatted file
|
||||||
|
void loadRAM(char *vmemFile)
|
||||||
|
{
|
||||||
|
dut->loadRAM(vmemFile);
|
||||||
|
} // loadRAM()
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief start the DUT
|
||||||
|
void start()
|
||||||
|
{
|
||||||
|
running = true;
|
||||||
|
dut->enable(1);
|
||||||
|
} // start()
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief close the trace file and delete the Verilator object
|
||||||
|
void stop()
|
||||||
|
{
|
||||||
|
dut->enable(0);
|
||||||
|
mTrace->close();
|
||||||
|
delete dut;
|
||||||
|
} // stop()
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
/// @brief print signal info
|
||||||
|
void printInfo()
|
||||||
|
{
|
||||||
|
dut->printInfo();
|
||||||
|
}
|
||||||
|
}; // class decoder
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main (int argc, char** argv)
|
||||||
|
{
|
||||||
|
uint32_t nCycles;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
// Get number of simulation cycles
|
||||||
|
nCycles = atoi(argv[1]);
|
||||||
|
|
||||||
|
cout << "\nCreating model...\n";
|
||||||
|
decoder *m = new decoder(argc, argv);
|
||||||
|
m->loadRAM(argv[2]);
|
||||||
|
|
||||||
|
cout << "Starting DECODER simulation...\n" << std::flush;
|
||||||
|
m->start();
|
||||||
|
|
||||||
|
cout << "Running for " << nCycles << " clock cycles...\n" << std::flush;
|
||||||
|
m->waitClocks(nCycles);
|
||||||
|
|
||||||
|
m->printInfo();
|
||||||
|
|
||||||
|
cout << "\nDone, closing simulation.\n\n\n" << std::flush;
|
||||||
|
m->stop();
|
||||||
|
delete m;
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
6533
riscv_rtl/hw/dv/wave_configs/icarus_wave.surf.ron
Normal file
6533
riscv_rtl/hw/dv/wave_configs/icarus_wave.surf.ron
Normal file
File diff suppressed because it is too large
Load Diff
6943
riscv_rtl/hw/dv/wave_configs/verilator_wave.surf.ron
Normal file
6943
riscv_rtl/hw/dv/wave_configs/verilator_wave.surf.ron
Normal file
File diff suppressed because it is too large
Load Diff
19
riscv_rtl/hw/file_lists/rtl_flist.f
Normal file
19
riscv_rtl/hw/file_lists/rtl_flist.f
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 12.Aug.2025 by Marcus Bednara
|
||||||
|
// Last Modified : 01.Nov.2025 by Hussein Elzomor
|
||||||
|
// ------
|
||||||
|
// Notes : All ${}-variables must be provided by shell or Makefile {using export}
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
${PRJ_ROOT}/hw/rtl/pc.sv
|
||||||
|
${PRJ_ROOT}/hw/rtl/reg_file.sv
|
||||||
|
${PRJ_ROOT}/hw/rtl/alu.sv
|
||||||
|
${PRJ_ROOT}/hw/rtl/main_mem.sv
|
||||||
|
${PRJ_ROOT}/hw/rtl/decoder.sv
|
||||||
|
${PRJ_ROOT}/hw/rtl/cpu.sv
|
||||||
24
riscv_rtl/hw/file_lists/tb_flist.f
Normal file
24
riscv_rtl/hw/file_lists/tb_flist.f
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 12.Aug.2025 by Marcus Bednara
|
||||||
|
// Last Modified : 01.Nov.2025 by Hussein Elzomor
|
||||||
|
// ------
|
||||||
|
// Notes : All ${}-variables must be provided by shell or Makefile {using export}
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Used with verilator
|
||||||
|
${PRJ_ROOT}/hw/dv/verilator/rtl/decoder_harness.sv
|
||||||
|
${PRJ_ROOT}/hw/dv/verilator/rtl/cpu_harness.sv
|
||||||
|
|
||||||
|
// Used with other compilers and simulators (eg. Icarus)
|
||||||
|
// ${PRJ_ROOT}/hw/dv/rtl/pc_tb.sv
|
||||||
|
// ${PRJ_ROOT}/hw/dv/rtl/reg_file_tb.sv
|
||||||
|
// ${PRJ_ROOT}/hw/dv/rtl/alu_tb.sv
|
||||||
|
// ${PRJ_ROOT}/hw/dv/rtl/main_mem_tb.sv
|
||||||
|
// ${PRJ_ROOT}/hw/dv/rtl/decoder_tb.sv
|
||||||
|
// ${PRJ_ROOT}/hw/dv/rtl/cpu_tb.sv
|
||||||
BIN
riscv_rtl/hw/rtl/.MemGen_32_11.sv.swm
Normal file
BIN
riscv_rtl/hw/rtl/.MemGen_32_11.sv.swm
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.MemGen_32_11.sv.swo
Normal file
BIN
riscv_rtl/hw/rtl/.MemGen_32_11.sv.swo
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.MemGen_32_11.sv.swp
Normal file
BIN
riscv_rtl/hw/rtl/.MemGen_32_11.sv.swp
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.cpu.sv.svz
Normal file
BIN
riscv_rtl/hw/rtl/.cpu.sv.svz
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.cpu.sv.swb
Normal file
BIN
riscv_rtl/hw/rtl/.cpu.sv.swb
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.cpu.sv.swc
Normal file
BIN
riscv_rtl/hw/rtl/.cpu.sv.swc
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.cpu.sv.swd
Normal file
BIN
riscv_rtl/hw/rtl/.cpu.sv.swd
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.cpu.sv.swe
Normal file
BIN
riscv_rtl/hw/rtl/.cpu.sv.swe
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.cpu.sv.swf
Normal file
BIN
riscv_rtl/hw/rtl/.cpu.sv.swf
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.cpu.sv.swg
Normal file
BIN
riscv_rtl/hw/rtl/.cpu.sv.swg
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.cpu.sv.swh
Normal file
BIN
riscv_rtl/hw/rtl/.cpu.sv.swh
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.cpu.sv.swi
Normal file
BIN
riscv_rtl/hw/rtl/.cpu.sv.swi
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.cpu.sv.swj
Normal file
BIN
riscv_rtl/hw/rtl/.cpu.sv.swj
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.cpu.sv.swk
Normal file
BIN
riscv_rtl/hw/rtl/.cpu.sv.swk
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.cpu.sv.swl
Normal file
BIN
riscv_rtl/hw/rtl/.cpu.sv.swl
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.cpu.sv.swm
Normal file
BIN
riscv_rtl/hw/rtl/.cpu.sv.swm
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.cpu.sv.swn
Normal file
BIN
riscv_rtl/hw/rtl/.cpu.sv.swn
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.cpu.sv.swo
Normal file
BIN
riscv_rtl/hw/rtl/.cpu.sv.swo
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.cpu.sv.swp
Normal file
BIN
riscv_rtl/hw/rtl/.cpu.sv.swp
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.decoder.sv.swo
Normal file
BIN
riscv_rtl/hw/rtl/.decoder.sv.swo
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.decoder.sv.swp
Normal file
BIN
riscv_rtl/hw/rtl/.decoder.sv.swp
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.main_mem.sv.swm
Normal file
BIN
riscv_rtl/hw/rtl/.main_mem.sv.swm
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.main_mem.sv.swn
Normal file
BIN
riscv_rtl/hw/rtl/.main_mem.sv.swn
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.main_mem.sv.swo
Normal file
BIN
riscv_rtl/hw/rtl/.main_mem.sv.swo
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.main_mem.sv.swp
Normal file
BIN
riscv_rtl/hw/rtl/.main_mem.sv.swp
Normal file
Binary file not shown.
BIN
riscv_rtl/hw/rtl/.pc.sv.swp
Normal file
BIN
riscv_rtl/hw/rtl/.pc.sv.swp
Normal file
Binary file not shown.
60
riscv_rtl/hw/rtl/MemGen_32_11.sv
Executable file
60
riscv_rtl/hw/rtl/MemGen_32_11.sv
Executable file
@ -0,0 +1,60 @@
|
|||||||
|
module MemGen_32_11 #(
|
||||||
|
parameter data_width = 32,
|
||||||
|
parameter addr_width = 11,
|
||||||
|
parameter mem_depth = 2048
|
||||||
|
)(
|
||||||
|
input chip_en,
|
||||||
|
input clock,
|
||||||
|
input [addr_width-1:0]addr,
|
||||||
|
output reg [data_width-1:0]rd_data,
|
||||||
|
input rd_en,
|
||||||
|
|
||||||
|
input wr_en,
|
||||||
|
input [data_width-1:0]wr_data
|
||||||
|
);
|
||||||
|
// Bank selection: 1 bit selects one of 2 banks
|
||||||
|
reg [1:0] mem_sel ;
|
||||||
|
wire [31:0] mem_data_out [1:0];
|
||||||
|
|
||||||
|
// Address decoder and output multiplexer
|
||||||
|
always @(*)
|
||||||
|
begin
|
||||||
|
if ( chip_en == 1'b1 )
|
||||||
|
case (addr[10])
|
||||||
|
1'b0 : begin mem_sel = 2'b01; rd_data = mem_data_out[0]; end
|
||||||
|
1'b1 : begin mem_sel = 2'b10; rd_data = mem_data_out[1]; end
|
||||||
|
endcase
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
mem_sel = 2'b00;
|
||||||
|
rd_data = 32'h00000000;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
genvar i;
|
||||||
|
// Instantiate 2 banks, each with 2 halves (low + high 16 bits)
|
||||||
|
generate
|
||||||
|
for (i = 0; i < 2; i = i + 1) begin
|
||||||
|
MemGen_16_10 U_lo (
|
||||||
|
.chip_en(mem_sel[i]),
|
||||||
|
.clock(clock),
|
||||||
|
.addr(addr[9:0]),
|
||||||
|
.rd_en(rd_en),
|
||||||
|
.rd_data(mem_data_out[i][15:0]),
|
||||||
|
.wr_en(wr_en),
|
||||||
|
.wr_data(wr_data[15:0])
|
||||||
|
);
|
||||||
|
MemGen_16_10 U_hi (
|
||||||
|
.chip_en(mem_sel[i]),
|
||||||
|
.clock(clock),
|
||||||
|
.addr(addr[9:0]),
|
||||||
|
.rd_en(rd_en),
|
||||||
|
.rd_data(mem_data_out[i][31:16]),
|
||||||
|
.wr_en(wr_en),
|
||||||
|
.wr_data(wr_data[31:16])
|
||||||
|
);
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
||||||
52
riscv_rtl/hw/rtl/alu.sv
Normal file
52
riscv_rtl/hw/rtl/alu.sv
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 12.Jun.2025 by Lund University [commit 5b1e415]
|
||||||
|
// Last Modified : 23.Oct.2025 by Bomin Kim [commit 2f8f03d]
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- --------- -------------------------------------------------
|
||||||
|
// 15.Oct.2025 Bomin Kim Refactored ALU logic from decoder into this file
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module alu (
|
||||||
|
input logic[2:0] aluOp,
|
||||||
|
input logic aluNegAr,
|
||||||
|
input logic aluBypass,
|
||||||
|
input logic[31:0] op1,
|
||||||
|
input logic[31:0] op2,
|
||||||
|
output logic[31:0] result,
|
||||||
|
output logic eqFlag
|
||||||
|
);
|
||||||
|
|
||||||
|
// Local parameters; list of aluOp
|
||||||
|
localparam logic[2:0] f3add = 3'b000;
|
||||||
|
localparam logic[2:0] f3sl = 3'b001;
|
||||||
|
localparam logic[2:0] f3slt = 3'b010;
|
||||||
|
localparam logic[2:0] f3sltU = 3'b011;
|
||||||
|
localparam logic[2:0] f3xor = 3'b100;
|
||||||
|
localparam logic[2:0] f3sr = 3'b101;
|
||||||
|
localparam logic[2:0] f3or = 3'b110;
|
||||||
|
localparam logic[2:0] f3and = 3'b111;
|
||||||
|
|
||||||
|
// ALU logic
|
||||||
|
always_comb begin : ALU
|
||||||
|
eqFlag = op1 == op2;
|
||||||
|
if (aluBypass) result = op1;
|
||||||
|
else case(aluOp)
|
||||||
|
f3add: result = aluNegAr ? op1 - op2 : op1 + op2;
|
||||||
|
f3sl: result = op1 << op2[4:0];
|
||||||
|
f3slt: result = {31'b0, $signed(op1) < $signed(op2)};
|
||||||
|
f3sltU: result = {31'b0, $unsigned(op1) < $unsigned(op2)};
|
||||||
|
f3xor: result = op1 ^ op2;
|
||||||
|
f3sr: result = aluNegAr ? $signed(op1) >>> op2[4:0] : $signed(op1) >> op2[4:0];
|
||||||
|
f3or: result = op1 | op2;
|
||||||
|
f3and: result = op1 & op2;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
135
riscv_rtl/hw/rtl/cpu.sv
Normal file
135
riscv_rtl/hw/rtl/cpu.sv
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 12.Jun.2025 by Lund University [commit 5b1e415]
|
||||||
|
// Last Modified : 23.Oct.2025 by Hussein Elzomor [commit 2f8f03d]
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- --------- -------------------------------------------------
|
||||||
|
// 15.Oct.2025 H.Elzomor Renamed file and module from soc to cpu
|
||||||
|
// 15.Oct.2025 H.Elzomor Added an initial condition for clk_12p5
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module cpu (
|
||||||
|
output logic[7:0] led,
|
||||||
|
input logic[6:0] btn,
|
||||||
|
input logic clk_25mhz,
|
||||||
|
input logic scan_mode //for defining if we are in scan or in functional mode
|
||||||
|
);
|
||||||
|
|
||||||
|
// Local Signals
|
||||||
|
// Clock & Reset
|
||||||
|
logic clk;
|
||||||
|
logic clk12p5;
|
||||||
|
logic reset;
|
||||||
|
// PC
|
||||||
|
logic[31:0] CurrentPC;
|
||||||
|
logic[31:0] JumpOrBranchPC;
|
||||||
|
logic JumpOrBranch;
|
||||||
|
logic[31:0] NextPC;
|
||||||
|
// Memory
|
||||||
|
logic[31:0] DAddr;
|
||||||
|
logic[31:0] WData;
|
||||||
|
logic[31:0] RData;
|
||||||
|
logic[31:0] Instruction;
|
||||||
|
logic WrMem;
|
||||||
|
logic[1:0] DWidth;
|
||||||
|
// Register File;
|
||||||
|
logic[4:0] Rs1;
|
||||||
|
logic[4:0] Rs2;
|
||||||
|
logic[4:0] Rd;
|
||||||
|
logic[31:0] RRs1;
|
||||||
|
logic[31:0] RRs2;
|
||||||
|
logic[31:0] WRd;
|
||||||
|
logic WrReg;
|
||||||
|
// Protection
|
||||||
|
logic Illegal;
|
||||||
|
|
||||||
|
// Logic
|
||||||
|
// Clock (12.5MHz)
|
||||||
|
//assign clk = scan_mode ? clk_25mhz : clk12p5;
|
||||||
|
assign clk = clk_25mhz;
|
||||||
|
|
||||||
|
// always_ff @(posedge clk_25mhz) begin
|
||||||
|
// if (reset)
|
||||||
|
// clk12p5 <= 1'b0;
|
||||||
|
// else if (!scan_mode)
|
||||||
|
// clk12p5 <= ~clk12p5;
|
||||||
|
// end
|
||||||
|
// Reset
|
||||||
|
assign reset = ~btn[0];
|
||||||
|
|
||||||
|
// LED
|
||||||
|
assign led[0] = Illegal;
|
||||||
|
assign led[1] = WrMem;
|
||||||
|
assign led[7:2] = NextPC[7:2];
|
||||||
|
|
||||||
|
// Module Instantiation
|
||||||
|
// Decoder
|
||||||
|
decoder theDecoder (
|
||||||
|
// PC
|
||||||
|
.CurrentPC(CurrentPC),
|
||||||
|
.JumpOrBranchPC(JumpOrBranchPC),
|
||||||
|
.JumpOrBranch(JumpOrBranch),
|
||||||
|
// Memory
|
||||||
|
.DAddr(DAddr),
|
||||||
|
.WData(WData),
|
||||||
|
.RData(RData),
|
||||||
|
.Instruction(Instruction),
|
||||||
|
.WrMem(WrMem),
|
||||||
|
.DWidth(DWidth),
|
||||||
|
// Register File
|
||||||
|
.Rs1(Rs1),
|
||||||
|
.Rs2(Rs2),
|
||||||
|
.Rd(Rd),
|
||||||
|
.RRs1(RRs1),
|
||||||
|
.RRs2(RRs2),
|
||||||
|
.WRd(WRd),
|
||||||
|
.WrReg(WrReg),
|
||||||
|
// Protection
|
||||||
|
.Illegal(Illegal)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Register File
|
||||||
|
reg_file theRegisters (
|
||||||
|
.Rs1(Rs1),
|
||||||
|
.Rs2(Rs2),
|
||||||
|
.Rd(Rd),
|
||||||
|
.RRs1(RRs1),
|
||||||
|
.RRs2(RRs2),
|
||||||
|
.WRd(WRd),
|
||||||
|
.WrReg(WrReg),
|
||||||
|
.reset(reset),
|
||||||
|
.clk(clk)
|
||||||
|
);
|
||||||
|
|
||||||
|
// PC
|
||||||
|
pc thePC (
|
||||||
|
.CurrentPC(CurrentPC),
|
||||||
|
.JumpOrBranchPC(JumpOrBranchPC),
|
||||||
|
.JumpOrBranch(JumpOrBranch),
|
||||||
|
.NextPC(NextPC),
|
||||||
|
.reset(reset),
|
||||||
|
.clk(clk)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Main Memory
|
||||||
|
main_mem #(
|
||||||
|
.MEM_INIT_FILE("") // Memory loading driven from the TB
|
||||||
|
) theMem (
|
||||||
|
.DAddr(DAddr),
|
||||||
|
.IAddr(NextPC),
|
||||||
|
.DWData(WData),
|
||||||
|
.DRData(RData),
|
||||||
|
.IRData(Instruction),
|
||||||
|
.DWE(WrMem),
|
||||||
|
.DWidth(DWidth),
|
||||||
|
.reset(reset),
|
||||||
|
.clk(clk)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
231
riscv_rtl/hw/rtl/decoder.sv
Normal file
231
riscv_rtl/hw/rtl/decoder.sv
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 12.Jun.2025 by Lund University [commit 5b1e415]
|
||||||
|
// Last Modified : 23.Oct.2025 by Hussein Elzomor [commit 2f8f03d]
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- --------- -------------------------------------------------
|
||||||
|
// 15.Oct.2025 H.Elzomor Moved PC and ALU logic to their respective files
|
||||||
|
// 15.Oct.2025 H.Elzomor Absorbed the branching logic into the decoder logic
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module decoder (
|
||||||
|
// PC
|
||||||
|
input logic[31:0] CurrentPC,
|
||||||
|
output logic[31:0] JumpOrBranchPC,
|
||||||
|
output logic JumpOrBranch,
|
||||||
|
// Memory
|
||||||
|
output logic[31:0] DAddr,
|
||||||
|
output logic[31:0] WData,
|
||||||
|
input logic[31:0] RData,
|
||||||
|
input logic[31:0] Instruction,
|
||||||
|
output logic WrMem,
|
||||||
|
output logic[1:0] DWidth,
|
||||||
|
// Register File
|
||||||
|
output logic[4:0] Rs1,
|
||||||
|
output logic[4:0] Rs2,
|
||||||
|
output logic[4:0] Rd,
|
||||||
|
input logic[31:0] RRs1,
|
||||||
|
input logic[31:0] RRs2,
|
||||||
|
output logic[31:0] WRd,
|
||||||
|
output logic WrReg,
|
||||||
|
// Protection
|
||||||
|
output logic Illegal
|
||||||
|
);
|
||||||
|
|
||||||
|
// Local Parameters
|
||||||
|
// OpCode: set a local parameter for each operation
|
||||||
|
localparam logic[6:0] opLd = 7'b0000011;
|
||||||
|
localparam logic[6:0] opAluImm = 7'b0010011;
|
||||||
|
localparam logic[6:0] opUpPC = 7'b0010111;
|
||||||
|
localparam logic[6:0] opSt = 7'b0100011;
|
||||||
|
localparam logic[6:0] opAlu = 7'b0110011;
|
||||||
|
localparam logic[6:0] opUpImm = 7'b0110111;
|
||||||
|
localparam logic[6:0] opBranch = 7'b1100011;
|
||||||
|
localparam logic[6:0] opJALR = 7'b1100111;
|
||||||
|
localparam logic[6:0] opJAL = 7'b1101111;
|
||||||
|
|
||||||
|
// Func7: set a local parameter for each function 7
|
||||||
|
localparam logic[6:0] f7neg = 7'b0100000;
|
||||||
|
|
||||||
|
// Func3: set a local parameter for each function 3
|
||||||
|
// Load/Store
|
||||||
|
localparam logic[2:0] f3byte = 3'b000;
|
||||||
|
localparam logic[2:0] f3half = 3'b001;
|
||||||
|
localparam logic[2:0] f3word = 3'b010;
|
||||||
|
localparam logic[2:0] f3byteU = 3'b100;
|
||||||
|
localparam logic[2:0] f3halfU = 3'b101;
|
||||||
|
// ALU
|
||||||
|
localparam logic[2:0] f3add = 3'b000;
|
||||||
|
localparam logic[2:0] f3sl = 3'b001;
|
||||||
|
localparam logic[2:0] f3slt = 3'b010;
|
||||||
|
localparam logic[2:0] f3sltU = 3'b011;
|
||||||
|
localparam logic[2:0] f3xor = 3'b100;
|
||||||
|
localparam logic[2:0] f3sr = 3'b101;
|
||||||
|
localparam logic[2:0] f3or = 3'b110;
|
||||||
|
localparam logic[2:0] f3and = 3'b111;
|
||||||
|
// Branch
|
||||||
|
localparam logic[2:0] f3beq = 3'b000;
|
||||||
|
localparam logic[2:0] f3bne = 3'b001;
|
||||||
|
localparam logic[2:0] f3blt = 3'b100;
|
||||||
|
localparam logic[2:0] f3bge = 3'b101;
|
||||||
|
localparam logic[2:0] f3bltU = 3'b110;
|
||||||
|
localparam logic[2:0] f3bgeU = 3'b111;
|
||||||
|
|
||||||
|
// Local Signals
|
||||||
|
// Instruction breakdown (excluding I/O)
|
||||||
|
logic[6:0] theOp;
|
||||||
|
logic[2:0] theFunct3;
|
||||||
|
logic[6:0] theFunct7;
|
||||||
|
logic[31:0] i_imm;
|
||||||
|
logic[31:0] s_imm;
|
||||||
|
logic[31:0] b_imm;
|
||||||
|
logic[31:0] u_imm;
|
||||||
|
logic[31:0] j_imm;
|
||||||
|
// ALU
|
||||||
|
logic[2:0] aluOp;
|
||||||
|
logic aluNegAr;
|
||||||
|
logic aluBypass;
|
||||||
|
logic[31:0] op1;
|
||||||
|
logic[31:0] op2;
|
||||||
|
logic[31:0] result;
|
||||||
|
logic eqFlag;
|
||||||
|
|
||||||
|
// Instruction breakdown: assign values
|
||||||
|
// OpCode and functions 3/7
|
||||||
|
assign theOp = Instruction[6:0];
|
||||||
|
assign theFunct3 = Instruction[14:12];
|
||||||
|
assign theFunct7 = Instruction[31:25];
|
||||||
|
// Registers
|
||||||
|
assign Rs1 = Instruction[19:15];
|
||||||
|
assign Rs2 = Instruction[24:20];
|
||||||
|
assign Rd = Instruction[11:7];
|
||||||
|
// Immediates
|
||||||
|
always_comb begin : Immediate_Generator
|
||||||
|
i_imm = {{21{Instruction[31]}}, Instruction[30:20]};
|
||||||
|
s_imm = {{21{Instruction[31]}}, Instruction[30:25], Instruction[11:7]};
|
||||||
|
b_imm = {{20{Instruction[31]}}, Instruction[7], Instruction[30:25], Instruction[11:8], 1'b0};
|
||||||
|
u_imm = {Instruction[31:12], 12'b0};
|
||||||
|
j_imm = {{12{Instruction[31]}}, Instruction[19:12], Instruction[20], Instruction[30:21], 1'b0};
|
||||||
|
end
|
||||||
|
|
||||||
|
// Decoder Logic
|
||||||
|
always_comb begin : Main_Decoder
|
||||||
|
// Factored port/signal values
|
||||||
|
JumpOrBranch = '0;
|
||||||
|
JumpOrBranchPC = '0;
|
||||||
|
DAddr = '0;
|
||||||
|
WData = RRs2;
|
||||||
|
WrMem = '0;
|
||||||
|
DWidth = f3word[1:0];
|
||||||
|
WrReg = '1;
|
||||||
|
Illegal = '0;
|
||||||
|
aluOp = theFunct3;
|
||||||
|
aluNegAr = '0;
|
||||||
|
aluBypass = '0;
|
||||||
|
op1 = RRs1;
|
||||||
|
op2 = RRs2;
|
||||||
|
// OpCode Cases
|
||||||
|
case(theOp)
|
||||||
|
opLd: begin
|
||||||
|
DAddr = RRs1 + i_imm;
|
||||||
|
DWidth = theFunct3[1:0];
|
||||||
|
aluBypass = '1;
|
||||||
|
op1 = RData;
|
||||||
|
case(theFunct3)
|
||||||
|
f3byte: op1[31:8] = {24{RData[7]}};
|
||||||
|
f3byteU: op1[31:8] = {24{1'b0}};
|
||||||
|
f3half: op1[31:16] = {16{RData[15]}};
|
||||||
|
f3halfU: op1[31:16] = {16{1'b0}};
|
||||||
|
f3word: ;
|
||||||
|
default: begin
|
||||||
|
Illegal = '1;
|
||||||
|
WrReg = '0;
|
||||||
|
JumpOrBranch = '1;
|
||||||
|
JumpOrBranchPC = CurrentPC;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
opAluImm: begin
|
||||||
|
op2 = i_imm;
|
||||||
|
aluOp = theFunct3;
|
||||||
|
aluNegAr = (theFunct7 == f7neg) & (theFunct3 == f3sr);
|
||||||
|
end
|
||||||
|
opUpPC: begin
|
||||||
|
op1 = u_imm;
|
||||||
|
op2 = CurrentPC;
|
||||||
|
aluOp = f3add;
|
||||||
|
end
|
||||||
|
opSt: begin
|
||||||
|
WrReg = '0;
|
||||||
|
WrMem = '1;
|
||||||
|
DAddr = RRs1 + s_imm;
|
||||||
|
DWidth = theFunct3[1:0];
|
||||||
|
end
|
||||||
|
opAlu: begin
|
||||||
|
aluOp = theFunct3;
|
||||||
|
aluNegAr = (theFunct7 == f7neg) & ((theFunct3 == f3add) | (theFunct3 == f3sr));
|
||||||
|
end
|
||||||
|
opUpImm: begin
|
||||||
|
op1 = u_imm;
|
||||||
|
aluBypass = '1;
|
||||||
|
end
|
||||||
|
opBranch: begin
|
||||||
|
WrReg = '0;
|
||||||
|
JumpOrBranchPC = CurrentPC + b_imm;
|
||||||
|
aluOp = f3slt;
|
||||||
|
case(theFunct3)
|
||||||
|
f3beq : begin JumpOrBranch = ( eqFlag)? '1 : '0; end
|
||||||
|
f3bne : begin JumpOrBranch = (~eqFlag)? '1 : '0; end
|
||||||
|
f3blt : begin JumpOrBranch = ( result[0])? '1 : '0; end
|
||||||
|
f3bge : begin JumpOrBranch = (~result[0])? '1 : '0; end
|
||||||
|
f3bltU: begin aluOp = f3sltU; JumpOrBranch = ( result[0])? '1 : '0; end
|
||||||
|
f3bgeU: begin aluOp = f3sltU; JumpOrBranch = (~result[0])? '1 : '0; end
|
||||||
|
default: begin
|
||||||
|
Illegal = '1;
|
||||||
|
JumpOrBranch = '1;
|
||||||
|
JumpOrBranchPC = CurrentPC;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
opJALR: begin
|
||||||
|
JumpOrBranch = '1;
|
||||||
|
JumpOrBranchPC = (RRs1 + i_imm) & 32'hFFFFFFFE;
|
||||||
|
op1 = CurrentPC;
|
||||||
|
op2 = 4;
|
||||||
|
aluOp = f3add;
|
||||||
|
end
|
||||||
|
opJAL: begin
|
||||||
|
JumpOrBranch = '1;
|
||||||
|
JumpOrBranchPC = CurrentPC + j_imm;
|
||||||
|
op1 = CurrentPC;
|
||||||
|
op2 = 4;
|
||||||
|
aluOp = f3add;
|
||||||
|
end
|
||||||
|
default: begin
|
||||||
|
Illegal = '1;
|
||||||
|
WrReg = '0;
|
||||||
|
JumpOrBranch = '1;
|
||||||
|
JumpOrBranchPC = CurrentPC;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
// ALU module instantiation
|
||||||
|
alu theALU (
|
||||||
|
.aluOp(aluOp),
|
||||||
|
.aluNegAr(aluNegAr),
|
||||||
|
.aluBypass(aluBypass),
|
||||||
|
.op1(op1),
|
||||||
|
.op2(op2),
|
||||||
|
.result(result),
|
||||||
|
.eqFlag(eqFlag)
|
||||||
|
);
|
||||||
|
assign WRd = result;
|
||||||
|
|
||||||
|
endmodule
|
||||||
117
riscv_rtl/hw/rtl/main_mem.sv
Normal file
117
riscv_rtl/hw/rtl/main_mem.sv
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 12.Jun.2025 by Lund University [commit 5b1e415]
|
||||||
|
// Last Modified : 23.Oct.2025 by Aliakbar Merchant [commit 2f8f03d]
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- ---------- -------------------------------------------------
|
||||||
|
// 22.Oct.2025 A.Merchant Added reset handling condition for Instr. read logic
|
||||||
|
// 22.Oct.2025 A.Merchant Added reset handling condition for data write logic
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module main_mem #(
|
||||||
|
parameter int ABits = 3 // Number of address bits
|
||||||
|
//parameter string MEM_INIT_FILE = "" // Optional memory initializations file
|
||||||
|
)(
|
||||||
|
input logic clk, // Clock
|
||||||
|
input logic reset, // Active high sync reset
|
||||||
|
input logic[31:0] DAddr, // Data Address
|
||||||
|
input logic[31:0] IAddr, // Instruction Address
|
||||||
|
input logic[31:0] DWData, // Data to write
|
||||||
|
output logic[31:0] DRData, // Data read
|
||||||
|
output logic[31:0] IRData, // Instruction read
|
||||||
|
input logic DWE, // Data write enable, 1=Write
|
||||||
|
input logic [1:0] DWidth // Access width (byte, half word, word)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Local Parameter
|
||||||
|
localparam logic[1:0] _byte = 2'b00; // byte: 8 bits
|
||||||
|
localparam logic[1:0] _half = 2'b01; // half: 16 bits
|
||||||
|
localparam logic[1:0] _word = 2'b10; // word: 32 bits
|
||||||
|
|
||||||
|
// Local Signals
|
||||||
|
logic[31:0] RAM[2**(ABits-2)-1:0]; // Memory array 8KB(8192): ignores lowest 2 bits as 32bit-word
|
||||||
|
logic[31:0] drTmp; // Temporary register to hold the data read from RAM.
|
||||||
|
|
||||||
|
// memory initilizations
|
||||||
|
// initial begin
|
||||||
|
//if (MEM_INIT_FILE != "") begin
|
||||||
|
// $readmemh(MEM_INIT_FILE, RAM);
|
||||||
|
//end
|
||||||
|
// end
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------//
|
||||||
|
//--------------------------- DATA WRITE LOGIC ---------------------------//
|
||||||
|
//---------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
always_ff @(negedge clk) begin
|
||||||
|
if (!reset) begin
|
||||||
|
if (DWE) begin
|
||||||
|
// RAM[DAddr[(ABits-1):2]] <= DWData;
|
||||||
|
case (DWidth)
|
||||||
|
_word:
|
||||||
|
RAM[DAddr[(ABits-1):2]] <= DWData;
|
||||||
|
_half:
|
||||||
|
case (DAddr[1])
|
||||||
|
1'b0: RAM[DAddr[(ABits-1):2]][31:16] <= DWData[15:0];
|
||||||
|
1'b1: RAM[DAddr[(ABits-1):2]][15: 0] <= DWData[15:0];
|
||||||
|
endcase
|
||||||
|
_byte:
|
||||||
|
case (DAddr[1:0])
|
||||||
|
2'b00: RAM[DAddr[(ABits-1):2]][31:24] <= DWData[7:0];
|
||||||
|
2'b01: RAM[DAddr[(ABits-1):2]][23:16] <= DWData[7:0];
|
||||||
|
2'b10: RAM[DAddr[(ABits-1):2]][15: 8] <= DWData[7:0];
|
||||||
|
2'b11: RAM[DAddr[(ABits-1):2]][ 7: 0] <= DWData[7:0];
|
||||||
|
endcase
|
||||||
|
default: ;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------//
|
||||||
|
//--------------------------- DATA READ LOGIC ----------------------------//
|
||||||
|
//---------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
always_ff @(negedge clk) begin
|
||||||
|
drTmp <= RAM[DAddr[(ABits-1):2]];
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
case (DWidth)
|
||||||
|
_word:
|
||||||
|
DRData = drTmp;
|
||||||
|
_half:
|
||||||
|
case (DAddr[1])
|
||||||
|
1'b0: DRData = {16'b0, drTmp[31:16]};
|
||||||
|
1'b1: DRData = {16'b0, drTmp[15: 0]};
|
||||||
|
endcase
|
||||||
|
_byte:
|
||||||
|
case (DAddr[1:0])
|
||||||
|
2'b00: DRData = {24'b0, drTmp[31:24]};
|
||||||
|
2'b01: DRData = {24'b0, drTmp[23:16]};
|
||||||
|
2'b10: DRData = {24'b0, drTmp[15: 8]};
|
||||||
|
2'b11: DRData = {24'b0, drTmp[ 7: 0]};
|
||||||
|
endcase
|
||||||
|
default: ;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------//
|
||||||
|
//----------------------- INSTRUCTION READ LOGIC -------------------------//
|
||||||
|
//---------------------------------------------------------------------------//
|
||||||
|
//
|
||||||
|
//fetch intrcution from memory into IRData
|
||||||
|
always_ff @(posedge clk) begin
|
||||||
|
if (reset)
|
||||||
|
IRData <= RAM[0];
|
||||||
|
else
|
||||||
|
IRData <= RAM[IAddr[(ABits-1):2]];
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
37
riscv_rtl/hw/rtl/pc.sv
Normal file
37
riscv_rtl/hw/rtl/pc.sv
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 12.Jun.2025 by Lund University [commit 5b1e415]
|
||||||
|
// Last Modified : 23.Oct.2025 by Bomin Kim [commit 2f8f03d]
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- --------- -------------------------------------------------
|
||||||
|
// 15.Oct.2025 Bomin Kim Moved NextPC logic from decoder into PC
|
||||||
|
// 15.Oct.2025 Bomin Kim Removed reset condition from combinational logic
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
module pc (
|
||||||
|
output logic[31:0] CurrentPC,
|
||||||
|
input logic[31:0] JumpOrBranchPC,
|
||||||
|
input logic JumpOrBranch,
|
||||||
|
output logic[31:0] NextPC,
|
||||||
|
input logic reset,
|
||||||
|
input logic clk
|
||||||
|
);
|
||||||
|
|
||||||
|
// NextPC logic; next-state function
|
||||||
|
always_comb begin : Next_PC
|
||||||
|
if (JumpOrBranch) NextPC = JumpOrBranchPC;
|
||||||
|
else NextPC = CurrentPC + 4;
|
||||||
|
end
|
||||||
|
|
||||||
|
// CurrentPC logic; state register
|
||||||
|
always_ff @(posedge clk) begin
|
||||||
|
if (reset) CurrentPC <= '0;
|
||||||
|
else CurrentPC <= NextPC;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
44
riscv_rtl/hw/rtl/reg_file.sv
Normal file
44
riscv_rtl/hw/rtl/reg_file.sv
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 12.Jun.2025 by Lund University [commit 5b1e415]
|
||||||
|
// Last Modified : 23.Oct.2025 by Bomin Kim [commit 2f8f03d]
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- --------- -------------------------------------------------
|
||||||
|
// 15.Oct.2025 Bomin Kim Added reset handling condition
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
module reg_file (
|
||||||
|
input logic[4:0] Rs1,
|
||||||
|
input logic[4:0] Rs2,
|
||||||
|
input logic[4:0] Rd,
|
||||||
|
output logic[31:0] RRs1,
|
||||||
|
output logic[31:0] RRs2,
|
||||||
|
input logic[31:0] WRd,
|
||||||
|
input logic WrReg,
|
||||||
|
input logic reset,
|
||||||
|
input logic clk
|
||||||
|
);
|
||||||
|
|
||||||
|
// Define the registers array
|
||||||
|
logic[31:0] registers[31:1];
|
||||||
|
|
||||||
|
// Register file reading
|
||||||
|
assign RRs1 = Rs1 == 0 ? '0 : registers[Rs1];
|
||||||
|
assign RRs2 = Rs2 == 0 ? '0 : registers[Rs2];
|
||||||
|
|
||||||
|
// Register file writing
|
||||||
|
always_ff @(posedge clk) begin
|
||||||
|
if (reset) begin
|
||||||
|
for (int i=1; i<32; i++)
|
||||||
|
registers[i] <= '0;
|
||||||
|
end else begin
|
||||||
|
if (WrReg & Rd != 0) registers[Rd] <= WRd;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
18
riscv_rtl/rtl_flist.f
Normal file
18
riscv_rtl/rtl_flist.f
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 12.Aug.2025 by Marcus Bednara
|
||||||
|
// Last Modified : 01.Nov.2025 by Hussein Elzomor
|
||||||
|
// ------
|
||||||
|
// Notes : All ${}-variables must be provided by shell or Makefile {using export}
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
hw/rtl/pc.sv
|
||||||
|
hw/rtl/reg_file.sv
|
||||||
|
hw/rtl/alu.sv
|
||||||
|
hw/rtl/MemGen_32_11.sv
|
||||||
|
hw/rtl/main_mem.sv
|
||||||
|
hw/rtl/decoder.sv
|
||||||
|
hw/rtl/cpu.sv
|
||||||
17
riscv_rtl/run.do
Normal file
17
riscv_rtl/run.do
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
if [file exists "work"] {vdel -all}
|
||||||
|
vlib work
|
||||||
|
|
||||||
|
# Comment out either the SystemVerilog or VHDL DUT.
|
||||||
|
# There can be only one!
|
||||||
|
|
||||||
|
# VHDL DUT
|
||||||
|
#vcom -f rtl_flist.f
|
||||||
|
|
||||||
|
vlog -sv dummz_memgen_16.sv
|
||||||
|
|
||||||
|
# SystemVerilog DUT
|
||||||
|
vlog -sv -lint -pedanticerrors -f rtl_flist.f
|
||||||
|
|
||||||
|
vopt work.cpu -o cpu_opt +acc -pedanticerrors
|
||||||
|
|
||||||
|
quit
|
||||||
37
riscv_rtl/sw/risc-v/decoder/decoder.hex
Normal file
37
riscv_rtl/sw/risc-v/decoder/decoder.hex
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
001080B3
|
||||||
|
40210133
|
||||||
|
0031C1B3
|
||||||
|
00426233
|
||||||
|
0052F2B3
|
||||||
|
00631333
|
||||||
|
0073D3B3
|
||||||
|
40845433
|
||||||
|
0094A4B3
|
||||||
|
00A53533
|
||||||
|
00B58593
|
||||||
|
00C64613
|
||||||
|
00D6E693
|
||||||
|
00E77713
|
||||||
|
00F79793
|
||||||
|
01085813
|
||||||
|
4118D893
|
||||||
|
01292913
|
||||||
|
0139B993
|
||||||
|
014A0A03
|
||||||
|
015A9A83
|
||||||
|
016B2B03
|
||||||
|
017BCB83
|
||||||
|
018C5C03
|
||||||
|
019C8CA3
|
||||||
|
01AD1D23
|
||||||
|
01BDADA3
|
||||||
|
01CE0E63
|
||||||
|
01CE1E63
|
||||||
|
01EF4F63
|
||||||
|
01EF5F63
|
||||||
|
00216163
|
||||||
|
00217163
|
||||||
|
0040026F
|
||||||
|
00420267
|
||||||
|
000052B7
|
||||||
|
00006317
|
||||||
65
riscv_rtl/sw/risc-v/decoder/decoder.s
Normal file
65
riscv_rtl/sw/risc-v/decoder/decoder.s
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Description : Assembly instructions for decoder test
|
||||||
|
// Project Version : v1.0
|
||||||
|
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 15.Oct.2025 by Hussein Elzomor
|
||||||
|
// Last Modified : 15.Oct.2025 by Hussein Elzomor
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- --------- -------------------------------------------------
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Iteration over all implemented instructions to test decoder
|
||||||
|
|
||||||
|
# R-instruction # Hex # bin f7 rs2 rs1 f3 rd opcode
|
||||||
|
add x1 , x1 , x1 # 0x001080B3 # 0b 0000000 00001 00001 000 00001 0110011
|
||||||
|
sub x2 , x2 , x2 # 0x40210133 # 0b 0100000 00010 00010 000 00010 0110011
|
||||||
|
xor x3 , x3 , x3 # 0x0031C1B3 # 0b 0000000 00011 00011 100 00011 0110011
|
||||||
|
or x4 , x4 , x4 # 0x00426233 # 0b 0000000 00100 00100 110 00100 0110011
|
||||||
|
and x5 , x5 , x5 # 0x0052F2B3 # 0b 0000000 00101 00101 111 00101 0110011
|
||||||
|
sll x6 , x6 , x6 # 0x00631333 # 0b 0000000 00110 00110 001 00110 0110011
|
||||||
|
srl x7 , x7 , x7 # 0x0073D3B3 # 0b 0000000 00111 00111 101 00111 0110011
|
||||||
|
sra x8 , x8 , x8 # 0x40845433 # 0b 0100000 01000 01000 101 01000 0110011
|
||||||
|
slt x9 , x9 , x9 # 0x0094A4B3 # 0b 0000000 01001 01001 010 01001 0110011
|
||||||
|
sltu x10, x10, x10 # 0x00A53533 # 0b 0000000 01010 01010 011 01010 0110011
|
||||||
|
|
||||||
|
# I-instruction # Hex # bin imm rs1 f3 rd opcode
|
||||||
|
addi x11, x11, 11 # 0x00B58593 # 0b 000000001011 01011 000 01011 0010011
|
||||||
|
xori x12, x12, 12 # 0x00C64613 # 0b 000000001100 01100 100 01100 0010011
|
||||||
|
ori x13, x13, 13 # 0x00D6E693 # 0b 000000001101 01101 110 01101 0010011
|
||||||
|
andi x14, x14, 14 # 0x00E77713 # 0b 000000001110 01110 111 01110 0010011
|
||||||
|
slli x15, x15, 15 # 0x00F79793 # 0b 000000001111 01111 001 01111 0010011
|
||||||
|
srli x16, x16, 16 # 0x01085813 # 0b 000000010000 10000 101 10000 0010011
|
||||||
|
srai x17, x17, 17 # 0x4118D893 # 0b 010000010001 10001 101 10001 0010011
|
||||||
|
slti x18, x18, 18 # 0x01292913 # 0b 000000010010 10010 010 10010 0010011
|
||||||
|
sltiu x19, x19, 19 # 0x0139B993 # 0b 000000010011 10011 011 10011 0010011
|
||||||
|
lb x20, 20(x20) # 0x014A0A03 # 0b 000000010100 10100 000 10100 0000011
|
||||||
|
lh x21, 21(x21) # 0x015A9A83 # 0b 000000010101 10101 001 10101 0000011
|
||||||
|
lw x22, 22(x22) # 0x016B2B03 # 0b 000000010110 10110 010 10110 0000011
|
||||||
|
lbu x23, 23(x23) # 0x017BCB83 # 0b 000000010111 10111 100 10111 0000011
|
||||||
|
lhu x24, 24(x24) # 0x018C5C03 # 0b 000000011000 11000 101 11000 0000011
|
||||||
|
|
||||||
|
# S-instruction # Hex # bin imm rs2 rs1 f3 imm opcode
|
||||||
|
sb x25, 25(x25) # 0x019C8CA3 # 0b 0000000 11001 11001 000 11001 0100011
|
||||||
|
sh x26, 26(x26) # 0x01AD1D23 # 0b 0000000 11010 11010 001 11010 0100011
|
||||||
|
sw x27, 27(x27) # 0x01BDADA3 # 0b 0000000 11011 11011 010 11011 0100011
|
||||||
|
|
||||||
|
# B-instruction # Hex # bin imm rs2 rs1 f3 imm opcode
|
||||||
|
beq x28, x28, 28 # 0x01CE0E63 # 0b 0000000 11100 11100 000 11100 1100011
|
||||||
|
bne x28, x28, 28 # 0x01CE1E63 # 0b 0000000 11100 11100 001 11100 1100011
|
||||||
|
blt x30, x30, 30 # 0x01EF4F63 # 0b 0000000 11110 11110 100 11110 1100011
|
||||||
|
bge x30, x30, 30 # 0x01EF5F63 # 0b 0000000 11110 11110 101 11110 1100011
|
||||||
|
bltu x2 , x2 , 2 # 0x00216163 # 0b 0000000 00010 00010 110 00010 1100011
|
||||||
|
bgeu x2 , x2 , 2 # 0x00217163 # 0b 0000000 00010 00010 111 00010 1100011
|
||||||
|
|
||||||
|
# J-instruction # Hex # bin f7 rd opcode
|
||||||
|
jal x4 , 4 # 0x0040026F # 0b 00000000010000000000 00100 1101111
|
||||||
|
jalr x4 , x4, 4 # 0x00420267 # 0b 00000000010000100000 00100 1100111
|
||||||
|
|
||||||
|
# U-instruction # Hex # bin f7 rd opcode
|
||||||
|
lui x5 , 5 # 0x000052B7 # 0b 00000000000000000101 00101 0110111
|
||||||
|
auipc x6 , 6 # 0x00006317 # 0b 00000000000000000110 00110 0010111
|
||||||
29
riscv_rtl/sw/risc-v/fibonacci_series/fibonacci.c
Normal file
29
riscv_rtl/sw/risc-v/fibonacci_series/fibonacci.c
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// *********************************************************************************************
|
||||||
|
// Description : C Program to calculate the Fibonacci numbers until a given number of terms
|
||||||
|
// File : v1.0
|
||||||
|
// Project Version : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||||
|
// Project : RISCV_IN3DAYS
|
||||||
|
// -----
|
||||||
|
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||||
|
// Created : 13.Oct.2025, 11:00:00 by Fuad Mammadzada (fuad.mammadzada@fau.de)
|
||||||
|
// -----
|
||||||
|
// HISTORY : Date By Comments
|
||||||
|
// ----------- --------- -------------------------------------------------
|
||||||
|
// *********************************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
asm(".global _start, halt; _start: lui sp 2; addi sp sp -4; jal x0 main");
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int n = 10; // count of Fibonacci numbers to be evaluated
|
||||||
|
|
||||||
|
int fib_number[20];
|
||||||
|
fib_number[0] = 0;
|
||||||
|
fib_number[1] = 1;
|
||||||
|
|
||||||
|
for (int i = 2; i < n; i++) {
|
||||||
|
fib_number[i] = fib_number[i-1] + fib_number[i-2];
|
||||||
|
}
|
||||||
|
|
||||||
|
asm("j halt");
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user