mirror of
https://github.com/openhwgroup/cvw.git
synced 2025-04-23 13:27:16 -04:00
Merge branch 'main' of https://github.com/openhwgroup/cvw into main
This commit is contained in:
commit
416b322ad6
64 changed files with 6824 additions and 2091 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -30,3 +30,6 @@
|
|||
[submodule "addins/vivado-boards"]
|
||||
path = addins/vivado-boards
|
||||
url = https://github.com/Digilent/vivado-boards/
|
||||
[submodule "addins/vivado-risc-v"]
|
||||
path = addins/vivado-risc-v
|
||||
url = https://github.com/eugene-tarassov/vivado-risc-v.git
|
||||
|
|
1
addins/vivado-risc-v
Submodule
1
addins/vivado-risc-v
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit c76a8613a177b3a04face2cb8e15dd07a8d2fc40
|
|
@ -114,12 +114,9 @@ localparam logic [63:0] UART_RANGE = 64'h00000007;
|
|||
localparam PLIC_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] PLIC_BASE = 64'h0C000000;
|
||||
localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
localparam SDC2_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000007F;
|
||||
|
||||
// Bus Interface width
|
||||
localparam AHBW = 32'd64;
|
||||
|
@ -162,4 +159,4 @@ localparam ZBS_SUPPORTED = 0;
|
|||
// Memory synthesis configuration
|
||||
localparam USE_SRAM = 0;
|
||||
|
||||
`include "test-shared.vh"
|
||||
`include "config-shared.vh"
|
||||
|
|
|
@ -112,7 +112,7 @@ localparam logic [63:0] UNCORE_RAM_RANGE = 64'h00000FFF;
|
|||
|
||||
localparam EXT_MEM_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] EXT_MEM_BASE = 64'h80000000;
|
||||
localparam logic [63:0] EXT_MEM_RANGE = 64'h07FFFFFF;
|
||||
localparam logic [63:0] EXT_MEM_RANGE = 64'h0FFFFFFF;
|
||||
|
||||
localparam CLINT_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] CLINT_BASE = 64'h02000000;
|
||||
|
@ -130,14 +130,9 @@ localparam PLIC_SUPPORTED = 1'b1;
|
|||
localparam logic [63:0] PLIC_BASE = 64'h0C000000;
|
||||
localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
||||
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
|
||||
// Temporary Boot Process Stuff
|
||||
localparam SDC2_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
localparam SDC_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000007F;
|
||||
|
||||
// Test modes
|
||||
|
||||
|
@ -177,4 +172,4 @@ localparam ZBS_SUPPORTED = 1;
|
|||
// Memory synthesis configuration
|
||||
localparam USE_SRAM = 0;
|
||||
|
||||
`include "test-shared.vh"
|
||||
`include "config-shared.vh"
|
||||
|
|
|
@ -115,12 +115,9 @@ localparam logic [63:0] UART_RANGE = 64'h00000007;
|
|||
localparam PLIC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] PLIC_BASE = 64'h0C000000;
|
||||
localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
localparam SDC2_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000007F;
|
||||
|
||||
// Bus Interface width
|
||||
localparam AHBW = 32'd32;
|
||||
|
@ -163,5 +160,5 @@ localparam ZBS_SUPPORTED = 0;
|
|||
// Memory synthesis configuration
|
||||
localparam USE_SRAM = 0;
|
||||
|
||||
`include "test-shared.vh"
|
||||
`include "config-shared.vh"
|
||||
|
||||
|
|
|
@ -116,12 +116,9 @@ localparam logic [63:0] UART_RANGE = 64'h00000007;
|
|||
localparam PLIC_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] PLIC_BASE = 64'h0C000000;
|
||||
localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
localparam SDC2_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000007F;
|
||||
|
||||
// Bus Interface width
|
||||
localparam AHBW = 32'd32;
|
||||
|
@ -164,4 +161,4 @@ localparam ZBS_SUPPORTED = 1;
|
|||
// Memory synthesis configuration
|
||||
localparam USE_SRAM = 0;
|
||||
|
||||
`include "test-shared.vh"
|
||||
`include "config-shared.vh"
|
||||
|
|
|
@ -115,12 +115,9 @@ localparam logic [63:0] UART_RANGE = 64'h00000007;
|
|||
localparam PLIC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] PLIC_BASE = 64'h0C000000;
|
||||
localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
localparam SDC2_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000007F;
|
||||
|
||||
// Bus Interface width
|
||||
localparam AHBW = 32'd32;
|
||||
|
@ -163,4 +160,4 @@ localparam ZBS_SUPPORTED = 0;
|
|||
// Memory synthesis configuration
|
||||
localparam USE_SRAM = 0;
|
||||
|
||||
`include "test-shared.vh"
|
||||
`include "config-shared.vh"
|
||||
|
|
|
@ -114,12 +114,9 @@ localparam logic [63:0] UART_RANGE = 64'h00000007;
|
|||
localparam PLIC_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] PLIC_BASE = 64'h0C000000;
|
||||
localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
localparam SDC2_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000007F;
|
||||
|
||||
// Bus Interface width
|
||||
localparam AHBW = 32'd32;
|
||||
|
@ -162,4 +159,4 @@ localparam ZBS_SUPPORTED = 0;
|
|||
// Memory synthesis configuration
|
||||
localparam USE_SRAM = 0;
|
||||
|
||||
`include "test-shared.vh"
|
||||
`include "config-shared.vh"
|
||||
|
|
|
@ -120,12 +120,9 @@ localparam logic [63:0] UART_RANGE = 64'h00000007;
|
|||
localparam PLIC_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] PLIC_BASE = 64'h0C000000;
|
||||
localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
localparam SDC2_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000007F;
|
||||
|
||||
// Test modes
|
||||
|
||||
|
@ -165,4 +162,4 @@ localparam ZBS_SUPPORTED = 0;
|
|||
// Memory synthesis configuration
|
||||
localparam USE_SRAM = 0;
|
||||
|
||||
`include "test-shared.vh"
|
||||
`include "config-shared.vh"
|
||||
|
|
|
@ -123,12 +123,9 @@ localparam logic [63:0] UART_RANGE = 64'h00000007;
|
|||
localparam PLIC_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] PLIC_BASE = 64'h0C000000;
|
||||
localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
localparam SDC2_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000007F;
|
||||
|
||||
// Test modes
|
||||
|
||||
|
@ -168,4 +165,4 @@ localparam ZBS_SUPPORTED = 1;
|
|||
// Memory synthesis configuration
|
||||
localparam USE_SRAM = 0;
|
||||
|
||||
`include "test-shared.vh"
|
||||
`include "config-shared.vh"
|
||||
|
|
|
@ -121,11 +121,8 @@ localparam PLIC_SUPPORTED = 1'b0;
|
|||
localparam logic [63:0] PLIC_BASE = 64'h0C000000;
|
||||
localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00012100;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000001F;
|
||||
localparam SDC2_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC2_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC2_RANGE = 64'h0000007F;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000007F;
|
||||
|
||||
// Test modes
|
||||
|
||||
|
@ -165,4 +162,4 @@ localparam ZBS_SUPPORTED = 0;
|
|||
// Memory synthesis configuration
|
||||
localparam USE_SRAM = 0;
|
||||
|
||||
`include "test-shared.vh"
|
||||
`include "config-shared.vh"
|
||||
|
|
|
@ -72,9 +72,6 @@ parameter cvw_t P = '{
|
|||
SDC_SUPPORTED : SDC_SUPPORTED,
|
||||
SDC_BASE : SDC_BASE,
|
||||
SDC_RANGE : SDC_RANGE,
|
||||
SDC2_SUPPORTED : SDC2_SUPPORTED,
|
||||
SDC2_BASE : SDC2_BASE,
|
||||
SDC2_RANGE : SDC2_RANGE,
|
||||
GPIO_LOOPBACK_TEST : GPIO_LOOPBACK_TEST,
|
||||
UART_PRESCALE : UART_PRESCALE ,
|
||||
PLIC_NUM_SRC : PLIC_NUM_SRC,
|
||||
|
|
|
@ -20,7 +20,7 @@ set_property IOSTANDARD LVCMOS33 [get_ports {GPI[1]}]
|
|||
set_property IOSTANDARD LVCMOS33 [get_ports {GPI[0]}]
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -min -add_delay 0.000 [get_ports {GPI[*]}]
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -max -add_delay 0.000 [get_ports {GPI[*]}]
|
||||
set_max_delay -from [get_ports {GPI[*]}] 10.000
|
||||
set_max_delay -from [get_ports {GPI[*]}] 20.000
|
||||
|
||||
##### GPO ####
|
||||
set_property PACKAGE_PIN G6 [get_ports {GPO[0]}]
|
||||
|
@ -33,17 +33,17 @@ set_property IOSTANDARD LVCMOS33 [get_ports {GPO[3]}]
|
|||
set_property IOSTANDARD LVCMOS33 [get_ports {GPO[2]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {GPO[1]}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {GPO[0]}]
|
||||
set_max_delay -to [get_ports {GPO[*]}] 10.000
|
||||
set_output_delay -clock [get_clocks clk_out3_xlnx_mmcm] -min -add_delay -5.000 [get_ports {GPO[*]}]
|
||||
set_output_delay -clock [get_clocks clk_out3_xlnx_mmcm] -max -add_delay -5.000 [get_ports {GPO[*]}]
|
||||
set_max_delay -to [get_ports {GPO[*]}] 20.000
|
||||
set_output_delay -clock [get_clocks clk_out3_xlnx_mmcm] -min -add_delay 0.000 [get_ports {GPO[*]}]
|
||||
set_output_delay -clock [get_clocks clk_out3_xlnx_mmcm] -max -add_delay 0.000 [get_ports {GPO[*]}]
|
||||
|
||||
|
||||
##### UART #####
|
||||
# *** IOSTANDARD is probably wrong
|
||||
set_property PACKAGE_PIN A9 [get_ports UARTSin]
|
||||
set_property PACKAGE_PIN D10 [get_ports UARTSout]
|
||||
set_max_delay -from [get_ports UARTSin] 14.000
|
||||
set_max_delay -to [get_ports UARTSout] 14.000
|
||||
set_max_delay -from [get_ports UARTSin] 20.000
|
||||
set_max_delay -to [get_ports UARTSout] 20.000
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports UARTSin]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports UARTSout]
|
||||
set_property DRIVE 4 [get_ports UARTSout]
|
||||
|
@ -57,7 +57,7 @@ set_output_delay -clock [get_clocks clk_out3_xlnx_mmcm] -max -add_delay 0.000 [g
|
|||
#************** reset is inverted
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -min -add_delay 2.000 [get_ports resetn]
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -max -add_delay 2.000 [get_ports resetn]
|
||||
set_max_delay -from [get_ports resetn] 15.000
|
||||
set_max_delay -from [get_ports resetn] 20.000
|
||||
set_false_path -from [get_ports resetn]
|
||||
set_property PACKAGE_PIN C2 [get_ports {resetn}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {resetn}]
|
||||
|
@ -65,7 +65,7 @@ set_property IOSTANDARD LVCMOS33 [get_ports {resetn}]
|
|||
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -min -add_delay 2.000 [get_ports south_reset]
|
||||
set_input_delay -clock [get_clocks clk_out3_xlnx_mmcm] -max -add_delay 2.000 [get_ports south_reset]
|
||||
set_max_delay -from [get_ports south_reset] 15.000
|
||||
set_max_delay -from [get_ports south_reset] 20.000
|
||||
set_false_path -from [get_ports south_reset]
|
||||
set_property PACKAGE_PIN D9 [get_ports {south_reset}]
|
||||
set_property IOSTANDARD LVCMOS33 [get_ports {south_reset}]
|
||||
|
|
|
@ -24,7 +24,7 @@ all: FPGA_Arty
|
|||
FPGA_Arty: PreProcessFiles IP_Arty
|
||||
vivado -mode tcl -source wally.tcl 2>&1 | tee wally.log
|
||||
|
||||
FPGA_VCU: PreProcessFiles IP_VCU SDC
|
||||
FPGA_VCU: PreProcessFiles IP_VCU
|
||||
vivado -mode tcl -source wally.tcl 2>&1 | tee wally.log
|
||||
|
||||
IP_VCU: $(dst)/xlnx_proc_sys_reset.log \
|
||||
|
|
|
@ -41,9 +41,14 @@ if {$board=="ArtyA7"} {
|
|||
|
||||
# read in all other rtl
|
||||
read_verilog -sv [glob -type f ../src/CopiedFiles_do_not_add_to_repo/*/*.sv ../src/CopiedFiles_do_not_add_to_repo/*/*/*.sv]
|
||||
read_verilog [glob -type f ../../pipelined/src/uncore/newsdc/*.v]
|
||||
# *** Once the sdc is updated to use ahb changes these to system verilog.
|
||||
read_verilog [glob -type f ../src/axi_sdc_controller.v]
|
||||
read_verilog [glob -type f ../../addins/vivado-risc-v/sdc/sd_cmd_master.v]
|
||||
read_verilog [glob -type f ../../addins/vivado-risc-v/sdc/sd_cmd_serial_host.v]
|
||||
read_verilog [glob -type f ../../addins/vivado-risc-v/sdc/sd_data_master.v]
|
||||
read_verilog [glob -type f ../../addins/vivado-risc-v/sdc/sd_data_serial_host.v]
|
||||
|
||||
set_property include_dirs {../../config/fpga ../../config/shared} [current_fileset]
|
||||
set_property include_dirs {../../config/fpga ../../config/shared ../../addins/vivado-risc-v/sdc} [current_fileset]
|
||||
|
||||
if {$board=="ArtyA7"} {
|
||||
add_files -fileset constrs_1 -norecurse ../constraints/constraints-$board.xdc
|
||||
|
|
|
@ -15,7 +15,7 @@ set_property -dict [list CONFIG.PRIM_IN_FREQ {100.000} \
|
|||
CONFIG.CLKOUT4_USED {false} \
|
||||
CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {166.66667} \
|
||||
CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {200} \
|
||||
CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {17} \
|
||||
CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {20} \
|
||||
CONFIG.CLKIN1_JITTER_PS {10.0} \
|
||||
] [get_ips $ipName]
|
||||
|
||||
|
|
81
fpga/probe
Executable file
81
fpga/probe
Executable file
|
@ -0,0 +1,81 @@
|
|||
#!/usr/bin/python3
|
||||
###########################################
|
||||
## probe.sh
|
||||
##
|
||||
## Written: Jacob Pease jacobpease@protonmail.com
|
||||
## Created: 16 August 2023
|
||||
## Modified: 16 August 2023
|
||||
##
|
||||
## A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
##
|
||||
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
##
|
||||
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
##
|
||||
## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
## except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
## may obtain a copy of the License at
|
||||
##
|
||||
## https:##solderpad.org#licenses#SHL-2.1#
|
||||
##
|
||||
## Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
## either express or implied. See the License for the specific language governing permissions
|
||||
## and limitations under the License.
|
||||
################################################################################################
|
||||
|
||||
import sys
|
||||
|
||||
def usage():
|
||||
print("Usage: ./probes name width probenum")
|
||||
exit(1)
|
||||
|
||||
def convertLine(x):
|
||||
temp = x.split()
|
||||
temp[1] = int(temp[1])
|
||||
return tuple(temp)
|
||||
|
||||
def probeBits( probe ):
|
||||
str = ''
|
||||
|
||||
if (probe[1] > 1):
|
||||
for i in range(probe[1]):
|
||||
if i != (probe[1]-1):
|
||||
str = str + f"{{{probe[0]}[{i}]}} "
|
||||
else:
|
||||
str = str + f"{{{probe[0]}[{i}]}} "
|
||||
|
||||
else:
|
||||
str = f'{{{probe[0]}}}'
|
||||
|
||||
return str
|
||||
|
||||
def printProbe( probe, i ):
|
||||
bits = probeBits(probe)
|
||||
|
||||
print(bits)
|
||||
|
||||
return (
|
||||
f'create_debug_port u_ila_0 probe\n'
|
||||
f'set_property port_width {probe[1]} [get_debug_ports u_ila_0/probe{i}]\n'
|
||||
f'set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe{i}]\n'
|
||||
f'connect_debug_port u_ila_0/probe{i} [get_nets [list {bits}]]\n\n'
|
||||
)
|
||||
|
||||
def main(args):
|
||||
if (len(args) != 3):
|
||||
usage()
|
||||
|
||||
name = args[0]
|
||||
width = int(args[1])
|
||||
probeNum = int(args[2])
|
||||
|
||||
|
||||
probe = (name, width)
|
||||
|
||||
print(printProbe(probe, probeNum))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv[1:])
|
||||
|
||||
|
|
@ -421,8 +421,8 @@ module fpgaTop
|
|||
wire [3:0] sd_dat_reg_o;
|
||||
wire sd_dat_reg_t;
|
||||
|
||||
assign GPIOPinsIn = {28'b0, GPI};
|
||||
assign GPO = GPIOPinsOut[4:0];
|
||||
assign GPIOIN = {28'b0, GPI};
|
||||
assign GPO = GPIOOUT[4:0];
|
||||
assign ahblite_resetn = peripheral_aresetn;
|
||||
assign cpu_reset = bus_struct_reset;
|
||||
assign calib = c0_init_calib_complete;
|
||||
|
|
124
linux/Makefile
Normal file
124
linux/Makefile
Normal file
|
@ -0,0 +1,124 @@
|
|||
RISCV := /opt/riscv
|
||||
BUILDROOT := ${RISCV}/buildroot
|
||||
IMAGES := ${BUILDROOT}/output/images
|
||||
WALLY := $(shell dirname $(shell pwd))
|
||||
WALLYLINUX := $(shell pwd)
|
||||
DIS := ${IMAGES}/disassembly
|
||||
BRPACKAGES := $(WALLYLINUX)/buildroot-packages
|
||||
|
||||
# Buildroot Config Stuff
|
||||
WALLYBOARDSRC := $(WALLYLINUX)/buildroot-config-src/wally
|
||||
WALLYBOARD := $(BUILDROOT)/board/wally
|
||||
|
||||
# Buildroot Package Stuff
|
||||
PACKAGE_SOURCE := ${WALLYLINUX}/buildroot-packages/package-source
|
||||
FPGA_AXI_SDC := ${WALLYLINUX}/buildroot-packages/fpga-axi-sdc
|
||||
DRIVER := ${PACKAGE_SOURCE}/fpga-axi-sdc.c
|
||||
PATCHFILE := $(BRPACKAGES)/package.patch
|
||||
|
||||
# Device tree files
|
||||
DTS ?= $(shell find -type f -regex ".*\.dts" | sort)
|
||||
DTB := $(DTS:%.dts=%.dtb)
|
||||
DTB := $(foreach name, $(DTB), $(IMAGES)/$(shell basename $(name)))
|
||||
|
||||
# Disassembly stuff
|
||||
BINARIES := fw_jump.elf vmlinux busybox
|
||||
OBJDUMPS := $(foreach name, $(BINARIES), $(basename $(name) .elf))
|
||||
OBJDUMPS := $(foreach name, $(OBJDUMPS), $(DIS)/$(name).objdump)
|
||||
|
||||
.PHONY: all generate disassemble install clean cleanDTB cleanDriver test
|
||||
|
||||
# Generate all device trees -------------------------------------------
|
||||
# TODO: Add configuration for only generating device tree for specified
|
||||
# supported FPGA.
|
||||
|
||||
all:
|
||||
$(MAKE) install
|
||||
make -C $(BUILDROOT) --jobs
|
||||
$(MAKE) generate
|
||||
# TODO: Need to find a way to set the PATH for child processes.
|
||||
# source ../setup.sh; $(MAKE) disassemble
|
||||
|
||||
# Temp rule for debugging
|
||||
test:
|
||||
@echo $(OBJDUMPS)
|
||||
|
||||
generate: $(DTB) $(IMAGES)
|
||||
|
||||
$(IMAGES)/%.dtb: ./devicetree/%.dts
|
||||
dtc -I dts -O dtb $< > $@
|
||||
|
||||
$(IMAGES):
|
||||
@ echo "No output/images directory in buildroot."
|
||||
@ echo "Run make --jobs in buildroot directory before generating device tree binaries."; exit 1
|
||||
|
||||
$(RISCV):
|
||||
@ echo "ERROR: No $(RISCV) directory. Make sure you have installed the Wally Toolchain."
|
||||
@ echo "this can be done with <WALLY>/bin/wally-tool-chain-install.sh"
|
||||
|
||||
# Disassembly rules ---------------------------------------------------
|
||||
|
||||
disassemble:
|
||||
mkdir -p $(DIS)
|
||||
make -j $(OBJDUMPS)
|
||||
|
||||
$(DIS)/%.objdump: $(IMAGES)/%.elf
|
||||
riscv64-unknown-elf-objdump -DS $< >> $@
|
||||
|
||||
$(DIS)/%.objdump: $(IMAGES)/%
|
||||
riscv64-unknown-elf-objdump -S $< >> $@
|
||||
|
||||
$(IMAGES)/vmlinux: $(BUILDROOT)/output/build/linux-5.10.7/vmlinux
|
||||
cp $< $@
|
||||
|
||||
$(IMAGES)/busybox: $(BUILDROOT)/output/build/busybox-1.33.0/busybox
|
||||
cp $< $@
|
||||
|
||||
# Generating new Buildroot directories --------------------------------
|
||||
|
||||
# This directive should be run as: make install BUILDROOT=path/to/buildroot
|
||||
install: $(BUILDROOT)/package/fpga-axi-sdc $(WALLYBOARD) $(DRIVER)
|
||||
cp $(WALLYBOARD)/main.config $(BUILDROOT)/.config
|
||||
|
||||
# CONFIG DEPENDENCIES 2021.05 -----------------------------------------
|
||||
# $(WALLYBOARD)/main.config: $(WALLYBOARD) $(BRPACKAGES)/wally.config
|
||||
# cp $(BRPACKAGES)/wally.config $@
|
||||
|
||||
# $(WALLYBOARD)/linux.config: $(BRPACKAGES)/linux.config $(WALLYBOARD)
|
||||
# cp $(BRPACKAGES)/linux.config $@
|
||||
|
||||
$(WALLYBOARD): $(BUILDROOT)
|
||||
cp -r $(WALLYBOARDSRC) $(BUILDROOT)/board
|
||||
cp $(BRPACKAGES)/wally.config $(WALLYBOARD)/main.config
|
||||
cp $(BRPACKAGES)/linux.config $(WALLYBOARD)/linux.config
|
||||
|
||||
# Buildroot Package ---------------------------------------------------
|
||||
$(BUILDROOT)/package/fpga-axi-sdc: $(BUILDROOT) $(PATCHFILE) $(BRPACKAGES)/fpga-axi-sdc
|
||||
cp -r $(BRPACKAGES)/fpga-axi-sdc $(BUILDROOT)/package
|
||||
sed -i 's|FPGA_AXI_SDC_SITE =|FPGA_AXI_SDC_SITE = $(PACKAGE_SOURCE)|1' $(BUILDROOT)/package/fpga-axi-sdc/fpga-axi-sdc.mk
|
||||
cd $(BUILDROOT); if git apply --check $(PATCHFILE) > /dev/null ; then git apply $(PATCHFILE); fi
|
||||
|
||||
$(PATCHFILE):
|
||||
cd $(BUILDROOT); git apply $(PATCHFILE)
|
||||
|
||||
$(BUILDROOT):
|
||||
git clone https://github.com/buildroot/buildroot.git $@
|
||||
# cd $@; git checkout 2023.05.x
|
||||
cd $@; git checkout 2021.05
|
||||
|
||||
$(DRIVER):
|
||||
@ if [ -d "$(WALLY)/addins/vivado-risc-v" ] ; then git submodule update --init $(WALLY)/addins/vivado-risc-v; fi
|
||||
cp ../addins/vivado-risc-v/patches/fpga-axi-sdc.c $@
|
||||
# For 2021.05
|
||||
sed -i "s|card_hw_reset|hw_reset|1" $@
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
cleanDriver:
|
||||
rm -f $(DRIVER)
|
||||
|
||||
cleanDTB:
|
||||
rm -f $(IMAGES)/*.dtb
|
||||
|
||||
clean:
|
||||
rm -rf $(DIS)
|
52
linux/README.MD
Normal file
52
linux/README.MD
Normal file
|
@ -0,0 +1,52 @@
|
|||
# Linux for core-v-wally
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Setting up Buildroot](#buildroot)
|
||||
2. [Generating Device Tree Binaries](#devicetree)
|
||||
3. [Disassembling the Binaries for Debugging](#disassembly)
|
||||
4. [Creating a Bootable SD Card](#sdcard)
|
||||
|
||||
## Setting up Buildroot <a name="buildroot"></a>
|
||||
|
||||
In order to generate the Linux and boot stage binaries compatible with Wally, Buildroot is used for cross-compilation. To set up a Buildroot directory, configuration files for Buildroot, Linux, and Busybox must be copied into the correct locations inside the main Buildroot directory. This can be done automatically using the Makefile inside Wally's Linux subdirectory (this one). To install and patch a fresh Buildroot directory, type:
|
||||
|
||||
$ make install BUILDROOT=path/to/buildroot
|
||||
|
||||
You can override the `BUILDROOT` variable to place buildroot where you want it. By default it will be placed at `/opt/riscv/buildroot`. In addition to copying the configuration files, it will install the buildroot package needed to build the SD card driver for Linux.
|
||||
|
||||
To install a new buildroot directory, build the binaries, and generate the device tree binaries in one command, use:
|
||||
|
||||
$ make BUILDROOT=path/to/buildroot
|
||||
|
||||
Or simply use the default buildroot location in `/opt/riscv`:
|
||||
|
||||
$ make
|
||||
|
||||
Note that the `$RISCV` variable cannot be set prior to building in buildroot or the build will fail. It is best to run `source ./setup.sh` to alter your `$PATH` and set the `$RISCV` variable after buildroot has succesfully built the binaries. If you're new to buildroot, you can find the binaries in `<BUILDROOT>/output/images`.
|
||||
|
||||
## Generating Device Tree Binaries <a name="devicetree"></a>
|
||||
|
||||
The device tree files for the various FPGA's Wally supports, as well as QEMU's device tree for the virt machine, are located in the `./devicetree` subdirectory. These device tree files are necessary for the boot process. In order to build the device tree binaries (.dtb) from the device tree sources (.dts), we can build all of them at once using:
|
||||
|
||||
$ make generate BUILDROOT=path/to/buildroot
|
||||
|
||||
Or for the default buildroot location:
|
||||
|
||||
$ make generate
|
||||
|
||||
The .dts files will end up in the `<BUILDROOT>/output/images` folder of your chosen buildroot directory.
|
||||
|
||||
## Disassembling the Binaries for Debugging <a name="disassembly"></a>
|
||||
|
||||
By using the `riscv64-unknown-elf-objdump` utility, we can disassemble the binaries in `<BUILDROOT>/output/images` so that we can explore the resulting machine code instructions and see what assembly or C code the instructions came from, along with the corresponding addresses. This is useful during debugging in order to trace how code is being executed.
|
||||
|
||||
To create the disassembled binaries, run:
|
||||
|
||||
$ make disassemble BUILDROOT=path/to/buildroot
|
||||
|
||||
You'll find the resulting disassembled files in `<BUILDROOT>/output/images/disassembly`.
|
||||
|
||||
## Creating a Bootable SD Card <a name="sdcard"></a>
|
||||
|
||||
|
1679
linux/buildroot-config-src/buildroot-2023.05.1/linux.config
Normal file
1679
linux/buildroot-config-src/buildroot-2023.05.1/linux.config
Normal file
File diff suppressed because it is too large
Load diff
4326
linux/buildroot-config-src/buildroot-2023.05.1/main.config
Normal file
4326
linux/buildroot-config-src/buildroot-2023.05.1/main.config
Normal file
File diff suppressed because it is too large
Load diff
|
@ -2,7 +2,7 @@ FPGA_AXI_SDC_MODULE_VERSION = 1.0
|
|||
# TODO This variable needs to change based on where the package
|
||||
# contents are stored on each individual computer. Might parameterize
|
||||
# this somehow.
|
||||
FPGA_AXI_SDC_SITE = /home/jpease/repos/fpga-axi-sdc
|
||||
FPGA_AXI_SDC_SITE =
|
||||
FPGA_AXI_SDC_SITE_METHOD = local
|
||||
FPGA_AXI_SDC_LICENSE = GPLv2
|
||||
|
||||
|
|
12
linux/buildroot-packages/package-2023.05.1.patch
Normal file
12
linux/buildroot-packages/package-2023.05.1.patch
Normal file
|
@ -0,0 +1,12 @@
|
|||
diff --git a/package/Config.in b/package/Config.in
|
||||
index ad438667d2..810bf0897e 100644
|
||||
--- a/package/Config.in
|
||||
+++ b/package/Config.in
|
||||
@@ -503,6 +503,7 @@ endmenu
|
||||
source "package/fconfig/Config.in"
|
||||
source "package/flashrom/Config.in"
|
||||
source "package/fmtools/Config.in"
|
||||
+ source "package/fpga-axi-sdc/Config.in"
|
||||
source "package/freeipmi/Config.in"
|
||||
source "package/freescale-imx/Config.in"
|
||||
source "package/fxload/Config.in"
|
|
@ -379,15 +379,11 @@ static irqreturn_t sdc_isr(int irq, void * dev_id) {
|
|||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
// JACOB: Had to modify this to resemble the older version of Linux
|
||||
// Used to be called hw_reset in older versions. Now it's
|
||||
// called .card_hw_reset to make it unambiguous what it's
|
||||
// resetting. When I update Linux, this will be changed back.
|
||||
static const struct mmc_host_ops axi_sdc_ops = {
|
||||
.request = sdc_request,
|
||||
.set_ios = sdc_set_ios,
|
||||
.get_cd = sdc_get_cd,
|
||||
.hw_reset = sdc_card_reset,
|
||||
.card_hw_reset = sdc_card_reset,
|
||||
};
|
||||
|
||||
static int axi_sdc_probe(struct platform_device * pdev) {
|
||||
|
|
|
@ -15,14 +15,14 @@
|
|||
|
||||
memory@80000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x00 0x80000000 0x00 0x08000000>;
|
||||
reg = <0x00 0x80000000 0x00 0x10000000>;
|
||||
};
|
||||
|
||||
cpus {
|
||||
#address-cells = <0x01>;
|
||||
#size-cells = <0x00>;
|
||||
clock-frequency = <0x1036640>;
|
||||
timebase-frequency = <0x1036640>;
|
||||
clock-frequency = <0x1312D00>;
|
||||
timebase-frequency = <0x1312D00>;
|
||||
|
||||
cpu@0 {
|
||||
phandle = <0x01>;
|
||||
|
@ -51,7 +51,7 @@
|
|||
uart@10000000 {
|
||||
interrupts = <0x0a>;
|
||||
interrupt-parent = <0x03>;
|
||||
clock-frequency = <0x1036640>;
|
||||
clock-frequency = <0x1312D00>;
|
||||
reg = <0x00 0x10000000 0x00 0x100>;
|
||||
compatible = "ns16550a";
|
||||
};
|
||||
|
@ -74,11 +74,11 @@
|
|||
fifo-depth = <256>;
|
||||
bus-width = <4>;
|
||||
interrupt-parent = <0x03>;
|
||||
clock = <0x1036640>;
|
||||
max-frequency = <0xA7D8C0>;
|
||||
clock = <0x1312D00>;
|
||||
max-frequency = <0x1312D00>;
|
||||
cap-sd-highspeed;
|
||||
cap-mmc-highspeed;
|
||||
no-sdio;
|
||||
sdio;
|
||||
};
|
||||
|
||||
clint@2000000 {
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
memory@80000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x00 0x80000000 0x00 0x08000000>;
|
||||
reg = <0x00 0x80000000 0x00 0x10000000>;
|
||||
};
|
||||
|
||||
cpus {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Exit on any error (return code != 0)
|
||||
set -e
|
||||
# set -e
|
||||
|
||||
# Output colors
|
||||
GREEN='\033[1;32m'
|
||||
|
@ -11,10 +11,10 @@ NAME="$GREEN"${0:2}"$NC"
|
|||
|
||||
# File location variables
|
||||
RISCV=/opt/riscv
|
||||
IMAGES=/home/ross/repos/buildroot/output/images/
|
||||
IMAGES=$RISCV/buildroot/output/images/
|
||||
FW_JUMP=$IMAGES/fw_jump.bin
|
||||
LINUX_KERNEL=$IMAGES/Image
|
||||
DEVICE_TREE=$IMAGES/wally-artya7.dtb
|
||||
DEVICE_TREE=$IMAGES/wally-vcu108.dtb
|
||||
|
||||
# Mount Directory
|
||||
MNT_DIR=wallyimg
|
||||
|
@ -61,12 +61,19 @@ echo -e "$NAME: Device tree block size: $DST_SIZE"
|
|||
echo -e "$NAME: OpenSBI FW_JUMP block size: $FW_JUMP_SIZE"
|
||||
echo -e "$NAME: Kernel block size: $KERNEL_SIZE"
|
||||
|
||||
read -p "Warning: " -n 1 -r
|
||||
read -p "Warning: Doing this will replace all data on this card.\nContinue? y/n: " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]] ; then
|
||||
# Make empty image
|
||||
#echo -e "$NAME: Creating blank image"
|
||||
#sudo dd if=/dev/zero of=$1 bs=4k conv=noerror status=progress && sync
|
||||
DEVBASENAME=$(basename $1)
|
||||
CHECKMOUNT=$(lsblk | grep "sdb4" | tr -s ' ' | cut -d' ' -f 7)
|
||||
|
||||
if [ ! -z $CHECKMOUNT ] ; then
|
||||
sudo umount -v $CHECKMOUNT
|
||||
fi
|
||||
|
||||
#Make empty image
|
||||
echo -e "$NAME: Creating blank image"
|
||||
sudo dd if=/dev/zero of=$1 bs=64k status=progress && sync
|
||||
|
||||
# GUID Partition Tables (GPT)
|
||||
# ===============================================
|
||||
|
@ -76,12 +83,10 @@ if [[ $REPLY =~ ^[Yy]$ ]] ; then
|
|||
# to 1 sector boundaries I think? This would normally be set to 2048
|
||||
# apparently.
|
||||
|
||||
# sudo sgdisk -g --clear --set-alignment=1 \
|
||||
# --new=1:34:+$FW_JUMP_SIZE: --change-name=1:'opensbi' --typecode=1:2E54B353-1271-4842-806F-E436D6AF6985 \
|
||||
# --new=2:$KERNEL_START:+$KERNEL_SIZE --change-name=2:'kernel' --typecode=2:3000 \
|
||||
# --new=3:$FS_START:-0 --change-name=3:'filesystem' \
|
||||
# $1
|
||||
sudo sgdisk -z $1
|
||||
|
||||
sleep 1
|
||||
|
||||
echo -e "$NAME: Creating GUID Partition Table"
|
||||
sudo sgdisk -g --clear --set-alignment=1 \
|
||||
--new=1:34:+$DST_SIZE: --change-name=1:'fdt' \
|
||||
|
@ -92,6 +97,8 @@ if [[ $REPLY =~ ^[Yy]$ ]] ; then
|
|||
|
||||
sudo partprobe $1
|
||||
|
||||
sleep 3
|
||||
|
||||
echo -e "$NAME: Copying binaries into their partitions."
|
||||
DD_FLAGS="bs=4k iflag=fullblock oflag=direct conv=fsync status=progress"
|
||||
|
||||
|
|
|
@ -1,502 +0,0 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
|
@ -1,152 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013-2022 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 Authors ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from https://www.gnu.org/licenses/ ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
`include "sd_defines.h"
|
||||
|
||||
module sd_cmd_master(
|
||||
input clock,
|
||||
input clock_posedge,
|
||||
input reset,
|
||||
input start,
|
||||
input int_status_rst,
|
||||
output [1:0] setting,
|
||||
output reg start_xfr,
|
||||
output reg go_idle,
|
||||
output reg [39:0] cmd,
|
||||
input [119:0] response,
|
||||
input crc_error,
|
||||
input index_ok,
|
||||
input finish,
|
||||
input busy, // direct signal from data sd data input (data[0])
|
||||
//input card_detect,
|
||||
input [31:0] argument,
|
||||
input [`CMD_REG_SIZE-1:0] command,
|
||||
input [`CMD_TIMEOUT_W-1:0] timeout,
|
||||
output [`INT_CMD_SIZE-1:0] int_status,
|
||||
output reg [31:0] response_0,
|
||||
output reg [31:0] response_1,
|
||||
output reg [31:0] response_2,
|
||||
output reg [31:0] response_3
|
||||
);
|
||||
|
||||
reg expect_response;
|
||||
reg long_response;
|
||||
reg [`INT_CMD_SIZE-1:0] int_status_reg;
|
||||
reg [`CMD_TIMEOUT_W-1:0] watchdog;
|
||||
reg watchdog_enable;
|
||||
|
||||
reg [2:0] state;
|
||||
parameter IDLE = 3'b001;
|
||||
parameter EXECUTE = 3'b010;
|
||||
parameter BUSY_CHECK = 3'b100;
|
||||
|
||||
assign setting[1:0] = {long_response, expect_response};
|
||||
assign int_status = state == IDLE ? int_status_reg : 5'h0;
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (reset) begin
|
||||
response_0 <= 0;
|
||||
response_1 <= 0;
|
||||
response_2 <= 0;
|
||||
response_3 <= 0;
|
||||
int_status_reg <= 0;
|
||||
expect_response <= 0;
|
||||
long_response <= 0;
|
||||
cmd <= 0;
|
||||
start_xfr <= 0;
|
||||
watchdog <= 0;
|
||||
watchdog_enable <= 0;
|
||||
go_idle <= 0;
|
||||
state <= IDLE;
|
||||
end else if (clock_posedge) begin
|
||||
case (state)
|
||||
IDLE: begin
|
||||
go_idle <= 0;
|
||||
if (command[`CMD_RESPONSE_CHECK] == 2'b10 || command[`CMD_RESPONSE_CHECK] == 2'b11) begin
|
||||
expect_response <= 1;
|
||||
long_response <= 1;
|
||||
end else if (command[`CMD_RESPONSE_CHECK] == 2'b01) begin
|
||||
expect_response <= 1;
|
||||
long_response <= 0;
|
||||
end else begin
|
||||
expect_response <= 0;
|
||||
long_response <= 0;
|
||||
end
|
||||
cmd[39:38] <= 2'b01;
|
||||
cmd[37:32] <= command[`CMD_INDEX];
|
||||
cmd[31:0] <= argument;
|
||||
watchdog <= 0;
|
||||
watchdog_enable <= timeout != 0;
|
||||
if (start) begin
|
||||
start_xfr <= 1;
|
||||
int_status_reg <= 0;
|
||||
state <= EXECUTE;
|
||||
end
|
||||
end
|
||||
EXECUTE: begin
|
||||
start_xfr <= 0;
|
||||
if (watchdog_enable && watchdog >= timeout) begin
|
||||
int_status_reg[`INT_CMD_CTE] <= 1;
|
||||
int_status_reg[`INT_CMD_EI] <= 1;
|
||||
go_idle <= 1;
|
||||
state <= IDLE;
|
||||
end else if (finish) begin
|
||||
if (command[`CMD_CRC_CHECK] && crc_error) begin
|
||||
int_status_reg[`INT_CMD_CCRCE] <= 1;
|
||||
int_status_reg[`INT_CMD_EI] <= 1;
|
||||
end
|
||||
if (command[`CMD_IDX_CHECK] && !index_ok) begin
|
||||
int_status_reg[`INT_CMD_CIE] <= 1;
|
||||
int_status_reg[`INT_CMD_EI] <= 1;
|
||||
end
|
||||
int_status_reg[`INT_CMD_CC] <= 1;
|
||||
if (expect_response) begin
|
||||
response_0 <= response[119:88];
|
||||
response_1 <= response[87:56];
|
||||
response_2 <= response[55:24];
|
||||
response_3 <= {response[23:0], 8'h00};
|
||||
end
|
||||
if (command[`CMD_BUSY_CHECK]) state <= BUSY_CHECK;
|
||||
else state <= IDLE;
|
||||
end else if (watchdog_enable) begin
|
||||
watchdog <= watchdog + 1;
|
||||
end
|
||||
end
|
||||
BUSY_CHECK: begin
|
||||
if (!busy) state <= IDLE;
|
||||
end
|
||||
endcase
|
||||
if (int_status_rst)
|
||||
int_status_reg <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -1,263 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013-2022 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 Authors ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from https://www.gnu.org/licenses/ ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
module sd_cmd_serial_host (
|
||||
//---------------Input ports---------------
|
||||
input clock,
|
||||
input clock_posedge,
|
||||
input clock_data_in,
|
||||
input reset,
|
||||
input [1:0] setting,
|
||||
input [39:0] cmd,
|
||||
input start,
|
||||
input cmd_i,
|
||||
//---------------Output ports---------------
|
||||
output reg [119:0] response,
|
||||
output reg finish,
|
||||
output reg crc_ok,
|
||||
output reg index_ok,
|
||||
output reg cmd_oe,
|
||||
output reg cmd_o
|
||||
);
|
||||
|
||||
//-------------Internal Constant-------------
|
||||
parameter INIT_DELAY = 4;
|
||||
parameter BITS_TO_SEND = 48;
|
||||
parameter CMD_SIZE = 40;
|
||||
parameter RESP_SIZE = 128;
|
||||
|
||||
//---------------Internal variable-----------
|
||||
reg cmd_dat_reg;
|
||||
integer resp_len;
|
||||
reg with_response;
|
||||
reg [CMD_SIZE-1:0] cmd_buff;
|
||||
reg [RESP_SIZE-1:0] resp_buff;
|
||||
integer resp_idx;
|
||||
//CRC
|
||||
reg crc_rst;
|
||||
reg [6:0]crc_in;
|
||||
wire [6:0] crc_val;
|
||||
reg crc_enable;
|
||||
reg crc_bit;
|
||||
reg crc_match;
|
||||
//-Internal Counterns
|
||||
integer counter;
|
||||
//-State Machine
|
||||
parameter
|
||||
STATE_SIZE = 8,
|
||||
INIT = 8'b00000001,
|
||||
IDLE = 8'b00000010,
|
||||
SETUP_CRC = 8'b00000100,
|
||||
WRITE = 8'b00001000,
|
||||
READ_WAIT = 8'b00010000,
|
||||
READ = 8'b00100000,
|
||||
FINISH_WR = 8'b01000000,
|
||||
FINISH_WO = 8'b10000000;
|
||||
reg [STATE_SIZE-1:0] state;
|
||||
|
||||
//Misc
|
||||
`define cmd_idx (CMD_SIZE-1-counter)
|
||||
|
||||
//sd cmd input pad register
|
||||
always @(posedge clock) begin
|
||||
if (clock_data_in) cmd_dat_reg <= cmd_i;
|
||||
end
|
||||
|
||||
//------------------------------------------
|
||||
sd_crc_7 CRC_7(
|
||||
crc_bit,
|
||||
crc_enable & clock_posedge,
|
||||
clock,
|
||||
crc_rst,
|
||||
crc_val);
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (reset) begin
|
||||
resp_len <= 0;
|
||||
with_response <= 0;
|
||||
cmd_buff <= 0;
|
||||
crc_enable <= 0;
|
||||
resp_idx <= 0;
|
||||
cmd_oe <= 1;
|
||||
cmd_o <= 1;
|
||||
resp_buff <= 0;
|
||||
finish <= 0;
|
||||
crc_rst <= 1;
|
||||
crc_bit <= 0;
|
||||
crc_in <= 0;
|
||||
response <= 0;
|
||||
index_ok <= 0;
|
||||
crc_ok <= 0;
|
||||
crc_match <= 0;
|
||||
counter <= 0;
|
||||
state <= INIT;
|
||||
end else if (clock_posedge) begin
|
||||
case (state)
|
||||
INIT: begin
|
||||
counter <= counter+1;
|
||||
// Pull cmd line up
|
||||
cmd_oe <= 1;
|
||||
cmd_o <= 1;
|
||||
if (counter >= INIT_DELAY) state <= IDLE;
|
||||
end
|
||||
IDLE: begin
|
||||
cmd_oe <= 0;
|
||||
counter <= 0;
|
||||
crc_rst <= 1;
|
||||
crc_enable <= 0;
|
||||
response <= 0;
|
||||
resp_idx <= 0;
|
||||
crc_ok <= 0;
|
||||
index_ok <= 0;
|
||||
finish <= 0;
|
||||
if (start) begin
|
||||
resp_len <= setting[1] ? 127 : 39;
|
||||
with_response <= setting[0];
|
||||
cmd_buff <= cmd;
|
||||
state <= SETUP_CRC;
|
||||
end
|
||||
end
|
||||
SETUP_CRC: begin
|
||||
crc_rst <= 0;
|
||||
crc_enable <= 1;
|
||||
crc_bit <= cmd_buff[`cmd_idx];
|
||||
state <= WRITE;
|
||||
end
|
||||
WRITE: begin
|
||||
if (counter < BITS_TO_SEND-8) begin // 1->40 CMD, (41 >= CNT && CNT <=47) CRC, 48 stop_bit
|
||||
cmd_oe <= 1;
|
||||
cmd_o <= cmd_buff[`cmd_idx];
|
||||
if (counter < BITS_TO_SEND-9) begin //1 step ahead
|
||||
crc_bit <= cmd_buff[`cmd_idx-1];
|
||||
end else begin
|
||||
crc_enable <= 0;
|
||||
end
|
||||
end else if (counter < BITS_TO_SEND-1) begin
|
||||
cmd_oe <= 1;
|
||||
crc_enable <= 0;
|
||||
cmd_o <= crc_val[BITS_TO_SEND-counter-2];
|
||||
end else if (counter == BITS_TO_SEND-1) begin
|
||||
cmd_oe <= 1;
|
||||
cmd_o <= 1'b1;
|
||||
end else begin
|
||||
cmd_oe <= 0;
|
||||
cmd_o <= 1'b1;
|
||||
end
|
||||
counter <= counter + 1;
|
||||
if (counter >= BITS_TO_SEND && with_response) state <= READ_WAIT;
|
||||
else if (counter >= BITS_TO_SEND) state <= FINISH_WO;
|
||||
end
|
||||
READ_WAIT: begin
|
||||
crc_enable <= 0;
|
||||
crc_rst <= 1;
|
||||
counter <= 1;
|
||||
cmd_oe <= 0;
|
||||
resp_buff[RESP_SIZE-1] <= cmd_dat_reg;
|
||||
if (!cmd_dat_reg) state <= READ;
|
||||
end
|
||||
FINISH_WO: begin
|
||||
finish <= 1;
|
||||
crc_enable <= 0;
|
||||
crc_rst <= 1;
|
||||
counter <= 0;
|
||||
cmd_oe <= 0;
|
||||
state <= IDLE;
|
||||
end
|
||||
READ: begin
|
||||
crc_rst <= 0;
|
||||
crc_enable <= (resp_len != RESP_SIZE-1 || counter > 7);
|
||||
cmd_oe <= 0;
|
||||
if (counter <= resp_len) begin
|
||||
if (counter < 8) //1+1+6 (S,T,Index)
|
||||
resp_buff[RESP_SIZE-1-counter] <= cmd_dat_reg;
|
||||
else begin
|
||||
resp_idx <= resp_idx + 1;
|
||||
resp_buff[RESP_SIZE-9-resp_idx] <= cmd_dat_reg;
|
||||
end
|
||||
crc_bit <= cmd_dat_reg;
|
||||
end else if (counter-resp_len <= 7) begin
|
||||
crc_in[(resp_len+7)-(counter)] <= cmd_dat_reg;
|
||||
crc_enable <= 0;
|
||||
end else begin
|
||||
crc_enable <= 0;
|
||||
crc_match <= crc_in == crc_val;
|
||||
end
|
||||
counter <= counter + 1;
|
||||
if (counter >= resp_len+8) state <= FINISH_WR;
|
||||
end
|
||||
FINISH_WR: begin
|
||||
index_ok <= cmd_buff[37:32] == resp_buff[125:120];
|
||||
crc_ok <= crc_match;
|
||||
finish <= 1;
|
||||
crc_enable <= 0;
|
||||
crc_rst <= 1;
|
||||
counter <= 0;
|
||||
cmd_oe <= 0;
|
||||
response <= resp_buff[119:0];
|
||||
state <= IDLE;
|
||||
end
|
||||
default:
|
||||
state <= INIT;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module sd_crc_7(
|
||||
input BITVAL, // Next input bit
|
||||
input ENABLE, // Enable calculation
|
||||
input BITSTRB, // Current bit valid (Clock)
|
||||
input CLEAR, // Init CRC value
|
||||
output reg [6:0] CRC // Current output CRC value
|
||||
);
|
||||
|
||||
wire inv;
|
||||
assign inv = BITVAL ^ CRC[6];
|
||||
|
||||
always @(posedge BITSTRB or posedge CLEAR) begin
|
||||
if (CLEAR) begin
|
||||
CRC <= 0;
|
||||
end else if (ENABLE == 1) begin
|
||||
CRC[6] <= CRC[5];
|
||||
CRC[5] <= CRC[4];
|
||||
CRC[4] <= CRC[3];
|
||||
CRC[3] <= CRC[2] ^ inv;
|
||||
CRC[2] <= CRC[1];
|
||||
CRC[1] <= CRC[0];
|
||||
CRC[0] <= inv;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -1,150 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013-2022 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 Authors ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from https://www.gnu.org/licenses/ ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
`include "sd_defines.h"
|
||||
|
||||
module sd_data_master (
|
||||
input clock,
|
||||
input clock_posedge,
|
||||
input reset,
|
||||
input start_tx,
|
||||
input start_rx,
|
||||
input [`DATA_TIMEOUT_W-1:0] timeout,
|
||||
// Output to SD-Host Reg
|
||||
output reg d_write,
|
||||
output reg d_read,
|
||||
// To fifo filler
|
||||
(* mark_debug = "true" *) output reg en_tx_fifo,
|
||||
output reg en_rx_fifo,
|
||||
(* mark_debug = "true" *) input fifo_empty,
|
||||
input fifo_ready,
|
||||
input fifo_full,
|
||||
(* mark_debug = "true" *) input bus_cycle,
|
||||
// SD-DATA_Host
|
||||
input xfr_complete,
|
||||
input crc_error,
|
||||
input bus_error,
|
||||
// status output
|
||||
output reg [`INT_DATA_SIZE-1:0] int_status,
|
||||
input int_status_rst
|
||||
);
|
||||
|
||||
reg [3:0] state;
|
||||
localparam IDLE = 4'b0001;
|
||||
localparam START_TX_FIFO = 4'b0010;
|
||||
localparam START_RX_FIFO = 4'b0100;
|
||||
localparam DATA_TRANSFER = 4'b1000;
|
||||
|
||||
(* mark_debug = "true" *) reg [`DATA_TIMEOUT_W-1:0] watchdog;
|
||||
reg watchdog_enable;
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (reset) begin
|
||||
en_tx_fifo <= 0;
|
||||
en_rx_fifo <= 0;
|
||||
d_write <= 0;
|
||||
d_read <= 0;
|
||||
int_status <= 0;
|
||||
watchdog <= 0;
|
||||
watchdog_enable <= 0;
|
||||
state <= IDLE;
|
||||
end else if (clock_posedge) begin
|
||||
case (state)
|
||||
IDLE: begin
|
||||
en_tx_fifo <= 0;
|
||||
en_rx_fifo <= 0;
|
||||
d_write <= 0;
|
||||
d_read <= 0;
|
||||
watchdog <= 0;
|
||||
watchdog_enable <= timeout != 0;
|
||||
if (start_tx) state <= START_TX_FIFO;
|
||||
else if (start_rx) state <= START_RX_FIFO;
|
||||
end
|
||||
START_RX_FIFO: begin
|
||||
en_rx_fifo <= 1;
|
||||
en_tx_fifo <= 0;
|
||||
d_read <= 1;
|
||||
if (!xfr_complete) state <= DATA_TRANSFER;
|
||||
end
|
||||
START_TX_FIFO: begin
|
||||
en_rx_fifo <= 0;
|
||||
en_tx_fifo <= 1;
|
||||
if (fifo_ready) begin
|
||||
d_write <= 1;
|
||||
if (!xfr_complete) state <= DATA_TRANSFER;
|
||||
end
|
||||
end
|
||||
DATA_TRANSFER: begin
|
||||
d_read <= 0;
|
||||
d_write <= 0;
|
||||
if (en_tx_fifo && fifo_empty) begin
|
||||
int_status[`INT_DATA_CFE] <= 1;
|
||||
int_status[`INT_DATA_EI] <= 1;
|
||||
state <= IDLE;
|
||||
// stop sd_data_serial_host
|
||||
d_write <= 1;
|
||||
d_read <= 1;
|
||||
end else if (en_rx_fifo && fifo_full) begin
|
||||
int_status[`INT_DATA_CFE] <= 1;
|
||||
int_status[`INT_DATA_EI] <= 1;
|
||||
state <= IDLE;
|
||||
// stop sd_data_serial_host
|
||||
d_write <= 1;
|
||||
d_read <= 1;
|
||||
end else if (watchdog_enable && watchdog >= timeout) begin
|
||||
int_status[`INT_DATA_CTE] <= 1;
|
||||
int_status[`INT_DATA_EI] <= 1;
|
||||
state <= IDLE;
|
||||
// stop sd_data_serial_host
|
||||
d_write <= 1;
|
||||
d_read <= 1;
|
||||
end else if (xfr_complete && !bus_cycle && (en_tx_fifo || fifo_empty)) begin
|
||||
state <= IDLE;
|
||||
if (crc_error) begin
|
||||
int_status[`INT_DATA_CCRCE] <= 1;
|
||||
int_status[`INT_DATA_EI] <= 1;
|
||||
end
|
||||
if (bus_error) begin
|
||||
int_status[`INT_DATA_CBE] <= 1;
|
||||
int_status[`INT_DATA_EI] <= 1;
|
||||
end
|
||||
int_status[`INT_DATA_CC] <= 1;
|
||||
end else if (watchdog_enable) begin
|
||||
watchdog <= watchdog + 1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
if (int_status_rst)
|
||||
int_status <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -1,311 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013-2022 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 Authors ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from https://www.gnu.org/licenses/ ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
`include "sd_defines.h"
|
||||
|
||||
module sd_data_serial_host(
|
||||
input clock,
|
||||
input clock_posedge,
|
||||
input clock_data_in,
|
||||
input reset,
|
||||
// Tx Fifo
|
||||
input [31:0] data_in,
|
||||
output reg rd,
|
||||
// Rx Fifo
|
||||
output reg [31:0] data_out,
|
||||
output reg we,
|
||||
// tristate data
|
||||
output reg dat_oe,
|
||||
output reg[3:0] dat_o,
|
||||
input [3:0] dat_i,
|
||||
// Controll signals
|
||||
input [`BLKSIZE_W-1:0] blksize,
|
||||
input bus_4bit,
|
||||
input [`BLKCNT_W-1:0] blkcnt,
|
||||
input [1:0] start,
|
||||
input [1:0] byte_alignment,
|
||||
output sd_data_busy,
|
||||
output busy,
|
||||
output reg crc_ok
|
||||
);
|
||||
|
||||
reg [3:0] DAT_dat_reg;
|
||||
reg bus_4bit_reg;
|
||||
reg crc_en;
|
||||
reg crc_rst;
|
||||
wire [15:0] crc_out [3:0];
|
||||
reg [`BLKSIZE_W+4-1:0] data_cycles;
|
||||
reg [`BLKSIZE_W+4-1:0] transf_cnt;
|
||||
reg [3:0] drt_bit;
|
||||
reg [3:0] drt_reg;
|
||||
(* mark_debug = "true" *) reg [`BLKCNT_W-1:0] blkcnt_reg;
|
||||
reg [1:0] byte_alignment_reg;
|
||||
reg [3:0] crc_bit;
|
||||
reg [3:0] last_din;
|
||||
reg [4:0] data_index;
|
||||
|
||||
reg [6:0] state;
|
||||
parameter IDLE = 7'b0000001;
|
||||
parameter WRITE_DAT = 7'b0000010;
|
||||
parameter WRITE_WAIT = 7'b0000100;
|
||||
parameter WRITE_DRT = 7'b0001000;
|
||||
parameter WRITE_BUSY = 7'b0010000;
|
||||
parameter READ_WAIT = 7'b0100000;
|
||||
parameter READ_DAT = 7'b1000000;
|
||||
|
||||
// sd data input pad register
|
||||
always @(posedge clock) begin
|
||||
if (clock_data_in) DAT_dat_reg <= dat_i;
|
||||
end
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i=0; i<4; i=i+1) begin: CRC_16_gen
|
||||
sd_crc_16 CRC_16_i (last_din[i], crc_en & clock_posedge, clock, crc_rst, crc_out[i]);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign busy = (state != IDLE);
|
||||
assign sd_data_busy = !DAT_dat_reg[0];
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (reset) begin
|
||||
state <= IDLE;
|
||||
dat_oe <= 0;
|
||||
crc_en <= 0;
|
||||
crc_rst <= 1;
|
||||
transf_cnt <= 0;
|
||||
rd <= 0;
|
||||
last_din <= 0;
|
||||
crc_bit <= 0;
|
||||
dat_o <= 4'b1111;
|
||||
drt_bit <= 0;
|
||||
drt_reg <= 0;
|
||||
we <= 0;
|
||||
data_out <= 0;
|
||||
crc_ok <= 0;
|
||||
data_index <= 0;
|
||||
blkcnt_reg <= 0;
|
||||
byte_alignment_reg <= 0;
|
||||
data_cycles <= 0;
|
||||
bus_4bit_reg <= 0;
|
||||
end else if (clock_posedge) begin
|
||||
case (state)
|
||||
IDLE: begin
|
||||
dat_oe <= 0;
|
||||
dat_o <= 4'b1111;
|
||||
transf_cnt <= 0;
|
||||
crc_en <= 0;
|
||||
crc_rst <= 1;
|
||||
crc_bit <= 15;
|
||||
we <= 0;
|
||||
rd <= 0;
|
||||
data_index <= 0;
|
||||
blkcnt_reg <= blkcnt;
|
||||
byte_alignment_reg <= byte_alignment;
|
||||
data_cycles <= (bus_4bit ? {3'b000, blksize, 1'b0} + 2 : {1'b0, blksize, 3'b000} + 8);
|
||||
bus_4bit_reg <= bus_4bit;
|
||||
if (start == 2'b01) state <= WRITE_DAT;
|
||||
else if (start == 2'b10) state <= READ_WAIT;
|
||||
end
|
||||
WRITE_DAT: begin
|
||||
rd <= 0;
|
||||
transf_cnt <= transf_cnt + 16'h1;
|
||||
if (transf_cnt == 0) begin
|
||||
crc_ok <= 0;
|
||||
crc_bit <= 15;
|
||||
end else if (transf_cnt == 1) begin
|
||||
crc_rst <= 0;
|
||||
crc_en <= 1;
|
||||
if (bus_4bit_reg) begin
|
||||
last_din <= {
|
||||
data_in[31-(byte_alignment_reg << 3)],
|
||||
data_in[30-(byte_alignment_reg << 3)],
|
||||
data_in[29-(byte_alignment_reg << 3)],
|
||||
data_in[28-(byte_alignment_reg << 3)]
|
||||
};
|
||||
end else begin
|
||||
last_din <= {3'h7, data_in[31-(byte_alignment_reg << 3)]};
|
||||
end
|
||||
dat_oe <= 1;
|
||||
dat_o <= bus_4bit_reg ? 4'h0 : 4'he;
|
||||
data_index <= bus_4bit_reg ? {2'b00, byte_alignment_reg, 1'b1} : {byte_alignment_reg, 3'b001};
|
||||
end else if (transf_cnt <= data_cycles+1) begin
|
||||
if (bus_4bit_reg) begin
|
||||
last_din <= {
|
||||
data_in[31-(data_index[2:0]<<2)],
|
||||
data_in[30-(data_index[2:0]<<2)],
|
||||
data_in[29-(data_index[2:0]<<2)],
|
||||
data_in[28-(data_index[2:0]<<2)]
|
||||
};
|
||||
if (data_index[2:0] == 3'h6 && transf_cnt <= data_cycles-1) rd <= 1;
|
||||
end else begin
|
||||
last_din <= {3'h7, data_in[31-data_index]};
|
||||
if (data_index == 30) rd <= 1;
|
||||
end
|
||||
data_index <= data_index + 5'h1;
|
||||
dat_o <= last_din;
|
||||
if (transf_cnt == data_cycles+1) crc_en <= 0;
|
||||
end else if (transf_cnt <= data_cycles+17) begin
|
||||
crc_en <= 0;
|
||||
dat_o[0] <= crc_out[0][crc_bit];
|
||||
if (bus_4bit_reg)
|
||||
dat_o[3:1] <= {crc_out[3][crc_bit], crc_out[2][crc_bit], crc_out[1][crc_bit]};
|
||||
crc_bit <= crc_bit - 1;
|
||||
end else if (transf_cnt == data_cycles+18) begin
|
||||
dat_o <= 4'hf;
|
||||
end else if (transf_cnt == data_cycles+19) begin
|
||||
dat_oe <= 0;
|
||||
end else begin
|
||||
state <= WRITE_WAIT;
|
||||
end
|
||||
end
|
||||
WRITE_WAIT: begin
|
||||
drt_bit <= 0;
|
||||
if (!DAT_dat_reg[0]) state <= WRITE_DRT;
|
||||
end
|
||||
WRITE_DRT: begin
|
||||
// See 7.3.3.1 Data Response Token
|
||||
if (drt_bit <= 3) begin
|
||||
drt_reg[drt_bit] <= DAT_dat_reg[0];
|
||||
end else if (drt_bit == 15) begin
|
||||
crc_ok <= drt_reg[3:0] == 4'b1010;
|
||||
state <= WRITE_BUSY;
|
||||
end
|
||||
drt_bit <= drt_bit + 1;
|
||||
end
|
||||
WRITE_BUSY: begin
|
||||
if (DAT_dat_reg[0]) begin
|
||||
if (blkcnt_reg != 0 && crc_ok) begin
|
||||
transf_cnt <= 0;
|
||||
blkcnt_reg <= blkcnt_reg - 1;
|
||||
byte_alignment_reg <= byte_alignment_reg + blksize[1:0] + 2'b1;
|
||||
crc_rst <= 1;
|
||||
state <= WRITE_DAT;
|
||||
end else begin
|
||||
state <= IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
READ_WAIT: begin
|
||||
dat_oe <= 0;
|
||||
crc_bit <= 15;
|
||||
last_din <= 0;
|
||||
transf_cnt <= 0;
|
||||
data_index <= bus_4bit_reg ? (byte_alignment_reg << 1) : (byte_alignment_reg << 3);
|
||||
if (!DAT_dat_reg[0]) begin
|
||||
crc_rst <= 0;
|
||||
crc_en <= 1;
|
||||
state <= READ_DAT;
|
||||
end
|
||||
end
|
||||
READ_DAT: begin
|
||||
last_din <= DAT_dat_reg;
|
||||
transf_cnt <= transf_cnt + 16'h1;
|
||||
if (transf_cnt < data_cycles) begin
|
||||
if (bus_4bit_reg) begin
|
||||
we <= (data_index[2:0] == 7 || (transf_cnt == data_cycles-1 && !blkcnt_reg));
|
||||
data_out[31-(data_index[2:0]<<2)] <= DAT_dat_reg[3];
|
||||
data_out[30-(data_index[2:0]<<2)] <= DAT_dat_reg[2];
|
||||
data_out[29-(data_index[2:0]<<2)] <= DAT_dat_reg[1];
|
||||
data_out[28-(data_index[2:0]<<2)] <= DAT_dat_reg[0];
|
||||
end else begin
|
||||
we <= (data_index == 31 || (transf_cnt == data_cycles-1 && !blkcnt_reg));
|
||||
data_out[31-data_index] <= DAT_dat_reg[0];
|
||||
end
|
||||
data_index <= data_index + 5'h1;
|
||||
crc_ok <= 1;
|
||||
end else if (transf_cnt == data_cycles) begin
|
||||
crc_en <= 0;
|
||||
we <= 0;
|
||||
end else if (transf_cnt <= data_cycles+16) begin
|
||||
if (crc_out[0][crc_bit] != last_din[0]) crc_ok <= 0;
|
||||
if (bus_4bit_reg) begin
|
||||
if (crc_out[1][crc_bit] != last_din[1]) crc_ok <= 0;
|
||||
if (crc_out[2][crc_bit] != last_din[2]) crc_ok <= 0;
|
||||
if (crc_out[3][crc_bit] != last_din[3]) crc_ok <= 0;
|
||||
end
|
||||
if (crc_bit == 0) begin
|
||||
byte_alignment_reg <= byte_alignment_reg + blksize[1:0] + 2'b1;
|
||||
crc_rst <= 1;
|
||||
end else begin
|
||||
crc_bit <= crc_bit - 1;
|
||||
end
|
||||
end else if (blkcnt_reg != 0 && crc_ok) begin
|
||||
blkcnt_reg <= blkcnt_reg - 1;
|
||||
state <= READ_WAIT;
|
||||
end else begin
|
||||
state <= IDLE;
|
||||
end
|
||||
end
|
||||
default:
|
||||
state <= IDLE;
|
||||
endcase
|
||||
if (start == 2'b11) state <= IDLE; // Abort
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module sd_crc_16(
|
||||
input BITVAL, // Next input bit
|
||||
input ENABLE, // Enable calculation
|
||||
input BITSTRB, // Current bit valid (Clock)
|
||||
input CLEAR, // Init CRC value
|
||||
output reg [15:0] CRC // Current output CRC value
|
||||
);
|
||||
|
||||
assign inv = BITVAL ^ CRC[15];
|
||||
|
||||
always @(posedge BITSTRB) begin
|
||||
if (CLEAR) begin
|
||||
CRC <= 0;
|
||||
end else if (ENABLE == 1) begin
|
||||
CRC[15] <= CRC[14];
|
||||
CRC[14] <= CRC[13];
|
||||
CRC[13] <= CRC[12];
|
||||
CRC[12] <= CRC[11] ^ inv;
|
||||
CRC[11] <= CRC[10];
|
||||
CRC[10] <= CRC[9];
|
||||
CRC[9] <= CRC[8];
|
||||
CRC[8] <= CRC[7];
|
||||
CRC[7] <= CRC[6];
|
||||
CRC[6] <= CRC[5];
|
||||
CRC[5] <= CRC[4] ^ inv;
|
||||
CRC[4] <= CRC[3];
|
||||
CRC[3] <= CRC[2];
|
||||
CRC[2] <= CRC[1];
|
||||
CRC[1] <= CRC[0];
|
||||
CRC[0] <= inv;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -1,91 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013-2022 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 Authors ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from https://www.gnu.org/licenses/ ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// global defines
|
||||
`define BLKSIZE_W 12
|
||||
`define BLKCNT_W 16
|
||||
`define CMD_TIMEOUT_W 25
|
||||
`define DATA_TIMEOUT_W 28
|
||||
|
||||
// cmd module interrupts
|
||||
`define INT_CMD_SIZE 5
|
||||
`define INT_CMD_CC 0
|
||||
`define INT_CMD_EI 1
|
||||
`define INT_CMD_CTE 2
|
||||
`define INT_CMD_CCRCE 3
|
||||
`define INT_CMD_CIE 4
|
||||
|
||||
// data module interrupts
|
||||
`define INT_DATA_SIZE 6
|
||||
`define INT_DATA_CC 0
|
||||
`define INT_DATA_EI 1
|
||||
`define INT_DATA_CTE 2 // Timeout
|
||||
`define INT_DATA_CCRCE 3 // CRC error
|
||||
`define INT_DATA_CFE 4 // FIFO error
|
||||
`define INT_DATA_CBE 5 // Bus error
|
||||
|
||||
// command register defines
|
||||
`define CMD_REG_SIZE 14
|
||||
`define CMD_RESPONSE_CHECK 1:0
|
||||
`define CMD_BUSY_CHECK 2
|
||||
`define CMD_CRC_CHECK 3
|
||||
`define CMD_IDX_CHECK 4
|
||||
`define CMD_WITH_DATA 6:5
|
||||
`define CMD_INDEX 13:8
|
||||
|
||||
// register addreses
|
||||
`define argument 8'h00
|
||||
`define command 8'h04
|
||||
`define resp0 8'h08
|
||||
`define resp1 8'h0c
|
||||
`define resp2 8'h10
|
||||
`define resp3 8'h14
|
||||
`define data_timeout 8'h18
|
||||
`define controller 8'h1c
|
||||
`define cmd_timeout 8'h20
|
||||
`define clock_d 8'h24
|
||||
`define reset 8'h28
|
||||
`define voltage 8'h2c
|
||||
`define capa 8'h30
|
||||
`define cmd_isr 8'h34
|
||||
`define cmd_iser 8'h38
|
||||
`define data_isr 8'h3c
|
||||
`define data_iser 8'h40
|
||||
`define blksize 8'h44
|
||||
`define blkcnt 8'h48
|
||||
`define card_detect 8'h4c
|
||||
`define dst_src_addr 8'h60
|
||||
`define dst_src_addr_high 8'h64
|
||||
|
||||
// register contents
|
||||
`define RESET_BLOCK_SIZE 12'd511
|
||||
`define RESET_CLOCK_DIV 124
|
|
@ -127,9 +127,6 @@ typedef struct packed {
|
|||
logic SDC_SUPPORTED;
|
||||
logic [63:0] SDC_BASE;
|
||||
logic [63:0] SDC_RANGE;
|
||||
logic SDC2_SUPPORTED;
|
||||
logic [63:0] SDC2_BASE;
|
||||
logic [63:0] SDC2_RANGE;
|
||||
|
||||
// Test modes
|
||||
|
||||
|
|
|
@ -112,8 +112,6 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
|||
assign Xfract = (IFX << ell) << 1;
|
||||
assign Dfract = (IFD << mE) << 1;
|
||||
|
||||
// *** CT: move to fdivsqrtintpreshift
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Integer Right Shift to digit boundary
|
||||
// Determine DivXShifted (X shifted to digit boundary)
|
||||
|
@ -141,8 +139,8 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
|||
assign IntTrunc = TotalIntBits % P.RK; // Truncation check for ceiling operator
|
||||
assign IntSteps = (TotalIntBits >> P.LOGRK) + |IntTrunc; // Number of steps for int div
|
||||
assign nE = (IntSteps * P.DIVCOPIES) - 1; // Fractional digits
|
||||
assign RightShiftX = P.RK - 1 - ((TotalIntBits - 1) % P.RK); // Right shift amount
|
||||
assign DivXShifted = DivX >> RightShiftX; // shift X by up to R*K-1 to complete in nE steps
|
||||
assign RightShiftX = P.RK - 1 - ((TotalIntBits - 1) % P.RK); // Right shift amount
|
||||
assign DivXShifted = DivX >> RightShiftX; // shift X by up to R*K-1 to complete in nE steps
|
||||
/* verilator lint_on WIDTH */
|
||||
end else begin // radix 2 1 copy doesn't require shifting
|
||||
assign nE = p;
|
||||
|
@ -152,14 +150,14 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
|||
assign ISpecialCaseE = 0;
|
||||
end
|
||||
|
||||
// CT *** fdivsqrtfplead1
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Floating-Point Preprocessing
|
||||
// append leading 1 (for nonzero inputs)
|
||||
// shift square root to be in range [1/4, 1)
|
||||
// Normalized numbers are shifted right by 1 if the exponent is odd
|
||||
// Denormalized numbers have Xe = 0 and an unbiased exponent of 1-BIAS. They are shifted right if the number of leading zeros is odd.
|
||||
// Subnormal numbers have Xe = 0 and an unbiased exponent of 1-BIAS. They are shifted right if the number of leading zeros is odd.
|
||||
// NOTE: there might be a discrepancy that X is never right shifted by 2. However
|
||||
// it comes out in the wash and gives the right answer. Investigate later if possible.
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
assign DivX = {3'b000, ~NumerZeroE, Xfract};
|
||||
|
|
|
@ -81,9 +81,9 @@ module fdivsqrtqsel4cmp (
|
|||
|
||||
// Compare residual W to selection constants to choose digit
|
||||
always_comb
|
||||
if ($signed(Wmsbs) >= $signed(mk2)) udigit = 4'b1000; // choose 2
|
||||
else if ($signed(Wmsbs) >= $signed(mk1)) udigit = 4'b0100; // choose 1
|
||||
else if ($signed(Wmsbs) >= $signed(mk0)) udigit = 4'b0000; // choose 0
|
||||
if ($signed(Wmsbs) >= $signed(mk2)) udigit = 4'b1000; // choose 2
|
||||
else if ($signed(Wmsbs) >= $signed(mk1)) udigit = 4'b0100; // choose 1
|
||||
else if ($signed(Wmsbs) >= $signed(mk0)) udigit = 4'b0000; // choose 0
|
||||
else if ($signed(Wmsbs) >= $signed(mkm1)) udigit = 4'b0010; // choose -1
|
||||
else udigit = 4'b0001; // choose -2
|
||||
else udigit = 4'b0001; // choose -2
|
||||
endmodule
|
||||
|
|
|
@ -27,17 +27,17 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module fma import cvw::*; #(parameter cvw_t P) (
|
||||
input logic Xs, Ys, Zs, // input's signs
|
||||
input logic Xs, Ys, Zs, // input's signs
|
||||
input logic [P.NE-1:0] Xe, Ye, Ze, // input's biased exponents in B(NE.0) format
|
||||
input logic [P.NF:0] Xm, Ym, Zm, // input's significands in U(0.NF) format
|
||||
input logic XZero, YZero, ZZero, // is the input zero
|
||||
input logic [2:0] OpCtrl, // operation control
|
||||
output logic ASticky, // sticky bit that is calculated during alignment
|
||||
input logic XZero, YZero, ZZero, // is the input zero
|
||||
input logic [2:0] OpCtrl, // operation control
|
||||
output logic ASticky, // sticky bit that is calculated during alignment
|
||||
output logic [3*P.NF+3:0] Sm, // the positive sum's significand
|
||||
output logic InvA, // Was A inverted for effective subtraction (P-A or -P+A)
|
||||
output logic As, // the aligned addend's sign (modified Z sign for other opperations)
|
||||
output logic Ps, // the product's sign
|
||||
output logic Ss, // the sum's sign
|
||||
output logic InvA, // Was A inverted for effective subtraction (P-A or -P+A)
|
||||
output logic As, // the aligned addend's sign (modified Z sign for other opperations)
|
||||
output logic Ps, // the product's sign
|
||||
output logic Ss, // the sum's sign
|
||||
output logic [P.NE+1:0] Se, // the sum's exponent
|
||||
output logic [$clog2(3*P.NF+5)-1:0] SCnt // normalization shift count
|
||||
);
|
||||
|
@ -56,7 +56,7 @@ module fma import cvw::*; #(parameter cvw_t P) (
|
|||
logic [3*P.NF+3:0] Am; // addend aligned's mantissa for addition in U(NF+4.2NF)
|
||||
logic [3*P.NF+3:0] AmInv; // aligned addend's mantissa possibly inverted
|
||||
logic [2*P.NF+1:0] PmKilled; // the product's mantissa possibly killed U(2.2Nf)
|
||||
logic KillProd; // set the product to zero before addition if the product is too small to matter
|
||||
logic KillProd; // set the product to zero before addition if the product is too small to matter
|
||||
logic [P.NE+1:0] Pe; // the product's exponent B(NE+2.0) format; adds 2 bits to allow for size of number and negative sign
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -67,7 +67,6 @@ module fma import cvw::*; #(parameter cvw_t P) (
|
|||
// - Multiply the mantissas
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// calculate the product's exponent
|
||||
fmaexpadd #(P) expadd(.Xe, .Ye, .XZero, .YZero, .Pe);
|
||||
|
||||
|
@ -80,6 +79,7 @@ module fma import cvw::*; #(parameter cvw_t P) (
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Alignment shifter
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
fmaalign #(P) align(.Ze, .Zm, .XZero, .YZero, .ZZero, .Xe, .Ye, .Am, .ASticky, .KillProd);
|
||||
|
||||
// ///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -91,5 +91,3 @@ module fma import cvw::*; #(parameter cvw_t P) (
|
|||
fmalza #(3*P.NF+4, P.NF) lza(.A(AmInv), .Pm(PmKilled), .Cin(InvA & (~ASticky | KillProd)), .sub(InvA), .SCnt);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
|
|
@ -29,21 +29,21 @@
|
|||
module fmaadd import cvw::*; #(parameter cvw_t P) (
|
||||
input logic [3*P.NF+3:0] Am, // aligned addend's mantissa for addition in U(NF+5.2NF+1)
|
||||
input logic [P.NE-1:0] Ze, // exponent of Z
|
||||
input logic Ps, // the product sign and the alligend addeded's sign (Modified Z sign for other opperations)
|
||||
input logic Ps, // the product sign and the alligend addeded's sign (Modified Z sign for other opperations)
|
||||
input logic [P.NE+1:0] Pe, // product's exponet
|
||||
input logic [2*P.NF+1:0] Pm, // the product's mantissa
|
||||
input logic InvA, // invert the aligned addend
|
||||
input logic KillProd, // should the product be set to 0
|
||||
input logic ASticky, // Alighed addend's sticky bit
|
||||
input logic InvA, // invert the aligned addend
|
||||
input logic KillProd, // should the product be set to 0
|
||||
input logic ASticky, // Alighed addend's sticky bit
|
||||
output logic [3*P.NF+3:0] AmInv, // aligned addend possibly inverted
|
||||
output logic [2*P.NF+1:0] PmKilled, // the product's mantissa possibly killed
|
||||
output logic Ss, // sum's sign
|
||||
output logic Ss, // sum's sign
|
||||
output logic [P.NE+1:0] Se, // sum's exponent
|
||||
output logic [3*P.NF+3:0] Sm // the positive sum
|
||||
);
|
||||
|
||||
logic [3*P.NF+3:0] PreSum, NegPreSum; // possibly negitive sum
|
||||
logic NegSum; // was the sum negitive
|
||||
logic NegSum; // was the sum negitive
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Addition
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
///////////////////////////////////////////
|
||||
// fmaalign.sv
|
||||
//
|
||||
|
@ -28,18 +27,18 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module fmaalign import cvw::*; #(parameter cvw_t P) (
|
||||
input logic [P.NE-1:0] Xe, Ye, Ze, // biased exponents in B(NE.0) format
|
||||
input logic [P.NF:0] Zm, // significand in U(0.NF) format]
|
||||
input logic XZero, YZero, ZZero,// is the input zero
|
||||
output logic [3*P.NF+3:0] Am, // addend aligned for addition in U(NF+5.2NF+1)
|
||||
output logic ASticky, // Sticky bit calculated from the aliged addend
|
||||
output logic KillProd // should the product be set to zero
|
||||
input logic [P.NE-1:0] Xe, Ye, Ze, // biased exponents in B(NE.0) format
|
||||
input logic [P.NF:0] Zm, // significand in U(0.NF) format]
|
||||
input logic XZero, YZero, ZZero, // is the input zero
|
||||
output logic [3*P.NF+3:0] Am, // addend aligned for addition in U(NF+5.2NF+1)
|
||||
output logic ASticky, // Sticky bit calculated from the aliged addend
|
||||
output logic KillProd // should the product be set to zero
|
||||
);
|
||||
|
||||
logic [P.NE+1:0] ACnt; // how far to shift the addend to align with the product in Q(NE+2.0) format
|
||||
logic [4*P.NF+3:0] ZmShifted; // output of the alignment shifter including sticky bits U(NF+5.3NF+1)
|
||||
logic [4*P.NF+3:0] ZmPreshifted; // input to the alignment shifter U(NF+5.3NF+1)
|
||||
logic KillZ; // should the addend be killed
|
||||
logic [P.NE+1:0] ACnt; // how far to shift the addend to align with the product in Q(NE+2.0) format
|
||||
logic [4*P.NF+3:0] ZmShifted; // output of the alignment shifter including sticky bits U(NF+5.3NF+1)
|
||||
logic [4*P.NF+3:0] ZmPreshifted; // input to the alignment shifter U(NF+5.3NF+1)
|
||||
logic KillZ; // should the addend be killed
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Alignment shifter
|
||||
|
@ -51,45 +50,41 @@ module fmaalign import cvw::*; #(parameter cvw_t P) (
|
|||
// This could have been done using Pe, but ACnt is on the critical path so we replicate logic for speed
|
||||
assign ACnt = {2'b0, Xe} + {2'b0, Ye} - {2'b0, (P.NE)'(P.BIAS)} + (P.NE+2)'(P.NF+2) - {2'b0, Ze};
|
||||
|
||||
// Defualt Addition with only inital left shift
|
||||
// | 53'b0 | 106'b(product) | 1'b0 |
|
||||
// | addnend |
|
||||
// Default Addition with only inital left shift
|
||||
// | 53'b0 | 106'b(product) | 1'b0 |
|
||||
// | addnend |
|
||||
|
||||
assign ZmPreshifted = {Zm,(3*P.NF+3)'(0)};
|
||||
|
||||
assign KillProd = (ACnt[P.NE+1]&~ZZero)|XZero|YZero;
|
||||
assign KillZ = $signed(ACnt)>$signed((P.NE+2)'(3)*(P.NE+2)'(P.NF)+(P.NE+2)'(3));
|
||||
assign KillProd = (ACnt[P.NE+1]&~ZZero)|XZero|YZero;
|
||||
assign KillZ = $signed(ACnt)>$signed((P.NE+2)'(3)*(P.NE+2)'(P.NF)+(P.NE+2)'(3));
|
||||
|
||||
always_comb begin
|
||||
// If the product is too small to effect the sum, kill the product
|
||||
|
||||
// | 53'b0 | 106'b(product) | 1'b0 |
|
||||
// | addnend |
|
||||
// | 53'b0 | 106'b(product) | 1'b0 |
|
||||
// | addnend |
|
||||
if (KillProd) begin
|
||||
ZmShifted = {(P.NF+2)'(0), Zm, (2*P.NF+1)'(0)};
|
||||
ASticky = ~(XZero|YZero);
|
||||
ASticky = ~(XZero|YZero);
|
||||
|
||||
// If the addend is too small to effect the addition
|
||||
// - The addend has to shift two past the end of the product to be considered too small
|
||||
// - The 2 extra bits are needed for rounding
|
||||
|
||||
// | 53'b0 | 106'b(product) | 1'b0 |
|
||||
// | addnend |
|
||||
|
||||
// | 53'b0 | 106'b(product) | 1'b0 |
|
||||
// | addnend |
|
||||
end else if (KillZ) begin
|
||||
ZmShifted = 0;
|
||||
ASticky = ~ZZero;
|
||||
ASticky = ~ZZero;
|
||||
|
||||
// If the Addend is shifted right
|
||||
// | 53'b0 | 106'b(product) | 1'b0 |
|
||||
// | addnend |
|
||||
// | 53'b0 | 106'b(product) | 1'b0 |
|
||||
// | addnend |
|
||||
end else begin
|
||||
ZmShifted = ZmPreshifted >> ACnt;
|
||||
ASticky = |(ZmShifted[P.NF-1:0]);
|
||||
|
||||
ASticky = |(ZmShifted[P.NF-1:0]);
|
||||
end
|
||||
end
|
||||
|
||||
assign Am = ZmShifted[4*P.NF+3:P.NF];
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -28,14 +28,14 @@
|
|||
|
||||
module fmaexpadd import cvw::*; #(parameter cvw_t P) (
|
||||
input logic [P.NE-1:0] Xe, Ye, // input's exponents
|
||||
input logic XZero, YZero, // are the inputs zero
|
||||
input logic XZero, YZero, // are the inputs zero
|
||||
output logic [P.NE+1:0] Pe // product's exponent B^(1023)NE+2
|
||||
);
|
||||
|
||||
logic PZero; // is the product zero?
|
||||
logic PZero; // is the product zero?
|
||||
|
||||
// kill the exponent if the product is zero - either X or Y is 0
|
||||
assign PZero = XZero | YZero;
|
||||
assign Pe = PZero ? '0 : ({2'b0, Xe} + {2'b0, Ye} - {2'b0, (P.NE)'(P.BIAS)});
|
||||
assign Pe = PZero ? '0 : ({2'b0, Xe} + {2'b0, Ye} - {2'b0, (P.NE)'(P.BIAS)});
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -28,11 +28,11 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module fmalza #(WIDTH, NF) (
|
||||
input logic [WIDTH-1:0] A, // addend
|
||||
input logic [2*NF+1:0] Pm, // product
|
||||
input logic Cin, // carry in
|
||||
input logic sub, // subtraction
|
||||
output logic [$clog2(WIDTH+1)-1:0] SCnt // normalization shift count for the positive result
|
||||
input logic [WIDTH-1:0] A, // addend
|
||||
input logic [2*NF+1:0] Pm, // product
|
||||
input logic Cin, // carry in
|
||||
input logic sub, // subtraction
|
||||
output logic [$clog2(WIDTH+1)-1:0] SCnt // normalization shift count for the positive result
|
||||
);
|
||||
|
||||
logic [WIDTH:0] F; // most significant bit of F indicates leading digit
|
||||
|
@ -40,19 +40,19 @@ module fmalza #(WIDTH, NF) (
|
|||
logic [WIDTH-1:0] P, G, K; // propagate, generate, kill for each column
|
||||
logic [WIDTH-1:0] Pp1, Gm1, Km1; // propagate shifted right by 1, generate/kill shifted left 1
|
||||
|
||||
assign B = {{(NF+1){1'b0}}, Pm, 1'b0}; // Zero extend product
|
||||
assign B = {{(NF+1){1'b0}}, Pm, 1'b0}; // Zero extend product
|
||||
|
||||
assign P = A^B;
|
||||
assign G = A&B;
|
||||
assign K= ~A&~B;
|
||||
assign K = ~A&~B;
|
||||
|
||||
assign Pp1 = {sub, P[WIDTH-1:1]}; // shift P right by 1 (for P_i+1) , use subtract flag in most significant bit
|
||||
assign Gm1 = {G[WIDTH-2:0], Cin}; // shift G left by 1 (for G_i-1) and bring in Cin
|
||||
assign Km1 = {K[WIDTH-2:0], ~Cin}; // shift K left by 1 (for K_i-1) and bring in Cin
|
||||
assign Pp1 = {sub, P[WIDTH-1:1]}; // shift P right by 1 (for P_i+1) , use subtract flag in most significant bit
|
||||
assign Gm1 = {G[WIDTH-2:0], Cin}; // shift G left by 1 (for G_i-1) and bring in Cin
|
||||
assign Km1 = {K[WIDTH-2:0], ~Cin}; // shift K left by 1 (for K_i-1) and bring in Cin
|
||||
|
||||
// Apply function to determine Leading pattern
|
||||
// - note: Schmookler01 uses the numbering system where 0 is the most significant bit
|
||||
assign F[WIDTH] = ~sub&P[WIDTH-1];
|
||||
assign F[WIDTH] = ~sub&P[WIDTH-1];
|
||||
assign F[WIDTH-1:0] = (Pp1&(G&~Km1 | K&~Gm1)) | (~Pp1&(K&~Km1 | G&~Gm1));
|
||||
|
||||
lzc #(WIDTH+1) lzc (.num(F), .ZeroCnt(SCnt));
|
||||
|
|
|
@ -33,4 +33,3 @@ module fmamult import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
assign Pm = Xm * Ym;
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ module fmasign(
|
|||
output logic InvA // Effective subtraction: invert addend
|
||||
);
|
||||
|
||||
assign Ps = Xs ^ Ys ^ (OpCtrl[1]&~OpCtrl[2]); // product sign. Negate for FMNADD or FNMSUB
|
||||
assign As = Zs^OpCtrl[0]; // flip addend sign for subtraction
|
||||
assign InvA = As ^ Ps; // Effective subtraction when product and addend have opposite signs
|
||||
assign Ps = Xs ^ Ys ^ (OpCtrl[1]&~OpCtrl[2]); // product sign. Negate for FMNADD or FNMSUB
|
||||
assign As = Zs^OpCtrl[0]; // flip addend sign for subtraction
|
||||
assign InvA = As ^ Ps; // Effective subtraction when product and addend have opposite signs
|
||||
endmodule
|
||||
|
|
|
@ -27,16 +27,16 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
|
||||
input logic XZero, // is the input zero?
|
||||
input logic ToInt, // to integer conversion?
|
||||
input logic IntToFp, // interger to floating point conversion?
|
||||
input logic XZero, // is the input zero?
|
||||
input logic ToInt, // to integer conversion?
|
||||
input logic IntToFp, // interger to floating point conversion?
|
||||
input logic [P.FMTBITS-1:0] OutFmt, // output format
|
||||
input logic [P.NE:0] CvtCe, // the calculated expoent
|
||||
input logic [P.NF:0] Xm, // input mantissas
|
||||
input logic [P.CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb)
|
||||
input logic CvtResSubnormUf, // is the conversion result subnormal or underlows
|
||||
output logic CvtResUf, // does the cvt result unerflow
|
||||
output logic [P.CVTLEN+P.NF:0] CvtShiftIn // number to be shifted
|
||||
input logic CvtResSubnormUf, // is the conversion result subnormal or underlows
|
||||
output logic CvtResUf, // does the cvt result unerflow
|
||||
output logic [P.CVTLEN+P.NF:0] CvtShiftIn // number to be shifted
|
||||
);
|
||||
|
||||
logic [$clog2(P.NF):0] ResNegNF; // the result's fraction length negated (-NF)
|
||||
|
@ -47,7 +47,7 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
// seclect the input to the shifter
|
||||
// fp -> int:
|
||||
// | P.XLEN zeros | mantissa | 0's if nessisary |
|
||||
// | P.XLEN zeros | mantissa | 0's if necessary |
|
||||
// .
|
||||
// Other problems:
|
||||
// - if shifting to the right (neg CalcExp) then don't a 1 in the round bit (to prevent an incorrect plus 1 later durring rounding)
|
||||
|
@ -58,16 +58,16 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
|
|||
// | P.NF-1 zeros | mantissa | 0's if nessisary |
|
||||
// .
|
||||
// - otherwise:
|
||||
// | LzcInM | 0's if nessisary |
|
||||
// | LzcInM | 0's if necessary |
|
||||
// .
|
||||
// change to int shift to the left one
|
||||
always_comb
|
||||
// get rid of round bit if needed
|
||||
// | add sticky bit if needed
|
||||
// | |
|
||||
if (ToInt) CvtShiftIn = {{P.XLEN{1'b0}}, Xm[P.NF]&~CvtCe[P.NE], Xm[P.NF-1]|(CvtCe[P.NE]&Xm[P.NF]), Xm[P.NF-2:0], {P.CVTLEN-P.XLEN{1'b0}}};
|
||||
if (ToInt) CvtShiftIn = {{P.XLEN{1'b0}}, Xm[P.NF]&~CvtCe[P.NE], Xm[P.NF-1]|(CvtCe[P.NE]&Xm[P.NF]), Xm[P.NF-2:0], {P.CVTLEN-P.XLEN{1'b0}}};
|
||||
else if (CvtResSubnormUf) CvtShiftIn = {{P.NF-1{1'b0}}, Xm, {P.CVTLEN-P.NF+1{1'b0}}};
|
||||
else CvtShiftIn = {CvtLzcIn, {P.NF+1{1'b0}}};
|
||||
else CvtShiftIn = {CvtLzcIn, {P.NF+1{1'b0}}};
|
||||
|
||||
// choose the negative of the fraction size
|
||||
if (P.FPSIZES == 1) begin
|
||||
|
@ -79,9 +79,9 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
|
|||
end else if (P.FPSIZES == 3) begin
|
||||
always_comb
|
||||
case (OutFmt)
|
||||
P.FMT: ResNegNF = -($clog2(P.NF)+1)'(P.NF);
|
||||
P.FMT1: ResNegNF = -($clog2(P.NF)+1)'(P.NF1);
|
||||
P.FMT2: ResNegNF = -($clog2(P.NF)+1)'(P.NF2);
|
||||
P.FMT: ResNegNF = -($clog2(P.NF)+1)'(P.NF);
|
||||
P.FMT1: ResNegNF = -($clog2(P.NF)+1)'(P.NF1);
|
||||
P.FMT2: ResNegNF = -($clog2(P.NF)+1)'(P.NF2);
|
||||
default: ResNegNF = 'x;
|
||||
endcase
|
||||
|
||||
|
@ -95,8 +95,6 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
|
|||
endcase
|
||||
end
|
||||
|
||||
|
||||
|
||||
// determine if the result underflows ??? -> fp
|
||||
// - if the first 1 is shifted out of the result then the result underflows
|
||||
// - can't underflow an integer to fp conversions
|
||||
|
|
|
@ -31,8 +31,8 @@ module divshiftcalc import cvw::*; #(parameter cvw_t P) (
|
|||
input logic [P.NE+1:0] DivQe, // divsqrt exponent
|
||||
output logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt, // divsqrt shift amount
|
||||
output logic [P.NORMSHIFTSZ-1:0] DivShiftIn, // divsqrt shift input
|
||||
output logic DivResSubnorm, // is the divsqrt result subnormal
|
||||
output logic DivSubnormShiftPos // is the subnormal shift amount positive
|
||||
output logic DivResSubnorm, // is the divsqrt result subnormal
|
||||
output logic DivSubnormShiftPos // is the subnormal shift amount positive
|
||||
);
|
||||
|
||||
logic [P.LOGNORMSHIFTSZ-1:0] NormShift; // normalized result shift amount
|
||||
|
@ -46,10 +46,10 @@ module divshiftcalc import cvw::*; #(parameter cvw_t P) (
|
|||
// if the result is subnormal
|
||||
// 00000000x.xxxxxx... Exp = DivQe
|
||||
// .00000000xxxxxxx... >> NF+1 Exp = DivQe+NF+1
|
||||
// .00xxxxxxxxxxxxx... << DivQe+NF+1 Exp = +1
|
||||
// .00xxxxxxxxxxxxx... << DivQe+NF+1 Exp = +1
|
||||
// .0000xxxxxxxxxxx... >> 1 Exp = 1
|
||||
// Left shift amount = DivQe+NF+1-1
|
||||
assign DivSubnormShift = (P.NE+2)'(P.NF)+DivQe;
|
||||
// Left shift amount = DivQe+NF+1-1
|
||||
assign DivSubnormShift = (P.NE+2)'(P.NF)+DivQe;
|
||||
assign DivSubnormShiftPos = ~DivSubnormShift[P.NE+1];
|
||||
|
||||
// if the result is normalized
|
||||
|
@ -65,7 +65,7 @@ module divshiftcalc import cvw::*; #(parameter cvw_t P) (
|
|||
// if the shift amount is negitive then don't shift (keep sticky bit)
|
||||
// need to multiply the early termination shift by LOGR*DIVCOPIES = left shift of log2(LOGR*DIVCOPIES)
|
||||
assign DivSubnormShiftAmt = DivSubnormShiftPos ? DivSubnormShift[P.LOGNORMSHIFTSZ-1:0] : '0;
|
||||
assign DivShiftAmt = DivResSubnorm ? DivSubnormShiftAmt : NormShift;
|
||||
assign DivShiftAmt = DivResSubnorm ? DivSubnormShiftAmt : NormShift;
|
||||
|
||||
// pre-shift the divider result for normalization
|
||||
assign DivShiftIn = {{P.NF{1'b0}}, DivQm, {P.NORMSHIFTSZ-P.DIVb-1-P.NF{1'b0}}};
|
||||
|
|
|
@ -27,50 +27,50 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module flags import cvw::*; #(parameter cvw_t P) (
|
||||
input logic Xs, // X sign
|
||||
input logic Xs, // X sign
|
||||
input logic [P.FMTBITS-1:0] OutFmt, // output format
|
||||
input logic InfIn, // is a Inf input being used
|
||||
input logic XInf, YInf, ZInf, // inputs are infinity
|
||||
input logic NaNIn, // is a NaN input being used
|
||||
input logic XSNaN, YSNaN, ZSNaN, // inputs are signaling NaNs
|
||||
input logic XZero, YZero, // inputs are zero
|
||||
input logic InfIn, // is a Inf input being used
|
||||
input logic XInf, YInf, ZInf, // inputs are infinity
|
||||
input logic NaNIn, // is a NaN input being used
|
||||
input logic XSNaN, YSNaN, ZSNaN, // inputs are signaling NaNs
|
||||
input logic XZero, YZero, // inputs are zero
|
||||
input logic [P.NE+1:0] FullRe, // Re with bits to determine sign and overflow
|
||||
input logic [P.NE+1:0] Me, // exponent of the normalized sum
|
||||
// rounding
|
||||
input logic Plus1, // do you add one for rounding
|
||||
input logic Round, Guard, Sticky, // bits used to determine rounding
|
||||
input logic UfPlus1, // do you add one for rounding for the unbounded exponent result
|
||||
input logic Plus1, // do you add one for rounding
|
||||
input logic Round, Guard, Sticky, // bits used to determine rounding
|
||||
input logic UfPlus1, // do you add one for rounding for the unbounded exponent result
|
||||
// convert
|
||||
input logic CvtOp, // conversion opperation?
|
||||
input logic ToInt, // convert to integer
|
||||
input logic IntToFp, // convert integer to floating point
|
||||
input logic Int64, // convert to 64 bit integer
|
||||
input logic Signed, // convert to a signed integer
|
||||
input logic CvtOp, // conversion opperation?
|
||||
input logic ToInt, // convert to integer
|
||||
input logic IntToFp, // convert integer to floating point
|
||||
input logic Int64, // convert to 64 bit integer
|
||||
input logic Signed, // convert to a signed integer
|
||||
input logic [P.NE:0] CvtCe, // the calculated expoent - Cvt
|
||||
input logic [1:0] CvtNegResMsbs, // the negitive integer result's most significant bits
|
||||
input logic [1:0] CvtNegResMsbs, // the negitive integer result's most significant bits
|
||||
// divsqrt
|
||||
input logic DivOp, // conversion opperation?
|
||||
input logic Sqrt, // Sqrt?
|
||||
input logic DivOp, // conversion opperation?
|
||||
input logic Sqrt, // Sqrt?
|
||||
// fma
|
||||
input logic FmaOp, // Fma opperation?
|
||||
input logic FmaAs, FmaPs, // the product and modified Z signs
|
||||
input logic FmaOp, // Fma opperation?
|
||||
input logic FmaAs, FmaPs, // the product and modified Z signs
|
||||
// flags
|
||||
output logic DivByZero, // divide by zero flag
|
||||
output logic Overflow, // overflow flag to select result
|
||||
output logic Invalid, // invalid flag to select the result
|
||||
output logic IntInvalid, // invalid integer result to select
|
||||
output logic [4:0] PostProcFlg // flags
|
||||
output logic DivByZero, // divide by zero flag
|
||||
output logic Overflow, // overflow flag to select result
|
||||
output logic Invalid, // invalid flag to select the result
|
||||
output logic IntInvalid, // invalid integer result to select
|
||||
output logic [4:0] PostProcFlg // flags
|
||||
);
|
||||
|
||||
logic SigNaN; // is an input a signaling NaN
|
||||
logic Inexact; // final inexact flag
|
||||
logic FpInexact; // floating point inexact flag
|
||||
logic IntInexact; // integer inexact flag
|
||||
logic FmaInvalid; // integer invalid flag
|
||||
logic DivInvalid; // integer invalid flag
|
||||
logic Underflow; // Underflow flag
|
||||
logic ResExpGteMax; // is the result greater than or equal to the maximum floating point expoent
|
||||
logic ShiftGtIntSz; // is the shift greater than the the integer size (use Re to account for possible roundning "shift")
|
||||
logic SigNaN; // is an input a signaling NaN
|
||||
logic Inexact; // final inexact flag
|
||||
logic FpInexact; // floating point inexact flag
|
||||
logic IntInexact; // integer inexact flag
|
||||
logic FmaInvalid; // integer invalid flag
|
||||
logic DivInvalid; // integer invalid flag
|
||||
logic Underflow; // Underflow flag
|
||||
logic ResExpGteMax; // is the result greater than or equal to the maximum floating point expoent
|
||||
logic ShiftGtIntSz; // is the shift greater than the the integer size (use Re to account for possible roundning "shift")
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Overflow
|
||||
|
@ -86,7 +86,7 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
|||
// 65 = ...0 0 0 0 0 1 0 0 0 0 0 1
|
||||
// | or | | or |
|
||||
// 33 = ...0 0 0 0 0 0 1 0 0 0 0 1
|
||||
// | or | | or |
|
||||
// | or | | or |
|
||||
// larger or equal if:
|
||||
// - any of the bits after the most significan 1 is one
|
||||
// - the most signifcant in 65 or 33 is still a one in the number and
|
||||
|
@ -102,9 +102,9 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
|||
end else if (P.FPSIZES == 3) begin
|
||||
always_comb
|
||||
case (OutFmt)
|
||||
P.FMT: ResExpGteMax = &FullRe[P.NE-1:0] | FullRe[P.NE];
|
||||
P.FMT1: ResExpGteMax = &FullRe[P.NE1-1:0] | (|FullRe[P.NE:P.NE1]);
|
||||
P.FMT2: ResExpGteMax = &FullRe[P.NE2-1:0] | (|FullRe[P.NE:P.NE2]);
|
||||
P.FMT: ResExpGteMax = &FullRe[P.NE-1:0] | FullRe[P.NE];
|
||||
P.FMT1: ResExpGteMax = &FullRe[P.NE1-1:0] | (|FullRe[P.NE:P.NE1]);
|
||||
P.FMT2: ResExpGteMax = &FullRe[P.NE2-1:0] | (|FullRe[P.NE:P.NE2]);
|
||||
default: ResExpGteMax = 1'bx;
|
||||
endcase
|
||||
assign ShiftGtIntSz = (|FullRe[P.NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64));
|
||||
|
@ -119,8 +119,7 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
|||
endcase
|
||||
assign ShiftGtIntSz = (|FullRe[P.Q_NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64));
|
||||
end
|
||||
|
||||
|
||||
|
||||
// calulate overflow flag:
|
||||
// if the result is greater than or equal to the max exponent(not taking into account sign)
|
||||
// | and the exponent isn't negitive
|
||||
|
@ -142,7 +141,6 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
|||
// | | | | | |
|
||||
assign Underflow = ((FullRe[P.NE+1] | (FullRe == 0) | ((FullRe == 1) & (Me == 0) & ~(UfPlus1&Guard)))&(Round|Sticky|Guard))&~(InfIn|NaNIn|DivByZero|Invalid);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Inexact
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -199,7 +197,6 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
|||
// - don't set flag if an input is NaN or Inf(IEEE says has to be a finite numerator)
|
||||
assign DivByZero = YZero&DivOp&~Sqrt&~(XZero|NaNIn|InfIn);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// final flags
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -209,7 +206,3 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
|||
assign PostProcFlg = {Invalid|(IntInvalid&CvtOp&ToInt), DivByZero, Overflow&~(ToInt&CvtOp), Underflow&~(ToInt&CvtOp), Inexact};
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -27,18 +27,18 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module fmashiftcalc import cvw::*; #(parameter cvw_t P) (
|
||||
input logic [P.FMTBITS-1:0] Fmt, // precision 1 = double 0 = single
|
||||
input logic [P.NE+1:0] FmaSe, // sum's exponent
|
||||
input logic [3*P.NF+3:0] FmaSm, // the positive sum
|
||||
input logic [$clog2(3*P.NF+5)-1:0] FmaSCnt, // normalization shift count
|
||||
output logic [P.NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account Subnormal or zero results
|
||||
output logic FmaSZero, // is the result subnormal - calculated before LZA corection
|
||||
output logic FmaPreResultSubnorm, // is the result subnormal - calculated before LZA corection
|
||||
output logic [$clog2(3*P.NF+5)-1:0] FmaShiftAmt, // normalization shift count
|
||||
output logic [3*P.NF+5:0] FmaShiftIn // is the sum zero
|
||||
input logic [P.FMTBITS-1:0] Fmt, // precision 1 = double 0 = single
|
||||
input logic [P.NE+1:0] FmaSe, // sum's exponent
|
||||
input logic [3*P.NF+3:0] FmaSm, // the positive sum
|
||||
input logic [$clog2(3*P.NF+5)-1:0] FmaSCnt, // normalization shift count
|
||||
output logic [P.NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account Subnormal or zero results
|
||||
output logic FmaSZero, // is the result subnormal - calculated before LZA corection
|
||||
output logic FmaPreResultSubnorm, // is the result subnormal - calculated before LZA corection
|
||||
output logic [$clog2(3*P.NF+5)-1:0] FmaShiftAmt, // normalization shift count
|
||||
output logic [3*P.NF+5:0] FmaShiftIn // is the sum zero
|
||||
);
|
||||
logic [P.NE+1:0] PreNormSumExp; // the exponent of the normalized sum with the P.FLEN bias
|
||||
logic [P.NE+1:0] BiasCorr; // correction for bias
|
||||
logic [P.NE+1:0] PreNormSumExp; // the exponent of the normalized sum with the P.FLEN bias
|
||||
logic [P.NE+1:0] BiasCorr; // correction for bias
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Normalization
|
||||
|
@ -59,9 +59,9 @@ module fmashiftcalc import cvw::*; #(parameter cvw_t P) (
|
|||
end else if (P.FPSIZES == 3) begin
|
||||
always_comb begin
|
||||
case (Fmt)
|
||||
P.FMT: BiasCorr = '0;
|
||||
P.FMT1: BiasCorr = (P.NE+2)'(P.BIAS1-P.BIAS);
|
||||
P.FMT2: BiasCorr = (P.NE+2)'(P.BIAS2-P.BIAS);
|
||||
P.FMT: BiasCorr = '0;
|
||||
P.FMT1: BiasCorr = (P.NE+2)'(P.BIAS1-P.BIAS);
|
||||
P.FMT2: BiasCorr = (P.NE+2)'(P.BIAS2-P.BIAS);
|
||||
default: BiasCorr = 'x;
|
||||
endcase
|
||||
end
|
||||
|
@ -101,9 +101,9 @@ module fmashiftcalc import cvw::*; #(parameter cvw_t P) (
|
|||
assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF2-2+P.BIAS-P.BIAS2)) | ~|PreNormSumExp;
|
||||
always_comb begin
|
||||
case (Fmt)
|
||||
P.FMT: FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero;
|
||||
P.FMT1: FmaPreResultSubnorm = Sum1LEZ & Sum1GEFL & ~FmaSZero;
|
||||
P.FMT2: FmaPreResultSubnorm = Sum2LEZ & Sum2GEFL & ~FmaSZero;
|
||||
P.FMT: FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero;
|
||||
P.FMT1: FmaPreResultSubnorm = Sum1LEZ & Sum1GEFL & ~FmaSZero;
|
||||
P.FMT2: FmaPreResultSubnorm = Sum2LEZ & Sum2GEFL & ~FmaSZero;
|
||||
default: FmaPreResultSubnorm = 1'bx;
|
||||
endcase
|
||||
end
|
||||
|
@ -131,5 +131,5 @@ module fmashiftcalc import cvw::*; #(parameter cvw_t P) (
|
|||
// - shift once if killing a product and the result is subnormal
|
||||
assign FmaShiftIn = {2'b0, FmaSm};
|
||||
if (P.FPSIZES == 1) assign FmaShiftAmt = FmaPreResultSubnorm ? FmaSe[$clog2(3*P.NF+5)-1:0]+($clog2(3*P.NF+5))'(P.NF+2): FmaSCnt+1;
|
||||
else assign FmaShiftAmt = FmaPreResultSubnorm ? FmaSe[$clog2(3*P.NF+5)-1:0]+($clog2(3*P.NF+5))'(P.NF+2)+BiasCorr[$clog2(3*P.NF+5)-1:0]: FmaSCnt+1;
|
||||
else assign FmaShiftAmt = FmaPreResultSubnorm ? FmaSe[$clog2(3*P.NF+5)-1:0]+($clog2(3*P.NF+5))'(P.NF+2)+BiasCorr[$clog2(3*P.NF+5)-1:0]: FmaSCnt+1;
|
||||
endmodule
|
||||
|
|
|
@ -27,20 +27,20 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module negateintres import cvw::*; #(parameter cvw_t P) (
|
||||
input logic Signed, // is the integer input signed
|
||||
input logic Int64, // is the integer input 64-bits
|
||||
input logic Plus1, // should one be added for rounding?
|
||||
input logic Xs, // X sign
|
||||
input logic Signed, // is the integer input signed
|
||||
input logic Int64, // is the integer input 64-bits
|
||||
input logic Plus1, // should one be added for rounding?
|
||||
input logic Xs, // X sign
|
||||
input logic [P.NORMSHIFTSZ-1:0] Shifted, // output from normalization shifter
|
||||
output logic [1:0] CvtNegResMsbs, // most signigficant bits of possibly negated result
|
||||
output logic [1:0] CvtNegResMsbs, // most signigficant bits of possibly negated result
|
||||
output logic [P.XLEN+1:0] CvtNegRes // possibly negated integer result
|
||||
);
|
||||
|
||||
logic [P.XLEN+1:0] CvtPreRes; // integer result with rounding
|
||||
logic [2:0] CvtNegResMsbs3; // first three msbs of possibly negated result
|
||||
logic [2:0] CvtNegResMsbs3; // first three msbs of possibly negated result
|
||||
|
||||
// round and negate the positive res if needed
|
||||
assign CvtPreRes = {2'b0, Shifted[P.NORMSHIFTSZ-1:P.NORMSHIFTSZ-P.XLEN]}+{{P.XLEN+1{1'b0}}, Plus1};
|
||||
assign CvtPreRes = {2'b0, Shifted[P.NORMSHIFTSZ-1:P.NORMSHIFTSZ-P.XLEN]}+{{P.XLEN+1{1'b0}}, Plus1};
|
||||
mux2 #(P.XLEN+2) resmux(CvtPreRes, -CvtPreRes, Xs, CvtNegRes);
|
||||
|
||||
// select 2 most significant bits
|
||||
|
|
|
@ -27,47 +27,47 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// convert shift
|
||||
// fp -> int: | `XLEN zeros | Mantissa | 0's if nessisary | << CalcExp
|
||||
// fp -> int: | `XLEN zeros | Mantissa | 0's if necessary | << CalcExp
|
||||
// process:
|
||||
// - start - CalcExp = 1 + XExp - Largest Bias
|
||||
// | `XLEN zeros | Mantissa | 0's if nessisary |
|
||||
// | `XLEN zeros | Mantissa | 0's if necessary |
|
||||
//
|
||||
// - shift left 1 (1)
|
||||
// | `XLEN-1 zeros |bit| frac | 0's if nessisary |
|
||||
// | `XLEN-1 zeros |bit| frac | 0's if necessary |
|
||||
// . <- binary point
|
||||
//
|
||||
// - shift left till unbiased exponent is 0 (XExp - Largest Bias)
|
||||
// | 0's | Mantissa | 0's if nessisary |
|
||||
// | 0's | Mantissa | 0's if necessary |
|
||||
// | keep |
|
||||
//
|
||||
// fp -> fp:
|
||||
// - if result is subnormal or underflowed:
|
||||
// | `NF-1 zeros | Mantissa | 0's if nessisary | << NF+CalcExp-1
|
||||
// | `NF-1 zeros | Mantissa | 0's if necessary | << NF+CalcExp-1
|
||||
// process:
|
||||
// - start
|
||||
// | mantissa | 0's |
|
||||
//
|
||||
// - shift right by NF-1 (NF-1)
|
||||
// | `NF-1 zeros | mantissa | 0's |
|
||||
// | `NF-1 zeros | mantissa | 0's |
|
||||
//
|
||||
// - shift left by CalcExp = XExp - Largest bias + new bias
|
||||
// | 0's | mantissa | 0's |
|
||||
// | keep |
|
||||
//
|
||||
// - if the input is subnormal:
|
||||
// | lzcIn | 0's if nessisary | << ZeroCnt+1
|
||||
// | lzcIn | 0's if necessary | << ZeroCnt+1
|
||||
// - plus 1 to shift out the first 1
|
||||
//
|
||||
// int -> fp: | lzcIn | 0's if nessisary | << ZeroCnt+1
|
||||
// int -> fp: | lzcIn | 0's if necessary | << ZeroCnt+1
|
||||
// - plus 1 to shift out the first 1
|
||||
|
||||
// fma shift
|
||||
// | 00 | Sm | << LZA output
|
||||
// | 00 | Sm | << LZA output
|
||||
// .
|
||||
// - two extra bits so we can correct for an LZA error of 1 or 2
|
||||
|
||||
// divsqrt shift
|
||||
// | Nf 0's | Qm | << calculated shift amount
|
||||
// | Nf 0's | Qm | << calculated shift amount
|
||||
// .
|
||||
|
||||
module normshift import cvw::*; #(parameter cvw_t P) (
|
||||
|
|
|
@ -28,100 +28,100 @@
|
|||
|
||||
module postprocess import cvw::*; #(parameter cvw_t P) (
|
||||
// general signals
|
||||
input logic Xs, Ys, // input signs
|
||||
input logic [P.NF:0] Xm, Ym, Zm, // input mantissas
|
||||
input logic [2:0] Frm, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
|
||||
input logic [P.FMTBITS-1:0] Fmt, // precision 1 = double 0 = single
|
||||
input logic [2:0] OpCtrl, // choose which opperation (look below for values)
|
||||
input logic XZero, YZero, // inputs are zero
|
||||
input logic XInf, YInf, ZInf, // inputs are infinity
|
||||
input logic XNaN, YNaN, ZNaN, // inputs are NaN
|
||||
input logic XSNaN, YSNaN, ZSNaN, // inputs are signaling NaNs
|
||||
input logic [1:0] PostProcSel, // select result to be written to fp register
|
||||
input logic Xs, Ys, // input signs
|
||||
input logic [P.NF:0] Xm, Ym, Zm, // input mantissas
|
||||
input logic [2:0] Frm, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
|
||||
input logic [P.FMTBITS-1:0] Fmt, // precision 1 = double 0 = single
|
||||
input logic [2:0] OpCtrl, // choose which opperation (look below for values)
|
||||
input logic XZero, YZero, // inputs are zero
|
||||
input logic XInf, YInf, ZInf, // inputs are infinity
|
||||
input logic XNaN, YNaN, ZNaN, // inputs are NaN
|
||||
input logic XSNaN, YSNaN, ZSNaN, // inputs are signaling NaNs
|
||||
input logic [1:0] PostProcSel, // select result to be written to fp register
|
||||
//fma signals
|
||||
input logic FmaAs, // the modified Z sign - depends on instruction
|
||||
input logic FmaPs, // the product's sign
|
||||
input logic FmaSs, // Sum sign
|
||||
input logic [P.NE+1:0] FmaSe, // the sum's exponent
|
||||
input logic [3*P.NF+3:0] FmaSm, // the positive sum
|
||||
input logic FmaASticky, // sticky bit that is calculated during alignment
|
||||
input logic [$clog2(3*P.NF+5)-1:0] FmaSCnt, // the normalization shift count
|
||||
input logic FmaAs, // the modified Z sign - depends on instruction
|
||||
input logic FmaPs, // the product's sign
|
||||
input logic FmaSs, // Sum sign
|
||||
input logic [P.NE+1:0] FmaSe, // the sum's exponent
|
||||
input logic [3*P.NF+3:0] FmaSm, // the positive sum
|
||||
input logic FmaASticky, // sticky bit that is calculated during alignment
|
||||
input logic [$clog2(3*P.NF+5)-1:0] FmaSCnt, // the normalization shift count
|
||||
//divide signals
|
||||
input logic DivSticky, // divider sticky bit
|
||||
input logic [P.NE+1:0] DivQe, // divsqrt exponent
|
||||
input logic [P.DIVb:0] DivQm, // divsqrt significand
|
||||
input logic DivSticky, // divider sticky bit
|
||||
input logic [P.NE+1:0] DivQe, // divsqrt exponent
|
||||
input logic [P.DIVb:0] DivQm, // divsqrt significand
|
||||
// conversion signals
|
||||
input logic CvtCs, // the result's sign
|
||||
input logic [P.NE:0] CvtCe, // the calculated expoent
|
||||
input logic CvtResSubnormUf, // the convert result is subnormal or underflows
|
||||
input logic [P.LOGCVTLEN-1:0] CvtShiftAmt,// how much to shift by
|
||||
input logic ToInt, // is fp->int (since it's writting to the integer register)
|
||||
input logic [P.CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb)
|
||||
input logic IntZero, // is the integer input zero
|
||||
input logic CvtCs, // the result's sign
|
||||
input logic [P.NE:0] CvtCe, // the calculated expoent
|
||||
input logic CvtResSubnormUf, // the convert result is subnormal or underflows
|
||||
input logic [P.LOGCVTLEN-1:0] CvtShiftAmt, // how much to shift by
|
||||
input logic ToInt, // is fp->int (since it's writting to the integer register)
|
||||
input logic [P.CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb)
|
||||
input logic IntZero, // is the integer input zero
|
||||
// final results
|
||||
output logic [P.FLEN-1:0] PostProcRes,// postprocessor final result
|
||||
output logic [4:0] PostProcFlg,// postprocesser flags
|
||||
output logic [P.XLEN-1:0] FCvtIntRes // the integer conversion result
|
||||
output logic [P.FLEN-1:0] PostProcRes, // postprocessor final result
|
||||
output logic [4:0] PostProcFlg, // postprocesser flags
|
||||
output logic [P.XLEN-1:0] FCvtIntRes // the integer conversion result
|
||||
);
|
||||
|
||||
// general signals
|
||||
logic Rs; // result sign
|
||||
logic [P.NF-1:0] Rf; // Result fraction
|
||||
logic [P.NE-1:0] Re; // Result exponent
|
||||
logic Ms; // norMalized sign
|
||||
logic [P.CORRSHIFTSZ-1:0] Mf; // norMalized fraction
|
||||
logic [P.NE+1:0] Me; // normalized exponent
|
||||
logic [P.NE+1:0] FullRe; // Re with bits to determine sign and overflow
|
||||
logic UfPlus1; // do you add one (for determining underflow flag)
|
||||
logic [P.LOGNORMSHIFTSZ-1:0] ShiftAmt; // normalization shift amount
|
||||
logic [P.NORMSHIFTSZ-1:0] ShiftIn; // input to normalization shift
|
||||
logic [P.NORMSHIFTSZ-1:0] Shifted; // the ouput of the normalized shifter (before shift correction)
|
||||
logic Plus1; // add one to the final result?
|
||||
logic Overflow; // overflow flag used to select results
|
||||
logic Invalid; // invalid flag used to select results
|
||||
logic Guard, Round, Sticky; // bits needed to determine rounding
|
||||
logic [P.FMTBITS-1:0] OutFmt; // output format
|
||||
logic Rs; // result sign
|
||||
logic [P.NF-1:0] Rf; // Result fraction
|
||||
logic [P.NE-1:0] Re; // Result exponent
|
||||
logic Ms; // norMalized sign
|
||||
logic [P.CORRSHIFTSZ-1:0] Mf; // norMalized fraction
|
||||
logic [P.NE+1:0] Me; // normalized exponent
|
||||
logic [P.NE+1:0] FullRe; // Re with bits to determine sign and overflow
|
||||
logic UfPlus1; // do you add one (for determining underflow flag)
|
||||
logic [P.LOGNORMSHIFTSZ-1:0] ShiftAmt; // normalization shift amount
|
||||
logic [P.NORMSHIFTSZ-1:0] ShiftIn; // input to normalization shift
|
||||
logic [P.NORMSHIFTSZ-1:0] Shifted; // the ouput of the normalized shifter (before shift correction)
|
||||
logic Plus1; // add one to the final result?
|
||||
logic Overflow; // overflow flag used to select results
|
||||
logic Invalid; // invalid flag used to select results
|
||||
logic Guard, Round, Sticky; // bits needed to determine rounding
|
||||
logic [P.FMTBITS-1:0] OutFmt; // output format
|
||||
// fma signals
|
||||
logic [P.NE+1:0] FmaMe; // exponent of the normalized sum
|
||||
logic FmaSZero; // is the sum zero
|
||||
logic [3*P.NF+5:0] FmaShiftIn; // fma shift input
|
||||
logic [P.NE+1:0] NormSumExp; // exponent of the normalized sum not taking into account Subnormal or zero results
|
||||
logic FmaPreResultSubnorm; // is the result subnormal - calculated before LZA corection
|
||||
logic [$clog2(3*P.NF+5)-1:0] FmaShiftAmt;// normalization shift amount for fma
|
||||
logic [P.NE+1:0] FmaMe; // exponent of the normalized sum
|
||||
logic FmaSZero; // is the sum zero
|
||||
logic [3*P.NF+5:0] FmaShiftIn; // fma shift input
|
||||
logic [P.NE+1:0] NormSumExp; // exponent of the normalized sum not taking into account Subnormal or zero results
|
||||
logic FmaPreResultSubnorm; // is the result subnormal - calculated before LZA corection
|
||||
logic [$clog2(3*P.NF+5)-1:0] FmaShiftAmt; // normalization shift amount for fma
|
||||
// division singals
|
||||
logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shif amount
|
||||
logic [P.NORMSHIFTSZ-1:0] DivShiftIn; // divsqrt shift input
|
||||
logic [P.NE+1:0] Qe; // divsqrt corrected exponent after corretion shift
|
||||
logic DivByZero; // divide by zero flag
|
||||
logic DivResSubnorm; // is the divsqrt result subnormal
|
||||
logic DivSubnormShiftPos; // is the divsqrt subnorm shift amout positive (not underflowed)
|
||||
logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shif amount
|
||||
logic [P.NORMSHIFTSZ-1:0] DivShiftIn; // divsqrt shift input
|
||||
logic [P.NE+1:0] Qe; // divsqrt corrected exponent after corretion shift
|
||||
logic DivByZero; // divide by zero flag
|
||||
logic DivResSubnorm; // is the divsqrt result subnormal
|
||||
logic DivSubnormShiftPos; // is the divsqrt subnorm shift amout positive (not underflowed)
|
||||
// conversion signals
|
||||
logic [P.CVTLEN+P.NF:0] CvtShiftIn; // number to be shifted for converter
|
||||
logic [1:0] CvtNegResMsbs; // most significant bits of possibly negated int result
|
||||
logic [P.XLEN+1:0] CvtNegRes; // possibly negated integer result
|
||||
logic CvtResUf; // did the convert result underflow
|
||||
logic IntInvalid; // invalid integer flag
|
||||
logic [P.CVTLEN+P.NF:0] CvtShiftIn; // number to be shifted for converter
|
||||
logic [1:0] CvtNegResMsbs; // most significant bits of possibly negated int result
|
||||
logic [P.XLEN+1:0] CvtNegRes; // possibly negated integer result
|
||||
logic CvtResUf; // did the convert result underflow
|
||||
logic IntInvalid; // invalid integer flag
|
||||
// readability signals
|
||||
logic Mult; // multiply opperation
|
||||
logic Sqrt; // is the divsqrt opperation sqrt
|
||||
logic Int64; // is the integer 64 bits?
|
||||
logic Signed; // is the opperation with a signed integer?
|
||||
logic IntToFp; // is the opperation an int->fp conversion?
|
||||
logic CvtOp; // convertion opperation
|
||||
logic FmaOp; // fma opperation
|
||||
logic DivOp; // divider opperation
|
||||
logic InfIn; // are any of the inputs infinity
|
||||
logic NaNIn; // are any of the inputs NaN
|
||||
logic Mult; // multiply opperation
|
||||
logic Sqrt; // is the divsqrt opperation sqrt
|
||||
logic Int64; // is the integer 64 bits?
|
||||
logic Signed; // is the opperation with a signed integer?
|
||||
logic IntToFp; // is the opperation an int->fp conversion?
|
||||
logic CvtOp; // convertion opperation
|
||||
logic FmaOp; // fma opperation
|
||||
logic DivOp; // divider opperation
|
||||
logic InfIn; // are any of the inputs infinity
|
||||
logic NaNIn; // are any of the inputs NaN
|
||||
|
||||
// signals to help readability
|
||||
assign Signed = OpCtrl[0];
|
||||
assign Int64 = OpCtrl[1];
|
||||
assign Signed = OpCtrl[0];
|
||||
assign Int64 = OpCtrl[1];
|
||||
assign IntToFp = OpCtrl[2];
|
||||
assign Mult = OpCtrl[2]&~OpCtrl[1]&~OpCtrl[0];
|
||||
assign CvtOp = (PostProcSel == 2'b00);
|
||||
assign FmaOp = (PostProcSel == 2'b10);
|
||||
assign DivOp = (PostProcSel == 2'b01);
|
||||
assign Sqrt = OpCtrl[0];
|
||||
assign Mult = OpCtrl[2]&~OpCtrl[1]&~OpCtrl[0];
|
||||
assign CvtOp = (PostProcSel == 2'b00);
|
||||
assign FmaOp = (PostProcSel == 2'b10);
|
||||
assign DivOp = (PostProcSel == 2'b01);
|
||||
assign Sqrt = OpCtrl[0];
|
||||
|
||||
// is there an input of infinity or NaN being used
|
||||
assign InfIn = XInf|YInf|ZInf;
|
||||
|
@ -153,19 +153,19 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
|
|||
case(PostProcSel)
|
||||
2'b10: begin // fma
|
||||
ShiftAmt = {{P.LOGNORMSHIFTSZ-$clog2(3*P.NF+5){1'b0}}, FmaShiftAmt};
|
||||
ShiftIn = {FmaShiftIn, {P.NORMSHIFTSZ-(3*P.NF+6){1'b0}}};
|
||||
ShiftIn = {FmaShiftIn, {P.NORMSHIFTSZ-(3*P.NF+6){1'b0}}};
|
||||
end
|
||||
2'b00: begin // cvt
|
||||
ShiftAmt = {{P.LOGNORMSHIFTSZ-$clog2(P.CVTLEN+1){1'b0}}, CvtShiftAmt};
|
||||
ShiftIn = {CvtShiftIn, {P.NORMSHIFTSZ-P.CVTLEN-P.NF-1{1'b0}}};
|
||||
ShiftIn = {CvtShiftIn, {P.NORMSHIFTSZ-P.CVTLEN-P.NF-1{1'b0}}};
|
||||
end
|
||||
2'b01: begin //divsqrt
|
||||
ShiftAmt = DivShiftAmt;
|
||||
ShiftIn = DivShiftIn;
|
||||
ShiftIn = DivShiftIn;
|
||||
end
|
||||
default: begin
|
||||
ShiftAmt = {P.LOGNORMSHIFTSZ{1'bx}};
|
||||
ShiftIn = {P.NORMSHIFTSZ{1'bx}};
|
||||
ShiftIn = {P.NORMSHIFTSZ{1'bx}};
|
||||
end
|
||||
endcase
|
||||
|
||||
|
|
|
@ -28,46 +28,46 @@
|
|||
|
||||
module round import cvw::*; #(parameter cvw_t P) (
|
||||
input logic [P.FMTBITS-1:0] OutFmt, // output format
|
||||
input logic [2:0] Frm, // rounding mode
|
||||
input logic [1:0] PostProcSel, // select the postprocessor output
|
||||
input logic Ms, // normalized sign
|
||||
input logic [2:0] Frm, // rounding mode
|
||||
input logic [1:0] PostProcSel, // select the postprocessor output
|
||||
input logic Ms, // normalized sign
|
||||
input logic [P.CORRSHIFTSZ-1:0] Mf, // normalized fraction
|
||||
// fma
|
||||
input logic FmaOp, // is an fma opperation being done?
|
||||
input logic FmaOp, // is an fma opperation being done?
|
||||
input logic [P.NE+1:0] FmaMe, // exponent of the normalized sum for fma
|
||||
input logic FmaASticky, // addend's sticky bit
|
||||
input logic FmaASticky, // addend's sticky bit
|
||||
// divsqrt
|
||||
input logic DivOp, // is a division opperation being done
|
||||
input logic DivSticky, // divsqrt sticky bit
|
||||
input logic DivOp, // is a division opperation being done
|
||||
input logic DivSticky, // divsqrt sticky bit
|
||||
input logic [P.NE+1:0] Qe, // the divsqrt calculated expoent
|
||||
// cvt
|
||||
input logic CvtOp, // is a convert opperation being done
|
||||
input logic ToInt, // is the cvt op a cvt to integer
|
||||
input logic CvtResSubnormUf, // is the cvt result subnormal or underflow
|
||||
input logic CvtResUf, // does the cvt result underflow
|
||||
input logic CvtOp, // is a convert opperation being done
|
||||
input logic ToInt, // is the cvt op a cvt to integer
|
||||
input logic CvtResSubnormUf, // is the cvt result subnormal or underflow
|
||||
input logic CvtResUf, // does the cvt result underflow
|
||||
input logic [P.NE:0] CvtCe, // the cvt calculated expoent
|
||||
// outputs
|
||||
output logic [P.NE+1:0] Me, // normalied fraction
|
||||
output logic UfPlus1, // do you add one to the result if given an unbounded exponent
|
||||
output logic UfPlus1, // do you add one to the result if given an unbounded exponent
|
||||
output logic [P.NE+1:0] FullRe, // Re with bits to determine sign and overflow
|
||||
output logic [P.NE-1:0] Re, // Result exponent
|
||||
output logic [P.NF-1:0] Rf, // Result fractionNormS
|
||||
output logic Sticky, // sticky bit
|
||||
output logic Plus1, // do you add one to the final result
|
||||
output logic Round, Guard // bits needed to calculate rounding
|
||||
output logic Sticky, // sticky bit
|
||||
output logic Plus1, // do you add one to the final result
|
||||
output logic Round, Guard // bits needed to calculate rounding
|
||||
);
|
||||
|
||||
logic UfCalcPlus1; // calculated plus one for unbounded exponent
|
||||
logic NormSticky; // normalized sum's sticky bit
|
||||
logic [P.NF-1:0] RoundFrac; // rounded fraction
|
||||
logic FpRes; // is the result a floating point
|
||||
logic IntRes; // is the result an integer
|
||||
logic FpGuard, FpRound; // floating point round/guard bits
|
||||
logic FpLsbRes; // least significant bit of floating point result
|
||||
logic LsbRes; // lsb of result
|
||||
logic CalcPlus1; // calculated plus1
|
||||
logic FpPlus1; // do you add one to the fp result
|
||||
logic [P.FLEN:0] RoundAdd; // how much to add to the result
|
||||
logic UfCalcPlus1; // calculated plus one for unbounded exponent
|
||||
logic NormSticky; // normalized sum's sticky bit
|
||||
logic [P.NF-1:0] RoundFrac; // rounded fraction
|
||||
logic FpRes; // is the result a floating point
|
||||
logic IntRes; // is the result an integer
|
||||
logic FpGuard, FpRound; // floating point round/guard bits
|
||||
logic FpLsbRes; // least significant bit of floating point result
|
||||
logic LsbRes; // lsb of result
|
||||
logic CalcPlus1; // calculated plus1
|
||||
logic FpPlus1; // do you add one to the fp result
|
||||
logic [P.FLEN:0] RoundAdd; // how much to add to the result
|
||||
|
||||
// what position is XLEN in?
|
||||
// options:
|
||||
|
@ -86,7 +86,7 @@ module round import cvw::*; #(parameter cvw_t P) (
|
|||
// {Round, Sticky}
|
||||
// 0x - do nothing
|
||||
// 10 - tie - Plus1 if result is odd (LSBNormSum = 1)
|
||||
// - don't add 1 if a small number was supposed to be subtracted
|
||||
// - don't add 1 if a small number was supposed to be subtracted
|
||||
// 11 - do nothing if a small number was supposed to subtracted (the sticky bit was set by the small number)
|
||||
// - plus 1 otherwise
|
||||
|
||||
|
@ -104,14 +104,13 @@ module round import cvw::*; #(parameter cvw_t P) (
|
|||
// {Guard, Round, Sticky}
|
||||
// 0x - do nothing
|
||||
// 10 - tie - Plus1
|
||||
// - don't add 1 if a small number was supposed to be subtracted
|
||||
// - don't add 1 if a small number was supposed to be subtracted
|
||||
// 11 - do nothing if a small number was supposed to subtracted (the sticky bit was set by the small number)
|
||||
// - Plus 1 otherwise
|
||||
|
||||
|
||||
// determine what format the final result is in: int or fp
|
||||
assign IntRes = ToInt;
|
||||
assign FpRes = ~IntRes;
|
||||
assign FpRes = ~IntRes;
|
||||
|
||||
// sticky bit calculation
|
||||
if (P.FPSIZES == 1) begin
|
||||
|
@ -121,7 +120,7 @@ module round import cvw::*; #(parameter cvw_t P) (
|
|||
// | NF |1|1|
|
||||
// ^ ^ if floating point result
|
||||
// ^ if not an FMA result
|
||||
if (XLENPOS == 1)assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes) |
|
||||
if (XLENPOS == 1)assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.XLEN-2:0]);
|
||||
// 2: NF > XLEN
|
||||
if (XLENPOS == 2)assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.NF-1]&IntRes) |
|
||||
|
@ -178,113 +177,104 @@ module round import cvw::*; #(parameter cvw_t P) (
|
|||
(|Mf[P.CORRSHIFTSZ-P.Q_NF-2:0]);
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
// only add the Addend sticky if doing an FMA opperation
|
||||
// - the shifter shifts too far left when there's an underflow (shifting out all possible sticky bits)
|
||||
assign Sticky = FmaASticky&FmaOp | NormSticky | CvtResUf&CvtOp | FmaMe[P.NE+1]&FmaOp | DivSticky&DivOp;
|
||||
|
||||
|
||||
|
||||
|
||||
// determine round and LSB of the rounded value
|
||||
// - underflow round bit is used to determint the underflow flag
|
||||
if (P.FPSIZES == 1) begin
|
||||
assign FpGuard = Mf[P.CORRSHIFTSZ-P.NF-1];
|
||||
assign FpGuard = Mf[P.CORRSHIFTSZ-P.NF-1];
|
||||
assign FpLsbRes = Mf[P.CORRSHIFTSZ-P.NF];
|
||||
assign FpRound = Mf[P.CORRSHIFTSZ-P.NF-2];
|
||||
assign FpRound = Mf[P.CORRSHIFTSZ-P.NF-2];
|
||||
|
||||
end else if (P.FPSIZES == 2) begin
|
||||
assign FpGuard = OutFmt ? Mf[P.CORRSHIFTSZ-P.NF-1] : Mf[P.CORRSHIFTSZ-P.NF1-1];
|
||||
assign FpGuard = OutFmt ? Mf[P.CORRSHIFTSZ-P.NF-1] : Mf[P.CORRSHIFTSZ-P.NF1-1];
|
||||
assign FpLsbRes = OutFmt ? Mf[P.CORRSHIFTSZ-P.NF] : Mf[P.CORRSHIFTSZ-P.NF1];
|
||||
assign FpRound = OutFmt ? Mf[P.CORRSHIFTSZ-P.NF-2] : Mf[P.CORRSHIFTSZ-P.NF1-2];
|
||||
assign FpRound = OutFmt ? Mf[P.CORRSHIFTSZ-P.NF-2] : Mf[P.CORRSHIFTSZ-P.NF1-2];
|
||||
|
||||
end else if (P.FPSIZES == 3) begin
|
||||
always_comb
|
||||
case (OutFmt)
|
||||
P.FMT: begin
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.NF-1];
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.NF-1];
|
||||
FpLsbRes = Mf[P.CORRSHIFTSZ-P.NF];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.NF-2];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.NF-2];
|
||||
end
|
||||
P.FMT1: begin
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.NF1-1];
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.NF1-1];
|
||||
FpLsbRes = Mf[P.CORRSHIFTSZ-P.NF1];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.NF1-2];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.NF1-2];
|
||||
end
|
||||
P.FMT2: begin
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.NF2-1];
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.NF2-1];
|
||||
FpLsbRes = Mf[P.CORRSHIFTSZ-P.NF2];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.NF2-2];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.NF2-2];
|
||||
end
|
||||
default: begin
|
||||
FpGuard = 1'bx;
|
||||
FpGuard = 1'bx;
|
||||
FpLsbRes = 1'bx;
|
||||
FpRound = 1'bx;
|
||||
FpRound = 1'bx;
|
||||
end
|
||||
endcase
|
||||
end else if (P.FPSIZES == 4) begin
|
||||
always_comb
|
||||
case (OutFmt)
|
||||
2'h3: begin
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.Q_NF-1];
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.Q_NF-1];
|
||||
FpLsbRes = Mf[P.CORRSHIFTSZ-P.Q_NF];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.Q_NF-2];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.Q_NF-2];
|
||||
end
|
||||
2'h1: begin
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.D_NF-1];
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.D_NF-1];
|
||||
FpLsbRes = Mf[P.CORRSHIFTSZ-P.D_NF];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.D_NF-2];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.D_NF-2];
|
||||
end
|
||||
2'h0: begin
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.S_NF-1];
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.S_NF-1];
|
||||
FpLsbRes = Mf[P.CORRSHIFTSZ-P.S_NF];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.S_NF-2];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.S_NF-2];
|
||||
end
|
||||
2'h2: begin
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.H_NF-1];
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.H_NF-1];
|
||||
FpLsbRes = Mf[P.CORRSHIFTSZ-P.H_NF];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.H_NF-2];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.H_NF-2];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
assign Guard = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN-1] : FpGuard;
|
||||
assign Guard = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN-1] : FpGuard;
|
||||
assign LsbRes = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN] : FpLsbRes;
|
||||
assign Round = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN-2] : FpRound;
|
||||
|
||||
assign Round = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN-2] : FpRound;
|
||||
|
||||
always_comb begin
|
||||
// Determine if you add 1
|
||||
case (Frm)
|
||||
3'b000: CalcPlus1 = Guard & (Round|Sticky|LsbRes);//round to nearest even
|
||||
3'b001: CalcPlus1 = 0;//round to zero
|
||||
3'b010: CalcPlus1 = Ms;//round down
|
||||
3'b011: CalcPlus1 = ~Ms;//round up
|
||||
3'b100: CalcPlus1 = Guard;//round to nearest max magnitude
|
||||
3'b000: CalcPlus1 = Guard & (Round|Sticky|LsbRes);//round to nearest even
|
||||
3'b001: CalcPlus1 = 0;//round to zero
|
||||
3'b010: CalcPlus1 = Ms;//round down
|
||||
3'b011: CalcPlus1 = ~Ms;//round up
|
||||
3'b100: CalcPlus1 = Guard;//round to nearest max magnitude
|
||||
default: CalcPlus1 = 1'bx;
|
||||
endcase
|
||||
// Determine if you add 1 (for underflow flag)
|
||||
case (Frm)
|
||||
3'b000: UfCalcPlus1 = Round & (Sticky|Guard);//round to nearest even
|
||||
3'b001: UfCalcPlus1 = 0;//round to zero
|
||||
3'b010: UfCalcPlus1 = Ms;//round down
|
||||
3'b011: UfCalcPlus1 = ~Ms;//round up
|
||||
3'b100: UfCalcPlus1 = Round;//round to nearest max magnitude
|
||||
3'b000: UfCalcPlus1 = Round & (Sticky|Guard);//round to nearest even
|
||||
3'b001: UfCalcPlus1 = 0;//round to zero
|
||||
3'b010: UfCalcPlus1 = Ms;//round down
|
||||
3'b011: UfCalcPlus1 = ~Ms;//round up
|
||||
3'b100: UfCalcPlus1 = Round;//round to nearest max magnitude
|
||||
default: UfCalcPlus1 = 1'bx;
|
||||
endcase
|
||||
|
||||
end
|
||||
|
||||
// If an answer is exact don't round
|
||||
assign Plus1 = CalcPlus1 & (Sticky|Round|Guard);
|
||||
assign Plus1 = CalcPlus1 & (Sticky|Round|Guard);
|
||||
assign FpPlus1 = Plus1&~(ToInt&CvtOp);
|
||||
assign UfPlus1 = UfCalcPlus1 & (Sticky|Round);
|
||||
|
||||
|
||||
|
||||
|
||||
// place Plus1 into the proper position for the format
|
||||
if (P.FPSIZES == 1) begin
|
||||
assign RoundAdd = {{P.FLEN{1'b0}}, FpPlus1};
|
||||
|
@ -302,21 +292,17 @@ module round import cvw::*; #(parameter cvw_t P) (
|
|||
end else if (P.FPSIZES == 4)
|
||||
assign RoundAdd = {(P.Q_NE+1+P.H_NF)'(0), FpPlus1&(OutFmt==P.H_FMT), (P.S_NF-P.H_NF-1)'(0), FpPlus1&(OutFmt==P.S_FMT), (P.D_NF-P.S_NF-1)'(0), FpPlus1&(OutFmt==P.D_FMT), (P.Q_NF-P.D_NF-1)'(0), FpPlus1&(OutFmt==P.Q_FMT)};
|
||||
|
||||
|
||||
|
||||
// trim unneeded bits from fraction
|
||||
assign RoundFrac = Mf[P.CORRSHIFTSZ-1:P.CORRSHIFTSZ-P.NF];
|
||||
|
||||
|
||||
|
||||
// select the exponent
|
||||
always_comb
|
||||
case(PostProcSel)
|
||||
2'b10: Me = FmaMe; // fma
|
||||
2'b00: Me = {CvtCe[P.NE], CvtCe}&{P.NE+2{~CvtResSubnormUf|CvtResUf}}; // cvt
|
||||
2'b10: Me = FmaMe; // fma
|
||||
2'b00: Me = {CvtCe[P.NE], CvtCe}&{P.NE+2{~CvtResSubnormUf|CvtResUf}}; // cvt
|
||||
// 2'b01: Me = DivDone ? Qe : '0; // divide
|
||||
2'b01: Me = Qe; // divide
|
||||
default: Me = '0;
|
||||
2'b01: Me = Qe; // divide
|
||||
default: Me = '0;
|
||||
endcase
|
||||
|
||||
|
||||
|
@ -324,7 +310,6 @@ module round import cvw::*; #(parameter cvw_t P) (
|
|||
// round the result
|
||||
// - if the fraction overflows one should be added to the exponent
|
||||
assign {FullRe, Rf} = {Me, RoundFrac} + RoundAdd;
|
||||
assign Re = FullRe[P.NE-1:0];
|
||||
|
||||
assign Re = FullRe[P.NE-1:0];
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -29,41 +29,41 @@
|
|||
module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
||||
input logic [P.NORMSHIFTSZ-1:0] Shifted, // the shifted sum before LZA correction
|
||||
// divsqrt
|
||||
input logic DivOp, // is it a divsqrt opperation
|
||||
input logic DivResSubnorm, // is the divsqrt result subnormal
|
||||
input logic DivOp, // is it a divsqrt opperation
|
||||
input logic DivResSubnorm, // is the divsqrt result subnormal
|
||||
input logic [P.NE+1:0] DivQe, // the divsqrt result's exponent
|
||||
input logic DivSubnormShiftPos, // is the subnorm divider shift amount positive (ie not underflowed)
|
||||
input logic DivSubnormShiftPos, // is the subnorm divider shift amount positive (ie not underflowed)
|
||||
//fma
|
||||
input logic FmaOp, // is it an fma opperation
|
||||
input logic FmaOp, // is it an fma opperation
|
||||
input logic [P.NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account Subnormal or zero results
|
||||
input logic FmaPreResultSubnorm, // is the result subnormal - calculated before LZA corection
|
||||
input logic FmaSZero,
|
||||
input logic FmaPreResultSubnorm, // is the result subnormal - calculated before LZA corection
|
||||
input logic FmaSZero,
|
||||
// output
|
||||
output logic [P.NE+1:0] FmaMe, // exponent of the normalized sum
|
||||
output logic [P.CORRSHIFTSZ-1:0] Mf, // the shifted sum before LZA correction
|
||||
output logic [P.NE+1:0] Qe // corrected exponent for divider
|
||||
);
|
||||
|
||||
logic [3*P.NF+3:0] CorrSumShifted; // the shifted sum after LZA correction
|
||||
logic [P.CORRSHIFTSZ-1:0] CorrQm0, CorrQm1; // portions of Shifted to select for CorrQmShifted
|
||||
logic [P.CORRSHIFTSZ-1:0] CorrQmShifted; // the shifted divsqrt result after one bit shift
|
||||
logic ResSubnorm; // is the result Subnormal
|
||||
logic LZAPlus1; // add one or two to the sum's exponent due to LZA correction
|
||||
logic LeftShiftQm; // should the divsqrt result be shifted one to the left
|
||||
logic [3*P.NF+3:0] CorrSumShifted; // the shifted sum after LZA correction
|
||||
logic [P.CORRSHIFTSZ-1:0] CorrQm0, CorrQm1; // portions of Shifted to select for CorrQmShifted
|
||||
logic [P.CORRSHIFTSZ-1:0] CorrQmShifted; // the shifted divsqrt result after one bit shift
|
||||
logic ResSubnorm; // is the result Subnormal
|
||||
logic LZAPlus1; // add one or two to the sum's exponent due to LZA correction
|
||||
logic LeftShiftQm; // should the divsqrt result be shifted one to the left
|
||||
|
||||
// LZA correction
|
||||
assign LZAPlus1 = Shifted[P.NORMSHIFTSZ-1];
|
||||
|
||||
// correct the shifting error caused by the LZA
|
||||
// - the only possible mantissa for a plus two is all zeroes
|
||||
// - a one has to propigate all the way through a sum. so we can leave the bottom statement alone
|
||||
// - a one has to propigate all the way through a sum. so we can leave the bottom statement alone
|
||||
mux2 #(P.NORMSHIFTSZ-2) lzacorrmux(Shifted[P.NORMSHIFTSZ-3:0], Shifted[P.NORMSHIFTSZ-2:1], LZAPlus1, CorrSumShifted);
|
||||
|
||||
// correct the shifting of the divsqrt caused by producing a result in (2, .5] range
|
||||
// condition: if the msb is 1 or the exponent was one, but the shifted quotent was < 1 (Subnorm)
|
||||
// condition: if the msb is 1 or the exponent was one, but the shifted quotent was < 1 (Subnorm)
|
||||
assign LeftShiftQm = (LZAPlus1|(DivQe==1&~LZAPlus1));
|
||||
assign CorrQm0 = Shifted[P.NORMSHIFTSZ-3:P.NORMSHIFTSZ-P.CORRSHIFTSZ-2];
|
||||
assign CorrQm1 = Shifted[P.NORMSHIFTSZ-2:P.NORMSHIFTSZ-P.CORRSHIFTSZ-1];
|
||||
assign CorrQm0 = Shifted[P.NORMSHIFTSZ-3:P.NORMSHIFTSZ-P.CORRSHIFTSZ-2];
|
||||
assign CorrQm1 = Shifted[P.NORMSHIFTSZ-2:P.NORMSHIFTSZ-P.CORRSHIFTSZ-1];
|
||||
mux2 #(P.CORRSHIFTSZ) divcorrmux(CorrQm0, CorrQm1, LeftShiftQm, CorrQmShifted);
|
||||
|
||||
// if the result of the divider was calculated to be subnormal, then the result was correctly normalized, so select the top shifted bits
|
||||
|
|
|
@ -27,39 +27,39 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module specialcase import cvw::*; #(parameter cvw_t P) (
|
||||
input logic Xs, // X sign
|
||||
input logic [P.NF:0] Xm, Ym, Zm, // input significand's
|
||||
input logic XNaN, YNaN, ZNaN, // are the inputs NaN
|
||||
input logic [2:0] Frm, // rounding mode
|
||||
input logic [P.FMTBITS-1:0] OutFmt, // output format
|
||||
input logic InfIn, // are any inputs infinity
|
||||
input logic NaNIn, // are any input NaNs
|
||||
input logic XInf, YInf, // are X or Y inifnity
|
||||
input logic XZero, // is X zero
|
||||
input logic Plus1, // do you add one for rounding
|
||||
input logic Rs, // the result's sign
|
||||
input logic Invalid, Overflow, // flags to choose the result
|
||||
input logic [P.NE-1:0] Re, // Result exponent
|
||||
input logic [P.NE+1:0] FullRe, // Result full exponent
|
||||
input logic [P.NF-1:0] Rf, // Result fraction
|
||||
input logic Xs, // X sign
|
||||
input logic [P.NF:0] Xm, Ym, Zm, // input significand's
|
||||
input logic XNaN, YNaN, ZNaN, // are the inputs NaN
|
||||
input logic [2:0] Frm, // rounding mode
|
||||
input logic [P.FMTBITS-1:0] OutFmt, // output format
|
||||
input logic InfIn, // are any inputs infinity
|
||||
input logic NaNIn, // are any input NaNs
|
||||
input logic XInf, YInf, // are X or Y inifnity
|
||||
input logic XZero, // is X zero
|
||||
input logic Plus1, // do you add one for rounding
|
||||
input logic Rs, // the result's sign
|
||||
input logic Invalid, Overflow, // flags to choose the result
|
||||
input logic [P.NE-1:0] Re, // Result exponent
|
||||
input logic [P.NE+1:0] FullRe, // Result full exponent
|
||||
input logic [P.NF-1:0] Rf, // Result fraction
|
||||
// fma
|
||||
input logic FmaOp, // is it a fma opperation
|
||||
input logic FmaOp, // is it a fma opperation
|
||||
// divsqrt
|
||||
input logic DivOp, // is it a divsqrt opperation
|
||||
input logic DivByZero, // divide by zero flag
|
||||
input logic DivOp, // is it a divsqrt opperation
|
||||
input logic DivByZero, // divide by zero flag
|
||||
// cvt
|
||||
input logic CvtOp, // is it a conversion opperation
|
||||
input logic IntZero, // is the integer input zero
|
||||
input logic IntToFp, // is cvt int -> fp opperation
|
||||
input logic Int64, // is the integer 64 bits
|
||||
input logic Signed, // is the integer signed
|
||||
input logic [P.NE:0] CvtCe, // the calculated expoent for cvt
|
||||
input logic IntInvalid, // integer invalid flag to choose the result
|
||||
input logic CvtResUf, // does the convert result underflow
|
||||
input logic [P.XLEN+1:0] CvtNegRes, // the possibly negated of the integer result
|
||||
input logic CvtOp, // is it a conversion opperation
|
||||
input logic IntZero, // is the integer input zero
|
||||
input logic IntToFp, // is cvt int -> fp opperation
|
||||
input logic Int64, // is the integer 64 bits
|
||||
input logic Signed, // is the integer signed
|
||||
input logic [P.NE:0] CvtCe, // the calculated expoent for cvt
|
||||
input logic IntInvalid, // integer invalid flag to choose the result
|
||||
input logic CvtResUf, // does the convert result underflow
|
||||
input logic [P.XLEN+1:0] CvtNegRes, // the possibly negated of the integer result
|
||||
// outputs
|
||||
output logic [P.FLEN-1:0] PostProcRes,// final result
|
||||
output logic [P.XLEN-1:0] FCvtIntRes // final integer result
|
||||
output logic [P.FLEN-1:0] PostProcRes, // final result
|
||||
output logic [P.XLEN-1:0] FCvtIntRes // final integer result
|
||||
);
|
||||
|
||||
logic [P.FLEN-1:0] XNaNRes; // X is NaN result
|
||||
|
@ -70,9 +70,9 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
|
|||
logic [P.FLEN-1:0] OfRes; // overflowed result result
|
||||
logic [P.FLEN-1:0] NormRes; // normal result
|
||||
logic [P.XLEN-1:0] OfIntRes; // the overflow result for integer output
|
||||
logic OfResMax; // does the of result output maximum norm fp number
|
||||
logic KillRes; // kill the result for underflow
|
||||
logic SelOfRes; // should the overflow result be selected
|
||||
logic OfResMax; // does the of result output maximum norm fp number
|
||||
logic KillRes; // kill the result for underflow
|
||||
logic SelOfRes; // should the overflow result be selected
|
||||
|
||||
|
||||
// does the overflow result output the maximum normalized floating point number
|
||||
|
@ -83,23 +83,23 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
|
|||
if (P.FPSIZES == 1) begin
|
||||
//NaN res selection depending on standard
|
||||
if(P.IEEE754) begin
|
||||
assign XNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
|
||||
assign YNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Ym[P.NF-2:0]};
|
||||
assign ZNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Zm[P.NF-2:0]};
|
||||
assign XNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
|
||||
assign YNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Ym[P.NF-2:0]};
|
||||
assign ZNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Zm[P.NF-2:0]};
|
||||
assign InvalidRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
|
||||
end else begin
|
||||
assign InvalidRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
|
||||
end
|
||||
|
||||
assign OfRes = OfResMax ? {Rs, {P.NE-1{1'b1}}, 1'b0, {P.NF{1'b1}}} : {Rs, {P.NE{1'b1}}, {P.NF{1'b0}}};
|
||||
assign UfRes = {Rs, {P.FLEN-2{1'b0}}, Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
assign OfRes = OfResMax ? {Rs, {P.NE-1{1'b1}}, 1'b0, {P.NF{1'b1}}} : {Rs, {P.NE{1'b1}}, {P.NF{1'b0}}};
|
||||
assign UfRes = {Rs, {P.FLEN-2{1'b0}}, Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
assign NormRes = {Rs, Re, Rf};
|
||||
|
||||
end else if (P.FPSIZES == 2) begin
|
||||
if(P.IEEE754) begin
|
||||
assign XNaNRes = OutFmt ? {1'b0, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]} : {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.NF1]};
|
||||
assign YNaNRes = OutFmt ? {1'b0, {P.NE{1'b1}}, 1'b1, Ym[P.NF-2:0]} : {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.NF1]};
|
||||
assign ZNaNRes = OutFmt ? {1'b0, {P.NE{1'b1}}, 1'b1, Zm[P.NF-2:0]} : {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.NF1]};
|
||||
assign XNaNRes = OutFmt ? {1'b0, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]} : {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.NF1]};
|
||||
assign YNaNRes = OutFmt ? {1'b0, {P.NE{1'b1}}, 1'b1, Ym[P.NF-2:0]} : {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.NF1]};
|
||||
assign ZNaNRes = OutFmt ? {1'b0, {P.NE{1'b1}}, 1'b1, Zm[P.NF-2:0]} : {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.NF1]};
|
||||
assign InvalidRes = OutFmt ? {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}} : {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, (P.NF1-1)'(0)};
|
||||
end else begin
|
||||
assign InvalidRes = OutFmt ? {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}} : {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, (P.NF1-1)'(0)};
|
||||
|
@ -120,57 +120,57 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
|
|||
case (OutFmt)
|
||||
P.FMT: begin
|
||||
if(P.IEEE754) begin
|
||||
XNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
|
||||
YNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Ym[P.NF-2:0]};
|
||||
ZNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Zm[P.NF-2:0]};
|
||||
XNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
|
||||
YNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Ym[P.NF-2:0]};
|
||||
ZNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Zm[P.NF-2:0]};
|
||||
InvalidRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
|
||||
end else begin
|
||||
InvalidRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
|
||||
end
|
||||
|
||||
OfRes = OfResMax ? {Rs, {P.NE-1{1'b1}}, 1'b0, {P.NF{1'b1}}} : {Rs, {P.NE{1'b1}}, {P.NF{1'b0}}};
|
||||
UfRes = {Rs, (P.FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
OfRes = OfResMax ? {Rs, {P.NE-1{1'b1}}, 1'b0, {P.NF{1'b1}}} : {Rs, {P.NE{1'b1}}, {P.NF{1'b0}}};
|
||||
UfRes = {Rs, (P.FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {Rs, Re, Rf};
|
||||
end
|
||||
P.FMT1: begin
|
||||
if(P.IEEE754) begin
|
||||
XNaNRes = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.NF1]};
|
||||
YNaNRes = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.NF1]};
|
||||
ZNaNRes = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.NF1]};
|
||||
XNaNRes = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.NF1]};
|
||||
YNaNRes = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.NF1]};
|
||||
ZNaNRes = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.NF1]};
|
||||
InvalidRes = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, (P.NF1-1)'(0)};
|
||||
end else begin
|
||||
InvalidRes = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, (P.NF1-1)'(0)};
|
||||
end
|
||||
OfRes = OfResMax ? {{P.FLEN-P.LEN1{1'b1}}, Rs, {P.NE1-1{1'b1}}, 1'b0, {P.NF1{1'b1}}} : {{P.FLEN-P.LEN1{1'b1}}, Rs, {P.NE1{1'b1}}, (P.NF1)'(0)};
|
||||
UfRes = {{P.FLEN-P.LEN1{1'b1}}, Rs, (P.LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {{P.FLEN-P.LEN1{1'b1}}, Rs, Re[P.NE1-1:0], Rf[P.NF-1:P.NF-P.NF1]};
|
||||
OfRes = OfResMax ? {{P.FLEN-P.LEN1{1'b1}}, Rs, {P.NE1-1{1'b1}}, 1'b0, {P.NF1{1'b1}}} : {{P.FLEN-P.LEN1{1'b1}}, Rs, {P.NE1{1'b1}}, (P.NF1)'(0)};
|
||||
UfRes = {{P.FLEN-P.LEN1{1'b1}}, Rs, (P.LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {{P.FLEN-P.LEN1{1'b1}}, Rs, Re[P.NE1-1:0], Rf[P.NF-1:P.NF-P.NF1]};
|
||||
end
|
||||
P.FMT2: begin
|
||||
if(P.IEEE754) begin
|
||||
XNaNRes = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.NF2]};
|
||||
YNaNRes = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.NF2]};
|
||||
ZNaNRes = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.NF2]};
|
||||
XNaNRes = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.NF2]};
|
||||
YNaNRes = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.NF2]};
|
||||
ZNaNRes = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.NF2]};
|
||||
InvalidRes = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, (P.NF2-1)'(0)};
|
||||
end else begin
|
||||
InvalidRes = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, (P.NF2-1)'(0)};
|
||||
end
|
||||
|
||||
OfRes = OfResMax ? {{P.FLEN-P.LEN2{1'b1}}, Rs, {P.NE2-1{1'b1}}, 1'b0, {P.NF2{1'b1}}} : {{P.FLEN-P.LEN2{1'b1}}, Rs, {P.NE2{1'b1}}, (P.NF2)'(0)};
|
||||
UfRes = {{P.FLEN-P.LEN2{1'b1}}, Rs, (P.LEN2-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
OfRes = OfResMax ? {{P.FLEN-P.LEN2{1'b1}}, Rs, {P.NE2-1{1'b1}}, 1'b0, {P.NF2{1'b1}}} : {{P.FLEN-P.LEN2{1'b1}}, Rs, {P.NE2{1'b1}}, (P.NF2)'(0)};
|
||||
UfRes = {{P.FLEN-P.LEN2{1'b1}}, Rs, (P.LEN2-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {{P.FLEN-P.LEN2{1'b1}}, Rs, Re[P.NE2-1:0], Rf[P.NF-1:P.NF-P.NF2]};
|
||||
end
|
||||
default: begin
|
||||
if(P.IEEE754) begin
|
||||
XNaNRes = (P.FLEN)'(0);
|
||||
YNaNRes = (P.FLEN)'(0);
|
||||
ZNaNRes = (P.FLEN)'(0);
|
||||
XNaNRes = (P.FLEN)'(0);
|
||||
YNaNRes = (P.FLEN)'(0);
|
||||
ZNaNRes = (P.FLEN)'(0);
|
||||
InvalidRes = (P.FLEN)'(0);
|
||||
end else begin
|
||||
InvalidRes = (P.FLEN)'(0);
|
||||
end
|
||||
OfRes = (P.FLEN)'(0);
|
||||
UfRes = (P.FLEN)'(0);
|
||||
NormRes = (P.FLEN)'(0);
|
||||
OfRes = (P.FLEN)'(0);
|
||||
UfRes = (P.FLEN)'(0);
|
||||
NormRes = (P.FLEN)'(0);
|
||||
end
|
||||
endcase
|
||||
|
||||
|
@ -179,58 +179,58 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
|
|||
case (OutFmt)
|
||||
2'h3: begin
|
||||
if(P.IEEE754) begin
|
||||
XNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
|
||||
YNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Ym[P.NF-2:0]};
|
||||
ZNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Zm[P.NF-2:0]};
|
||||
XNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
|
||||
YNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Ym[P.NF-2:0]};
|
||||
ZNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Zm[P.NF-2:0]};
|
||||
InvalidRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
|
||||
end else begin
|
||||
InvalidRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
|
||||
end
|
||||
|
||||
OfRes = OfResMax ? {Rs, {P.NE-1{1'b1}}, 1'b0, {P.NF{1'b1}}} : {Rs, {P.NE{1'b1}}, {P.NF{1'b0}}};
|
||||
UfRes = {Rs, (P.FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
OfRes = OfResMax ? {Rs, {P.NE-1{1'b1}}, 1'b0, {P.NF{1'b1}}} : {Rs, {P.NE{1'b1}}, {P.NF{1'b0}}};
|
||||
UfRes = {Rs, (P.FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {Rs, Re, Rf};
|
||||
end
|
||||
2'h1: begin
|
||||
if(P.IEEE754) begin
|
||||
XNaNRes = {{P.FLEN-P.D_LEN{1'b1}}, 1'b0, {P.D_NE{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.D_NF]};
|
||||
YNaNRes = {{P.FLEN-P.D_LEN{1'b1}}, 1'b0, {P.D_NE{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.D_NF]};
|
||||
ZNaNRes = {{P.FLEN-P.D_LEN{1'b1}}, 1'b0, {P.D_NE{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.D_NF]};
|
||||
XNaNRes = {{P.FLEN-P.D_LEN{1'b1}}, 1'b0, {P.D_NE{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.D_NF]};
|
||||
YNaNRes = {{P.FLEN-P.D_LEN{1'b1}}, 1'b0, {P.D_NE{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.D_NF]};
|
||||
ZNaNRes = {{P.FLEN-P.D_LEN{1'b1}}, 1'b0, {P.D_NE{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.D_NF]};
|
||||
InvalidRes = {{P.FLEN-P.D_LEN{1'b1}}, 1'b0, {P.D_NE{1'b1}}, 1'b1, (P.D_NF-1)'(0)};
|
||||
end else begin
|
||||
InvalidRes = {{P.FLEN-P.D_LEN{1'b1}}, 1'b0, {P.D_NE{1'b1}}, 1'b1, (P.D_NF-1)'(0)};
|
||||
end
|
||||
OfRes = OfResMax ? {{P.FLEN-P.D_LEN{1'b1}}, Rs, {P.D_NE-1{1'b1}}, 1'b0, {P.D_NF{1'b1}}} : {{P.FLEN-P.D_LEN{1'b1}}, Rs, {P.D_NE{1'b1}}, (P.D_NF)'(0)};
|
||||
UfRes = {{P.FLEN-P.D_LEN{1'b1}}, Rs, (P.D_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
OfRes = OfResMax ? {{P.FLEN-P.D_LEN{1'b1}}, Rs, {P.D_NE-1{1'b1}}, 1'b0, {P.D_NF{1'b1}}} : {{P.FLEN-P.D_LEN{1'b1}}, Rs, {P.D_NE{1'b1}}, (P.D_NF)'(0)};
|
||||
UfRes = {{P.FLEN-P.D_LEN{1'b1}}, Rs, (P.D_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {{P.FLEN-P.D_LEN{1'b1}}, Rs, Re[P.D_NE-1:0], Rf[P.NF-1:P.NF-P.D_NF]};
|
||||
end
|
||||
2'h0: begin
|
||||
if(P.IEEE754) begin
|
||||
XNaNRes = {{P.FLEN-P.S_LEN{1'b1}}, 1'b0, {P.S_NE{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.S_NF]};
|
||||
YNaNRes = {{P.FLEN-P.S_LEN{1'b1}}, 1'b0, {P.S_NE{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.S_NF]};
|
||||
ZNaNRes = {{P.FLEN-P.S_LEN{1'b1}}, 1'b0, {P.S_NE{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.S_NF]};
|
||||
XNaNRes = {{P.FLEN-P.S_LEN{1'b1}}, 1'b0, {P.S_NE{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.S_NF]};
|
||||
YNaNRes = {{P.FLEN-P.S_LEN{1'b1}}, 1'b0, {P.S_NE{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.S_NF]};
|
||||
ZNaNRes = {{P.FLEN-P.S_LEN{1'b1}}, 1'b0, {P.S_NE{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.S_NF]};
|
||||
InvalidRes = {{P.FLEN-P.S_LEN{1'b1}}, 1'b0, {P.S_NE{1'b1}}, 1'b1, (P.S_NF-1)'(0)};
|
||||
end else begin
|
||||
InvalidRes = {{P.FLEN-P.S_LEN{1'b1}}, 1'b0, {P.S_NE{1'b1}}, 1'b1, (P.S_NF-1)'(0)};
|
||||
end
|
||||
|
||||
OfRes = OfResMax ? {{P.FLEN-P.S_LEN{1'b1}}, Rs, {P.S_NE-1{1'b1}}, 1'b0, {P.S_NF{1'b1}}} : {{P.FLEN-P.S_LEN{1'b1}}, Rs, {P.S_NE{1'b1}}, (P.S_NF)'(0)};
|
||||
UfRes = {{P.FLEN-P.S_LEN{1'b1}}, Rs, (P.S_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
OfRes = OfResMax ? {{P.FLEN-P.S_LEN{1'b1}}, Rs, {P.S_NE-1{1'b1}}, 1'b0, {P.S_NF{1'b1}}} : {{P.FLEN-P.S_LEN{1'b1}}, Rs, {P.S_NE{1'b1}}, (P.S_NF)'(0)};
|
||||
UfRes = {{P.FLEN-P.S_LEN{1'b1}}, Rs, (P.S_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {{P.FLEN-P.S_LEN{1'b1}}, Rs, Re[P.S_NE-1:0], Rf[P.NF-1:P.NF-P.S_NF]};
|
||||
end
|
||||
2'h2: begin
|
||||
if(P.IEEE754) begin
|
||||
XNaNRes = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.H_NF]};
|
||||
YNaNRes = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.H_NF]};
|
||||
ZNaNRes = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.H_NF]};
|
||||
XNaNRes = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.H_NF]};
|
||||
YNaNRes = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.H_NF]};
|
||||
ZNaNRes = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.H_NF]};
|
||||
InvalidRes = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, (P.H_NF-1)'(0)};
|
||||
end else begin
|
||||
InvalidRes = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, (P.H_NF-1)'(0)};
|
||||
end
|
||||
|
||||
OfRes = OfResMax ? {{P.FLEN-P.H_LEN{1'b1}}, Rs, {P.H_NE-1{1'b1}}, 1'b0, {P.H_NF{1'b1}}} : {{P.FLEN-P.H_LEN{1'b1}}, Rs, {P.H_NE{1'b1}}, (P.H_NF)'(0)};
|
||||
OfRes = OfResMax ? {{P.FLEN-P.H_LEN{1'b1}}, Rs, {P.H_NE-1{1'b1}}, 1'b0, {P.H_NF{1'b1}}} : {{P.FLEN-P.H_LEN{1'b1}}, Rs, {P.H_NE{1'b1}}, (P.H_NF)'(0)};
|
||||
// zero is exact if dividing by infinity so don't add 1
|
||||
UfRes = {{P.FLEN-P.H_LEN{1'b1}}, Rs, (P.H_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
UfRes = {{P.FLEN-P.H_LEN{1'b1}}, Rs, (P.H_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {{P.FLEN-P.H_LEN{1'b1}}, Rs, Re[P.H_NE-1:0], Rf[P.NF-1:P.NF-P.H_NF]};
|
||||
end
|
||||
endcase
|
||||
|
@ -290,7 +290,6 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
|
|||
if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b0}}; // unsigned negitive
|
||||
else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive
|
||||
|
||||
|
||||
// select the integer output
|
||||
// - if the input is invalid (out of bounds NaN or Inf) then output overflow res
|
||||
// - if the input underflows
|
||||
|
|
|
@ -232,7 +232,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
|||
// **** create config to support DTIM with floating point.
|
||||
dtim #(P) dtim(.clk, .ce(~GatedStallW), .MemRWM(DTIMMemRWM),
|
||||
.DTIMAdr, .FlushW, .WriteDataM(LSUWriteDataM),
|
||||
.ReadDataWordM(DTIMReadDataWordM[P.XLEN-1:0]), .ByteMaskM(ByteMaskM[P.XLEN/8-1:0]));
|
||||
.ReadDataWordM(DTIMReadDataWordM[P.LLEN-1:0]), .ByteMaskM(ByteMaskM[P.LLEN/8-1:0]));
|
||||
end else begin
|
||||
end
|
||||
if (P.BUS_SUPPORTED) begin : bus
|
||||
|
@ -308,11 +308,11 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
ahbinterface #(P.XLEN, 1) ahbinterface(.HCLK(clk), .HRESETn(~reset), .Flush(FlushW), .HREADY(LSUHREADY),
|
||||
.HRDATA(HRDATA), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HWDATA(LSUHWDATA),
|
||||
.HWSTRB(LSUHWSTRB), .BusRW, .ByteMask(ByteMaskM), .WriteData(LSUWriteDataM),
|
||||
.HWSTRB(LSUHWSTRB), .BusRW, .ByteMask(ByteMaskM[P.XLEN/8-1:0]), .WriteData(LSUWriteDataM[P.XLEN-1:0]),
|
||||
.Stall(GatedStallW), .BusStall, .BusCommitted(BusCommittedM), .FetchBuffer(FetchBuffer));
|
||||
|
||||
// Mux between the 2 sources of read data, 0: Bus, 1: DTIM
|
||||
if(P.DTIM_SUPPORTED) mux2 #(P.XLEN) ReadDataMux2(FetchBuffer, DTIMReadDataWordM, SelDTIM, ReadDataWordMuxM);
|
||||
if(P.DTIM_SUPPORTED) mux2 #(P.XLEN) ReadDataMux2(FetchBuffer, DTIMReadDataWordM[P.XLEN-1:0], SelDTIM, ReadDataWordMuxM[P.XLEN-1:0]);
|
||||
else assign ReadDataWordMuxM = FetchBuffer[P.XLEN-1:0];
|
||||
assign LSUHBURST = 3'b0;
|
||||
assign {DCacheStallM, DCacheCommittedM, DCacheMiss, DCacheAccess} = '0;
|
||||
|
|
|
@ -32,7 +32,7 @@ module adrdecs import cvw::*; #(parameter cvw_t P) (
|
|||
input logic [P.PA_BITS-1:0] PhysicalAddress,
|
||||
input logic AccessRW, AccessRX, AccessRWX,
|
||||
input logic [1:0] Size,
|
||||
output logic [11:0] SelRegions
|
||||
output logic [10:0] SelRegions
|
||||
);
|
||||
|
||||
localparam logic [3:0] SUPPORTED_SIZE = (P.LLEN == 32 ? 4'b0111 : 4'b1111);
|
||||
|
@ -46,10 +46,9 @@ module adrdecs import cvw::*; #(parameter cvw_t P) (
|
|||
adrdec #(P.PA_BITS) gpiodec(PhysicalAddress, P.GPIO_BASE[P.PA_BITS-1:0], P.GPIO_RANGE[P.PA_BITS-1:0], P.GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[4]);
|
||||
adrdec #(P.PA_BITS) uartdec(PhysicalAddress, P.UART_BASE[P.PA_BITS-1:0], P.UART_RANGE[P.PA_BITS-1:0], P.UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[3]);
|
||||
adrdec #(P.PA_BITS) plicdec(PhysicalAddress, P.PLIC_BASE[P.PA_BITS-1:0], P.PLIC_RANGE[P.PA_BITS-1:0], P.PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[2]);
|
||||
adrdec #(P.PA_BITS) sdcdec(PhysicalAddress, P.SDC_BASE[P.PA_BITS-1:0], P.SDC_RANGE[P.PA_BITS-1:0], P.SDC_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE & 4'b1100, SelRegions[1]);
|
||||
adrdec #(P.PA_BITS) newsdc(PhysicalAddress, P.SDC2_BASE[P.PA_BITS-1:0], P.SDC2_RANGE[P.PA_BITS-1:0], P.SDC2_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE, SelRegions[11]);
|
||||
adrdec #(P.PA_BITS) sdcdec(PhysicalAddress, P.SDC_BASE[P.PA_BITS-1:0], P.SDC_RANGE[P.PA_BITS-1:0], P.SDC_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE, SelRegions[1]);
|
||||
|
||||
assign SelRegions[0] = ~|(SelRegions[11:1]); // none of the regions are selected
|
||||
assign SelRegions[0] = ~|(SelRegions[10:1]); // none of the regions are selected
|
||||
endmodule
|
||||
|
||||
// verilator lint_on UNOPTFLAT
|
||||
|
|
|
@ -43,7 +43,7 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
logic PMAAccessFault;
|
||||
logic AccessRW, AccessRWX, AccessRX;
|
||||
logic [11:0] SelRegions;
|
||||
logic [10:0] SelRegions;
|
||||
logic AtomicAllowed;
|
||||
|
||||
// Determine what type of access is being made
|
||||
|
|
|
@ -157,7 +157,7 @@ module csrs import cvw::*; #(parameter cvw_t P) (
|
|||
IllegalCSRSAccessM = 1;
|
||||
end
|
||||
STIMECMPH: if (STCE)
|
||||
CSRSReadValM[31:0] = STIMECMP_REGW[63:32];
|
||||
CSRSReadValM = {{(P.XLEN-32){1'b0}}, STIMECMP_REGW[63:32]};
|
||||
else begin // not supported for RV64
|
||||
CSRSReadValM = 0;
|
||||
IllegalCSRSAccessM = 1;
|
||||
|
@ -168,4 +168,4 @@ module csrs import cvw::*; #(parameter cvw_t P) (
|
|||
end
|
||||
endcase
|
||||
end
|
||||
endmodule
|
||||
endmodule
|
||||
|
|
|
@ -73,6 +73,15 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
|
|||
logic [`C-1:0][7:1] threshMask;
|
||||
logic [P.PLIC_NUM_SRC-1:0] One;
|
||||
|
||||
// hacks to handle gracefully PLIC_NUM_SRC being smaller than 32
|
||||
// Otherwise Questa and other simulators produce part-select out of bounds even
|
||||
// though sources >=32 are never used
|
||||
|
||||
localparam PLIC_SRC_TOP = (P.PLIC_NUM_SRC >= 32) ? P.PLIC_NUM_SRC : 1;
|
||||
localparam PLIC_SRC_BOT = (P.PLIC_NUM_SRC >= 32) ? 32 : 1;
|
||||
localparam PLIC_SRC_DINTOP = (P.PLIC_NUM_SRC >= 32) ? P.PLIC_NUM_SRC -32 : 0;
|
||||
localparam PLIC_SRC_EXT = (P.PLIC_NUM_SRC >= 32) ? 63-P.PLIC_NUM_SRC : 31;
|
||||
|
||||
// =======
|
||||
// AHB I/O
|
||||
// =======
|
||||
|
@ -107,18 +116,13 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
|
|||
intInProgress <= #1 '0;
|
||||
// writing
|
||||
end else begin
|
||||
if (memwrite)
|
||||
if (memwrite)
|
||||
casez(entry)
|
||||
24'h0000??: intPriority[entry[7:2]] <= #1 Din[2:0];
|
||||
24'h002000: intEn[0][PLIC_NUM_SRC_MIN_32:1] <= #1 Din[PLIC_NUM_SRC_MIN_32:1];
|
||||
24'h002080: intEn[1][PLIC_NUM_SRC_MIN_32:1] <= #1 Din[PLIC_NUM_SRC_MIN_32:1];
|
||||
|
||||
// verilator lint_off SELRANGE
|
||||
// *** RT: Long term we want to factor out these variable number of registers as a generate loop
|
||||
// I think this won't work as a case statement.
|
||||
24'h002004: if (P.PLIC_NUM_SRC >= 32) intEn[0][P.PLIC_NUM_SRC:32] <= #1 Din[P.PLIC_NUM_SRC-32:0];
|
||||
24'h002084: if (P.PLIC_NUM_SRC >= 32) intEn[1][P.PLIC_NUM_SRC:32] <= #1 Din[P.PLIC_NUM_SRC-32:0];
|
||||
// verilator lint_on SELRANGE
|
||||
24'h002004: if (P.PLIC_NUM_SRC >= 32) intEn[0][PLIC_SRC_TOP:PLIC_SRC_BOT] <= #1 Din[PLIC_SRC_DINTOP:0];
|
||||
24'h002084: if (P.PLIC_NUM_SRC >= 32) intEn[1][PLIC_SRC_TOP:PLIC_SRC_BOT] <= #1 Din[PLIC_SRC_DINTOP:0];
|
||||
24'h200000: intThreshold[0] <= #1 Din[2:0];
|
||||
24'h200004: intInProgress <= #1 intInProgress & ~(One << (Din[5:0]-1)); // lower "InProgress" to signify completion
|
||||
24'h201000: intThreshold[1] <= #1 Din[2:0];
|
||||
|
@ -131,20 +135,10 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
|
|||
24'h0000??: Dout <= #1 {29'b0,intPriority[entry[7:2]]};
|
||||
24'h001000: Dout <= #1 {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intPending[PLIC_NUM_SRC_MIN_32:1],1'b0};
|
||||
24'h002000: Dout <= #1 {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intEn[0][PLIC_NUM_SRC_MIN_32:1],1'b0};
|
||||
|
||||
// verilator lint_off SELRANGE
|
||||
// verilator lint_off WIDTHTRUNC
|
||||
24'h001004: if (P.PLIC_NUM_SRC >= 32) Dout <= #1 {{(63-P.PLIC_NUM_SRC){1'b0}},intPending[P.PLIC_NUM_SRC:32]};
|
||||
24'h002004: if (P.PLIC_NUM_SRC >= 32) Dout <= #1 {{(63-P.PLIC_NUM_SRC){1'b0}},intEn[0][P.PLIC_NUM_SRC:32]};
|
||||
// verilator lint_on SELRANGE
|
||||
// verilator lint_on WIDTHTRUNC
|
||||
|
||||
24'h001004: if (P.PLIC_NUM_SRC >= 32) Dout <= #1 {{(PLIC_SRC_EXT){1'b0}},intPending[PLIC_SRC_TOP:PLIC_SRC_BOT]};
|
||||
24'h002004: if (P.PLIC_NUM_SRC >= 32) Dout <= #1 {{(PLIC_SRC_EXT){1'b0}},intEn[0][PLIC_SRC_TOP:PLIC_SRC_BOT]};
|
||||
24'h002080: Dout <= #1 {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intEn[1][PLIC_NUM_SRC_MIN_32:1],1'b0};
|
||||
// verilator lint_off SELRANGE
|
||||
// verilator lint_off WIDTHTRUNC
|
||||
24'h002084: if (P.PLIC_NUM_SRC >= 32) Dout <= #1 {{(63-P.PLIC_NUM_SRC){1'b0}},intEn[1][P.PLIC_NUM_SRC:32]};
|
||||
// verilator lint_on SELRANGE
|
||||
// verilator lint_on WIDTHTRUNC
|
||||
24'h002084: if (P.PLIC_NUM_SRC >= 32) Dout <= #1 {{(PLIC_SRC_EXT){1'b0}},intEn[1][PLIC_SRC_TOP:PLIC_SRC_BOT]};
|
||||
24'h200000: Dout <= #1 {29'b0,intThreshold[0]};
|
||||
24'h200004: begin
|
||||
Dout <= #1 {26'b0,intClaim[0]};
|
||||
|
|
|
@ -59,9 +59,9 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
|||
|
||||
logic [P.XLEN-1:0] HREADRam, HREADSDC;
|
||||
|
||||
logic [11:0] HSELRegions;
|
||||
logic [10:0] HSELRegions;
|
||||
logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC;
|
||||
logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD;
|
||||
logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD;
|
||||
logic HRESPRam, HRESPSDC;
|
||||
logic HREADYRam, HRESPSDCD;
|
||||
logic [P.XLEN-1:0] HREADBootRom;
|
||||
|
@ -88,7 +88,7 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
|||
adrdecs #(P) adrdecs(HADDR, 1'b1, 1'b1, 1'b1, HSIZE[1:0], HSELRegions);
|
||||
|
||||
// unswizzle HSEL signals
|
||||
assign {HSELEXTSDC, HSELDTIM, HSELIROM, HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELSDC} = HSELRegions[11:1];
|
||||
assign {HSELDTIM, HSELIROM, HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELEXTSDC} = HSELRegions[10:1];
|
||||
|
||||
// AHB -> APB bridge
|
||||
ahbapbbridge #(P, 4) ahbapbbridge (
|
||||
|
@ -146,29 +146,21 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
|||
assign UARTSout = 0; assign UARTIntr = 0;
|
||||
end
|
||||
|
||||
// eventually remove
|
||||
assign HREADSDC = '0;
|
||||
assign HREADYSDC = '1;
|
||||
assign HRESPSDC = '0;
|
||||
|
||||
// AHB Read Multiplexer
|
||||
assign HRDATA = ({P.XLEN{HSELRamD}} & HREADRam) |
|
||||
({P.XLEN{HSELEXTD | HSELEXTSDCD}} & HRDATAEXT) |
|
||||
({P.XLEN{HSELBRIDGED}} & HREADBRIDGE) |
|
||||
({P.XLEN{HSELBootRomD}} & HREADBootRom) |
|
||||
({P.XLEN{HSELSDCD}} & HREADSDC);
|
||||
({P.XLEN{HSELBootRomD}} & HREADBootRom);
|
||||
|
||||
assign HRESP = HSELRamD & HRESPRam |
|
||||
(HSELEXTD | HSELEXTSDCD) & HRESPEXT |
|
||||
HSELBRIDGE & HRESPBRIDGE |
|
||||
HSELBootRomD & HRESPBootRom |
|
||||
HSELSDC & HRESPSDC;
|
||||
|
||||
HSELBootRomD & HRESPBootRom;
|
||||
|
||||
assign HREADY = HSELRamD & HREADYRam |
|
||||
(HSELEXTD | HSELEXTSDCD) & HREADYEXT |
|
||||
HSELBRIDGED & HREADYBRIDGE |
|
||||
HSELBootRomD & HREADYBootRom |
|
||||
HSELSDCD & HREADYSDC |
|
||||
HSELNoneD; // don't lock up the bus if no region is being accessed
|
||||
|
||||
// Address Decoder Delay (figure 4-2 in spec)
|
||||
|
@ -176,6 +168,6 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
|||
// takes more than 1 cycle to repsond it needs to hold on to the old select until the
|
||||
// device is ready. Hense this register must be selectively enabled by HREADY.
|
||||
// However on reset None must be seleted.
|
||||
flopenl #(12) hseldelayreg(HCLK, ~HRESETn, HREADY, HSELRegions[11:0], 12'b1, {HSELEXTSDCD, HSELDTIMD, HSELIROMD, HSELEXTD, HSELBootRomD, HSELRamD, HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD, HSELNoneD});
|
||||
flopenl #(11) hseldelayreg(HCLK, ~HRESETn, HREADY, HSELRegions, 11'b1, {HSELDTIMD, HSELIROMD, HSELEXTD, HSELBootRomD, HSELRamD, HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELEXTSDCD, HSELNoneD});
|
||||
flopenr #(1) hselbridgedelayreg(HCLK, ~HRESETn, HREADY, HSELBRIDGE, HSELBRIDGED);
|
||||
endmodule
|
||||
|
|
|
@ -44,7 +44,7 @@ DIRS = $(DIRS32) $(DIRS64)
|
|||
# bpred:
|
||||
# @$(foreach kval, $(k), rm -rf $(CONFIGDIR)/rv64gc_bpred_$(kval);)
|
||||
# @$(foreach kval, $(k), cp -r $(CONFIGDIR)/rv64gc $(CONFIGDIR)/rv64gc_bpred_$(kval);)
|
||||
# @$(foreach kval, $(k), sed -i 's/BPRED_SIZE.*/BPRED_SIZE $(kval)/g' $(CONFIGDIR)/rv64gc_bpred_$(kval)/wally-config.vh;)
|
||||
# @$(foreach kval, $(k), sed -i 's/BPRED_SIZE.*/BPRED_SIZE $(kval)/g' $(CONFIGDIR)/rv64gc_bpred_$(kval)/config.vh;)
|
||||
# @$(foreach kval, $(k), make synth DESIGN=wallypipelinedcore CONFIG=rv64gc_bpred_$(kval) TECH=sky90 FREQ=500 MAXCORES=4 --jobs;)
|
||||
|
||||
configs: $(CONFIG)
|
||||
|
@ -55,11 +55,11 @@ $(CONFIG):
|
|||
|
||||
# adjust DTIM and IROM to reasonable values depending on config
|
||||
ifneq ($(filter $(CONFIG), $(DIRS32)),)
|
||||
sed -i "s/DTIM_RANGE.*/DTIM_RANGE 34\'h01FF/g" $(CONFIGDIR)/wally-config.vh
|
||||
sed -i "s/IROM_RANGE.*/IROM_RANGE 34\'h01FF/g" $(CONFIGDIR)/wally-config.vh
|
||||
sed -i "s/DTIM_RANGE.*/DTIM_RANGE 34\'h01FF/g" $(CONFIGDIR)/config.vh
|
||||
sed -i "s/IROM_RANGE.*/IROM_RANGE 34\'h01FF/g" $(CONFIGDIR)/config.vh
|
||||
else ifneq ($(filter $(CONFIG), $(DIRS64)),)
|
||||
sed -i "s/DTIM_RANGE.*/DTIM_RANGE 56\'h01FF/g" $(CONFIGDIR)/wally-config.vh
|
||||
sed -i "s/IROM_RANGE.*/IROM_RANGE 56\'h01FF/g" $(CONFIGDIR)/wally-config.vh
|
||||
sed -i "s/DTIM_RANGE.*/DTIM_RANGE 56\'h01FF/g" $(CONFIGDIR)/config.vh
|
||||
sed -i "s/IROM_RANGE.*/IROM_RANGE 56\'h01FF/g" $(CONFIGDIR)/config.vh
|
||||
else
|
||||
$(info $(CONFIG) does not exist in $(DIRS32) or $(DIRS64))
|
||||
@echo "Config not in list, RAM_RANGE will be unmodified"
|
||||
|
@ -67,18 +67,18 @@ endif
|
|||
|
||||
# if USESRAM = 1, set that in the config file, otherwise reduce sizes
|
||||
ifeq ($(USESRAM), 1)
|
||||
sed -i 's/USE_SRAM.*/USE_SRAM 1/g' $(CONFIGDIR)/wally-config.vh
|
||||
sed -i 's/USE_SRAM.*/USE_SRAM 1/g' $(CONFIGDIR)/config.vh
|
||||
else
|
||||
sed -i 's/WAYSIZEINBYTES.*/WAYSIZEINBYTES 512/g' $(CONFIGDIR)/wally-config.vh
|
||||
sed -i 's/NUMWAYS.*/NUMWAYS 1/g' $(CONFIGDIR)/wally-config.vh
|
||||
sed -i 's/BPRED_SIZE.*/BPRED_SIZE 5/g' $(CONFIGDIR)/wally-config.vh
|
||||
sed -i 's/BTB_SIZE.*/BTB_SIZE 5/g' $(CONFIGDIR)/wally-config.vh
|
||||
sed -i 's/WAYSIZEINBYTES.*/WAYSIZEINBYTES 512/g' $(CONFIGDIR)/config.vh
|
||||
sed -i 's/NUMWAYS.*/NUMWAYS 1/g' $(CONFIGDIR)/config.vh
|
||||
sed -i 's/BPRED_SIZE.*/BPRED_SIZE 5/g' $(CONFIGDIR)/config.vh
|
||||
sed -i 's/BTB_SIZE.*/BTB_SIZE 5/g' $(CONFIGDIR)/config.vh
|
||||
ifneq ($(filter $(CONFIG), $(DIRS32)),)
|
||||
sed -i "s/BOOTROM_RANGE.*/BOOTROM_RANGE 34\'h01FF/g" $(CONFIGDIR)/wally-config.vh
|
||||
sed -i "s/UNCORE_RAM_RANGE.*/UNCORE_RAM_RANGE 34\'h01FF/g" $(CONFIGDIR)/wally-config.vh
|
||||
sed -i "s/BOOTROM_RANGE.*/BOOTROM_RANGE 34\'h01FF/g" $(CONFIGDIR)/config.vh
|
||||
sed -i "s/UNCORE_RAM_RANGE.*/UNCORE_RAM_RANGE 34\'h01FF/g" $(CONFIGDIR)/config.vh
|
||||
else ifneq ($(filter $(CONFIG), $(DIRS64)),)
|
||||
sed -i "s/BOOTROM_RANGE.*/BOOTROM_RANGE 56\'h01FF/g" $(CONFIGDIR)/wally-config.vh
|
||||
sed -i "s/UNCORE_RAM_RANGE.*/UNCORE_RAM_RANGE 56\'h01FF/g" $(CONFIGDIR)/wally-config.vh
|
||||
sed -i "s/BOOTROM_RANGE.*/BOOTROM_RANGE 56\'h01FF/g" $(CONFIGDIR)/config.vh
|
||||
sed -i "s/UNCORE_RAM_RANGE.*/UNCORE_RAM_RANGE 56\'h01FF/g" $(CONFIGDIR)/config.vh
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -94,20 +94,20 @@ endif
|
|||
|
||||
ifneq ($(MOD), orig)
|
||||
# PMP 0
|
||||
sed -i 's/PMP_ENTRIES \(64\|16\|0\)/PMP_ENTRIES 0/' $(CONFIGDIR)/wally-config.vh
|
||||
sed -i 's/PMP_ENTRIES \(64\|16\|0\)/PMP_ENTRIES 0/' $(CONFIGDIR)/config.vh
|
||||
ifneq ($(MOD), PMP0)
|
||||
# no priv
|
||||
sed -i 's/ZICSR_SUPPORTED *1/ZICSR_SUPPORTED 0/' $(CONFIGDIR)/wally-config.vh
|
||||
sed -i 's/ZICSR_SUPPORTED *1/ZICSR_SUPPORTED 0/' $(CONFIGDIR)/config.vh
|
||||
ifneq ($(MOD), noPriv)
|
||||
# turn off FPU
|
||||
sed -i 's/1 *<< *3/0 << 3/' $(CONFIGDIR)/wally-config.vh
|
||||
sed -i 's/1 *<< *5/0 << 5/' $(CONFIGDIR)/wally-config.vh
|
||||
sed -i 's/1 *<< *3/0 << 3/' $(CONFIGDIR)/config.vh
|
||||
sed -i 's/1 *<< *5/0 << 5/' $(CONFIGDIR)/config.vh
|
||||
ifneq ($(MOD), noFPU)
|
||||
# no muldiv
|
||||
sed -i 's/1 *<< *12/0 << 12/' $(CONFIGDIR)/wally-config.vh
|
||||
sed -i 's/1 *<< *12/0 << 12/' $(CONFIGDIR)/config.vh
|
||||
ifneq ($(MOD), noMulDiv)
|
||||
# no atomic
|
||||
sed -i 's/1 *<< *0/0 << 0/' $(CONFIGDIR)/wally-config.vh
|
||||
sed -i 's/1 *<< *0/0 << 0/' $(CONFIGDIR)/config.vh
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
|
|
@ -25,6 +25,7 @@ set maxopt $::env(MAXOPT)
|
|||
set drive $::env(DRIVE)
|
||||
|
||||
eval file copy -force [glob ${cfg}/*.vh] {$outputDir/hdl/}
|
||||
eval file copy -force [glob ${hdl_src}/*.sv] {$outputDir/hdl/}
|
||||
eval file copy -force [glob ${hdl_src}/*/*.sv] {$outputDir/hdl/}
|
||||
eval file copy -force [glob ${hdl_src}/*/*/*.sv] {$outputDir/hdl/}
|
||||
|
||||
|
@ -37,7 +38,7 @@ if { $saifpower == 1 } {
|
|||
}
|
||||
|
||||
# Verilog files
|
||||
set my_verilog_files [glob $outputDir/hdl/*]
|
||||
set my_verilog_files [glob $outputDir/hdl/cvw.sv $outputDir/hdl/*.sv]
|
||||
|
||||
# Set toplevel
|
||||
set my_toplevel $::env(DESIGN)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue