Compare commits
No commits in common. "master" and "no-pipeline" have entirely different histories.
master
...
no-pipelin
Binary file not shown.
@ -11,7 +11,7 @@ module fp_mult_top (
|
|||||||
|
|
||||||
logic [31:0] a1, b1; // Floating-Point numbers
|
logic [31:0] a1, b1; // Floating-Point numbers
|
||||||
logic [2:0] rnd1; // Rounding signal
|
logic [2:0] rnd1; // Rounding signal
|
||||||
logic [31:0] z1; // a * b
|
logic [31:0] z1; // a ± b
|
||||||
logic [7:0] status1; // Status Flags
|
logic [7:0] status1; // Status Flags
|
||||||
|
|
||||||
fp_mult multiplier(a1,b1,rnd1,z1,status1,clk,rst);
|
fp_mult multiplier(a1,b1,rnd1,z1,status1,clk,rst);
|
||||||
|
34
fpu_mult.mpf
34
fpu_mult.mpf
@ -2304,27 +2304,25 @@ suppress = 8780 ;an explanation can be had by running: verror 8780
|
|||||||
Project_Version = 6
|
Project_Version = 6
|
||||||
Project_DefaultLib = work
|
Project_DefaultLib = work
|
||||||
Project_SortMethod = unused
|
Project_SortMethod = unused
|
||||||
Project_Files_Count = 10
|
Project_Files_Count = 9
|
||||||
Project_File_0 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/normalize_mult.sv
|
Project_File_0 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/fp_mult_top.sv
|
||||||
Project_File_P_0 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 last_compile 1749838823 cover_fsm 0 cover_branch 0 vlog_noload 0 folder src vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 2 dont_compile 0 cover_expr 0 cover_stmt 0
|
Project_File_P_0 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 vlog_noload 0 folder {Top Level} last_compile 1749470139 cover_fsm 0 cover_branch 0 cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 0 cover_expr 0 dont_compile 0 cover_stmt 0
|
||||||
Project_File_1 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/fp_mult_top.sv
|
Project_File_1 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/normalize_mult.sv
|
||||||
Project_File_P_1 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 cover_fsm 0 cover_branch 0 vlog_noload 0 folder {Top Level} last_compile 1750010789 cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 0 cover_expr 0 dont_compile 0 cover_stmt 0
|
Project_File_P_1 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 vlog_noload 0 folder src last_compile 1749838823 cover_fsm 0 cover_branch 0 vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 2 dont_compile 0 cover_expr 0 cover_stmt 0
|
||||||
Project_File_2 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/sim/round_mult_tb.sv
|
Project_File_2 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/round_modes.sv
|
||||||
Project_File_P_2 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 cover_branch 0 vlog_noload 0 folder sim last_compile 1749484994 cover_fsm 0 cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 6 cover_expr 0 dont_compile 0 cover_stmt 0
|
Project_File_P_2 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 folder src last_compile 1749985365 cover_fsm 0 cover_branch 0 vlog_noload 0 cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 8 cover_expr 0 dont_compile 0 cover_stmt 0
|
||||||
Project_File_3 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/fp_mult.sv
|
Project_File_3 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/fp_mult.sv
|
||||||
Project_File_P_3 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 vlog_noload 0 folder src last_compile 1750010789 cover_fsm 0 cover_branch 0 vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 3 dont_compile 0 cover_expr 0 cover_stmt 0
|
Project_File_P_3 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 vlog_noload 0 folder src last_compile 1749991254 cover_fsm 0 cover_branch 0 vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 3 dont_compile 0 cover_expr 0 cover_stmt 0
|
||||||
Project_File_4 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/round_modes.sv
|
Project_File_4 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/sim/round_mult_tb.sv
|
||||||
Project_File_P_4 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 cover_fsm 0 cover_branch 0 vlog_noload 0 folder src last_compile 1749985365 cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 8 cover_expr 0 dont_compile 0 cover_stmt 0
|
Project_File_P_4 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 last_compile 1749484994 cover_fsm 0 cover_branch 0 vlog_noload 0 folder sim cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 6 cover_expr 0 dont_compile 0 cover_stmt 0
|
||||||
Project_File_5 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/sim/fp_mult_top_tb.sv
|
Project_File_5 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/exception_mult.sv
|
||||||
Project_File_P_5 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 last_compile 1750010789 cover_fsm 0 cover_branch 0 vlog_noload 0 folder sim cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 9 cover_expr 0 dont_compile 0 cover_stmt 0
|
Project_File_P_5 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 cover_fsm 0 cover_branch 0 vlog_noload 0 folder src last_compile 1749989714 vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 7 dont_compile 0 cover_expr 0 cover_stmt 0
|
||||||
Project_File_6 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/sim/normalize_mult_tb.sv
|
Project_File_6 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/sim/normalize_mult_tb.sv
|
||||||
Project_File_P_6 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 cover_fsm 0 cover_branch 0 vlog_noload 0 folder sim last_compile 1749840708 vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 5 dont_compile 0 cover_expr 0 cover_stmt 0
|
Project_File_P_6 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 folder sim last_compile 1749840708 cover_fsm 0 cover_branch 0 vlog_noload 0 vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 5 dont_compile 0 cover_expr 0 cover_stmt 0
|
||||||
Project_File_7 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/exception_mult.sv
|
Project_File_7 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/round_mult.sv
|
||||||
Project_File_P_7 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 cover_fsm 0 cover_branch 0 vlog_noload 0 folder src last_compile 1750016331 cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 7 cover_expr 0 dont_compile 0 cover_stmt 0
|
Project_File_P_7 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 cover_fsm 0 cover_branch 0 vlog_noload 0 folder src last_compile 1749991129 cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 1 cover_expr 0 dont_compile 0 cover_stmt 0
|
||||||
Project_File_8 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/sim/fp_mult_tb.sv
|
Project_File_8 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/sim/fp_mult_tb.sv
|
||||||
Project_File_P_8 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 last_compile 1750010789 cover_fsm 0 cover_branch 0 vlog_noload 0 folder sim vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 4 dont_compile 0 cover_expr 0 cover_stmt 0
|
Project_File_P_8 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 last_compile 1749991928 cover_fsm 0 cover_branch 0 vlog_noload 0 folder sim vlog_enable0In 0 cover_excludedefault 0 vlog_disableopt 0 cover_covercells 0 cover_optlevel 3 vlog_hazard 0 vlog_showsource 0 voptflow 1 ood 0 vlog_0InOptions {} toggle - vlog_options {} compile_to work vlog_upper 0 cover_noshort 0 compile_order 4 dont_compile 0 cover_expr 0 cover_stmt 0
|
||||||
Project_File_9 = /home/hoo2/Public/AUTH/HWDigSys-II/fpu_mult/src/round_mult.sv
|
|
||||||
Project_File_P_9 = cover_toggle 0 file_type systemverilog group_id 0 cover_exttoggle 0 cover_nofec 0 cover_cond 0 vlog_1995compat SV vlog_nodebug 0 vlog_noload 0 folder src last_compile 1749991129 cover_fsm 0 cover_branch 0 cover_excludedefault 0 vlog_enable0In 0 vlog_disableopt 0 cover_covercells 0 voptflow 1 vlog_showsource 0 vlog_hazard 0 cover_optlevel 3 toggle - vlog_0InOptions {} ood 0 cover_noshort 0 vlog_upper 0 compile_to work vlog_options {} compile_order 1 cover_expr 0 dont_compile 0 cover_stmt 0
|
|
||||||
Project_Sim_Count = 0
|
Project_Sim_Count = 0
|
||||||
Project_Folder_Count = 2
|
Project_Folder_Count = 2
|
||||||
Project_Folder_0 = src
|
Project_Folder_0 = src
|
||||||
|
7
report/.gitignore
vendored
7
report/.gitignore
vendored
@ -1,7 +0,0 @@
|
|||||||
# TeX auxiliary files
|
|
||||||
*.aux
|
|
||||||
*.log
|
|
||||||
*.out
|
|
||||||
*.synctex.gz
|
|
||||||
|
|
||||||
_minted-report/
|
|
Binary file not shown.
Before Width: | Height: | Size: 50 KiB |
Binary file not shown.
@ -1,344 +0,0 @@
|
|||||||
%
|
|
||||||
% !TEX TS-program = xelatex
|
|
||||||
% !TEX encoding = UTF-8 Unicode
|
|
||||||
% !TEX spellcheck = el-GR
|
|
||||||
%
|
|
||||||
% Low-Level HW Digital Systems II coursework report
|
|
||||||
%
|
|
||||||
%
|
|
||||||
% authors:
|
|
||||||
% Χρήστος Χουτουρίδης ΑΕΜ 8997
|
|
||||||
% cchoutou@ece.auth.gr
|
|
||||||
|
|
||||||
|
|
||||||
% Options:
|
|
||||||
%
|
|
||||||
% 1) mainlang=<language>
|
|
||||||
% Default: english
|
|
||||||
% Set the default language of the document which affects hyphenations,
|
|
||||||
% localization (section, dates, etc...)
|
|
||||||
%
|
|
||||||
% example: \documentclass[mainlang=greek]{AUThReport}
|
|
||||||
%
|
|
||||||
% 2) <language>
|
|
||||||
% Add hyphenation and typesetting support for other languages
|
|
||||||
% Currently supports: english, greek, german, frenc
|
|
||||||
%
|
|
||||||
% example: \documentclass[english, greek]{AUThReport}
|
|
||||||
%
|
|
||||||
% 3) short: Requests a shorter title for the document
|
|
||||||
% Default: no short
|
|
||||||
%
|
|
||||||
% example: \documentclass[short]{AUThReport}
|
|
||||||
%
|
|
||||||
\documentclass[a4paper, 11pt, mainlang=greek, english]{AUThReport}
|
|
||||||
|
|
||||||
\CurrentDate{\today}
|
|
||||||
|
|
||||||
% Greek report document setup suggestions
|
|
||||||
%---------------------------------
|
|
||||||
% Document configuration
|
|
||||||
\AuthorName{Χρήστος Χουτουρίδης}
|
|
||||||
\AuthorAEM{8997}
|
|
||||||
\AuthorMail{cchoutou@ece.auth.gr}
|
|
||||||
|
|
||||||
%\CoAuthorName{CoAuthor Name}
|
|
||||||
%\CoAuthorAEM{AEM}
|
|
||||||
%\CoAuthorMail{CoAuthor Mail}
|
|
||||||
|
|
||||||
% \WorkGroup{Ομάδα Χ}
|
|
||||||
|
|
||||||
\DocTitle{Εργασία}
|
|
||||||
\DocSubTitle{Πολλαπλασιασμός αριθμών κινητής υποδιαστολής}
|
|
||||||
|
|
||||||
\Department{Τμήμα ΗΜΜΥ. Τομέας Ηλεκτρονικής}
|
|
||||||
\ClassName{Ψηφιακά Συστήματα HW σε Χαμηλά Επίπεδα Λογικής II}
|
|
||||||
|
|
||||||
\InstructorName{Βασίλης Παυλίδης}
|
|
||||||
\InstructorMail{ }
|
|
||||||
|
|
||||||
\CoInstructorName{Ευάγγελος Τζουβάρας}
|
|
||||||
\CoInstructorMail{ }
|
|
||||||
|
|
||||||
|
|
||||||
% Local package requirements
|
|
||||||
%---------------------------------
|
|
||||||
%\usepackage{tabularx}
|
|
||||||
%\usepackage{array}
|
|
||||||
%\usepackage{commath}
|
|
||||||
|
|
||||||
\usepackage{amsmath, amssymb, amsfonts}
|
|
||||||
\usepackage{graphicx}
|
|
||||||
\usepackage{subcaption}
|
|
||||||
\usepackage{float}
|
|
||||||
|
|
||||||
|
|
||||||
% Requires: -shell-escape compile argument
|
|
||||||
\usepackage{minted}
|
|
||||||
\usepackage{xcolor}
|
|
||||||
|
|
||||||
\newminted{verilog}{
|
|
||||||
fontsize=\small,
|
|
||||||
breaklines,
|
|
||||||
autogobble,
|
|
||||||
%frame=lines,
|
|
||||||
%framesep=5pt,
|
|
||||||
baselinestretch=1.1,
|
|
||||||
tabsize=2,
|
|
||||||
%bgcolor=LightGray,
|
|
||||||
numbersep=8pt,
|
|
||||||
gobble=0
|
|
||||||
}
|
|
||||||
|
|
||||||
\newcommand{\icode}[1]{\mintinline{verilog}{#1}}
|
|
||||||
|
|
||||||
|
|
||||||
\newcommand{\repo}{https://git.hoo2.net/hoo2/HWDigSys-II}
|
|
||||||
\newcommand{\repoNopipeline}{https://git.hoo2.net/hoo2/HWDigSys-II/src/branch/no-pipeline}
|
|
||||||
\begin{document}
|
|
||||||
|
|
||||||
% Request a title page or header
|
|
||||||
\InsertTitle
|
|
||||||
|
|
||||||
\section{Εισαγωγή}
|
|
||||||
|
|
||||||
Η παρούσα εργασία αφορά στην υλοποίηση ενός πολλαπλασιαστή αριθμών κινητής υποδιαστολής μονής ακρίβειας (IEEE-754 single-precision) σε γλώσσα περιγραφής υλικού SystemVerilog.
|
|
||||||
Η σχεδίαση του κυκλώματος ακολουθεί μια αρθρωτή και κλιμακούμενη προσέγγιση, βασισμένη σε δομή pipeline τριών σταδίων.
|
|
||||||
Το κύριο ζητούμενο ήταν η διαχωρισμένη υλοποίηση της κανονικοποίησης, της στρογγυλοποίησης και της διαχείρισης εξαιρέσεων, με δυνατότητα ελέγχου διαφορετικών τρόπων στρογγυλοποίησης.
|
|
||||||
\par
|
|
||||||
Στόχος της εργασίας είναι η κατανόηση της εσωτερικής λειτουργίας των αριθμητικών μονάδων κινητής υποδιαστολής, η υλοποίηση τους σε επίπεδο RTL και η επαλήθευση της σωστής λειτουργίας τους μέσω εκτενούς ελέγχου με test benches.
|
|
||||||
Η εργασία απαιτεί κατανόηση τόσο της γλώσσας SystemVerilog όσο και του προτύπου IEEE-754, και συνδυάζει αρχιτεκτονική σχεδίαση, ψηφιακή λογική και επαλήθευση μέσω προσομοίωσης.
|
|
||||||
|
|
||||||
\subsection{Παραδοτέα}
|
|
||||||
Τα παραδοτέα της εργασίας αποτελούνται από:
|
|
||||||
\begin{itemize}
|
|
||||||
\item Την παρούσα αναφορά.
|
|
||||||
\item Τον κατάλογο \textbf{src/}, που περιέχει τον κώδικα της SystemVerilog με τα ζητηθέντα modules.
|
|
||||||
\item Τον κατάλογο \textbf{sim/}, που περιέχει το ζητηθέν test bench αλλά και επιμέρους tests για τα υπόλοιπα modules (πλην του exception handler).
|
|
||||||
\item Το \href{\repo}{σύνδεσμο} με το αποθετήριο που περιέχει όλο το project στο vsim, τους κώδικες της SystemVerilog και της αναφοράς καθώς και τα παραδοτέα.
|
|
||||||
\end{itemize}
|
|
||||||
Στην εργασία \textbf{δεν} υλοποιήθηκαν τα εξής:
|
|
||||||
\begin{itemize}
|
|
||||||
\item \textit{Όλοι οι 144} συνδυασμοί των corner cases για το test bench με βάση τους τυχαίους αριθμούς και τον έλεγχο μέσω multiplication.sv.
|
|
||||||
Αντ' αυτού δημιουργήθηκαν test cases που ελέγχουν τόσο την “κανονική” λειτουργία όσο και αρκετά corner cases αλλά οι τιμές τους εισήχθηκαν \textit{με το χέρι}.
|
|
||||||
\item Το μέρος με τα \textit{immediate assertions}.
|
|
||||||
\end{itemize}
|
|
||||||
|
|
||||||
\section{Προσέγγιση Υλοποίησης}
|
|
||||||
Για την εργασία χρησιμοποιήσαμε μια \textbf{αρθρωτή} προσέγγιση.
|
|
||||||
Καθώς η πολυπλοκότητα έμοιαζε αρκετά μεγάλη, σε συνδυασμό με τη μικρή προσωπική εμπειρία σε ψηφιακή σχεδίαση με verilog, προτιμήσαμε να ακολουθήσουμε μια \textbf{test driven} προσέγγιση ανά module.
|
|
||||||
Έτσι χωρίσαμε την ανάπτυξη στα modules που πρότεινε η εκφώνηση και για αυτά δημιουργήσαμε test benches.
|
|
||||||
Τα βασικά tests που θα χρειαζόταν να υλοποιηθούν πρώτα ήταν για τα \textit{normalize} και \textit{round}.
|
|
||||||
Το \textit{exception handler} θα μπορούσε να εκμαιευτεί με “αφαίρεση” των παραπάνω από το συνολικό test bench του \textit{fp\_mult}.
|
|
||||||
Όλα αυτά τα αρχεία μπορούν να βρεθούν στον κατάλογο \textit{sim/}.
|
|
||||||
\par
|
|
||||||
Τα test αυτά αν και κάπως τετριμμένα, έπαιξαν πολύ σημαντικό ρόλο στην υλοποίηση καθώς μας δώσανε τη δυνατότητα να χωριστούν τα interfaces των modules και να πιστοποιήσουν ότι η αναγκαία λειτουργικότητα είναι παρούσα.
|
|
||||||
Κάτι που φυσικά μας βοήθησε στην απομόνωση των σφαλμάτων κλπ...
|
|
||||||
\par
|
|
||||||
Έχοντας υλοποιήσει λοιπόν τα test προβήκαμε στην υλοποίηση των ίδιων των modules.
|
|
||||||
Αρχικά υλοποιήσαμε τα \textit{normalize} και \textit{round} και έπειτα το \textit{fp\_mult}.
|
|
||||||
Με αυτά τα τρία να περνούν τα επιμέρους tests προχωρήσαμε στην υλοποίηση του \textit{exception handler}.
|
|
||||||
Για αυτό το module δεν υλοποιήσαμε πρώτα tests καθώς υπήρχαν τα συνολικά tests και το μόνο modul-άκι που “άλλαζε” ήταν αυτό.
|
|
||||||
\par
|
|
||||||
Τέλος με όλη τη λειτουργικότητα έτοιμη, προβήκαμε στην τελευταία αλλαγή, που ήταν η μετατροπή της λογικής για χρήση \textbf{pipeline τριών σταδίων}.
|
|
||||||
Μιας και τα αρχεία για τα tests για το pipeline είναι διαφορετικά από τα αρχικά, ο αναγνώστης μπορεί \href{\repoNopipeline}{εδώ} να βρει αυτή την ενδιάμεση έκδοση.
|
|
||||||
|
|
||||||
\subsection{Pipeline}
|
|
||||||
|
|
||||||
Η αρχική υλοποίηση όπως είδαμε είχε combinational logic.
|
|
||||||
Επομένως το αποτέλεσμα του πολλαπλασιασμού θα ήταν διαθέσιμο σε κάθε clock του ρολογιού του \textit{fp\_mult\_top}.
|
|
||||||
Παρόλα αυτά ο διαχωρισμός σε 3 στάδια μειώνει αρκετά το βάθος, χωρίς να μεγαλώνει την ανάγκη για extra clock ticks.
|
|
||||||
Αντ' αυτού μειώνει το συνολικό latency.
|
|
||||||
Τα στάδια που χρησιμοποιήθηκαν είναι με τη σειρά τα εξής:
|
|
||||||
\begin{enumerate}
|
|
||||||
\item \textbf{Normalize}: Όπου καλείται το normalize\_mult.
|
|
||||||
\item \textbf{Round}: Όπου καλείται το round\_mult και το
|
|
||||||
\item \textbf{Exception handler}: Όπου καλείται το exception\_mult
|
|
||||||
\end{enumerate}
|
|
||||||
\par
|
|
||||||
Για το pipeline εργαστήκαμε με γνώμονα τη διατήρηση όλης της απαραίτητης πληροφορίας στα στάδια, ούτως ώστε ο χρήστης να μπορεί σε κάθε clock να τροφοδοτεί το module με διαφορετικούς αριθμούς για πολλαπλασιασμό.
|
|
||||||
Όλα τα σήματα από την είσοδο τροφοδοτούνται από το ένα στάδιο στο επόμενο.
|
|
||||||
Η μετάδοση αυτή σταματάει μόνο αν τα σήματα δεν είναι απαραίτητα για τη λειτουργία του επόμενου module.
|
|
||||||
Με αυτό τον τρόπο για παράδειγμα όλη η απαραίτητη πληροφορία για το κάθε module, περνάει από το ένα στάδιο στο επόμενο σε κάθε clock.
|
|
||||||
Για την ακρίβεια, μετά τον αρχικό υπολογισμό του πρόσημου καθώς και του αποτελέσματος του πολλαπλασιασμού για τον εκθέτη και τη mantissa:
|
|
||||||
\begin{itemize}
|
|
||||||
\item Οι \textbf{αριθμοί} προς πολλαπλασιασμό φτάνουνε μέχρι τον exception handler.
|
|
||||||
\item Ο \textbf{εκθέτης} και η \textbf{mantissa} φτάνει μέχρι τον exception handler, όπου και συνθέτει τον τελικό αριθμό πριν την είσοδο.
|
|
||||||
\item To υπολογισμένο \textbf{πρόσημο} του τελικού αριθμού φτάνει μέχρι το round module.
|
|
||||||
\item Τα \textbf{guard} και \textbf{sticky} bits φτάνουν από το normalize μέχρι το round module.
|
|
||||||
\item To \textbf{inexact} bit από το round μέχρι το exception handler.
|
|
||||||
\end{itemize}
|
|
||||||
\par
|
|
||||||
Ενώ επιλέξαμε να υποστηρίξουμε με pipeline όλη σχεδόν την πληροφορία, ένα σήμα δεν ακολουθεί την οδό των σταδίων.
|
|
||||||
Πρόκειται για το \textbf{round}.
|
|
||||||
Ενώ για τα υπόλοιπα θεωρήσαμε πως ο χρήστης πρέπει να μπορεί να τα αλλάζει σε κάθε clock του ρολογιού, αυτό υποθέσαμε ότι θα επιλέγεται κατά την έναρξη και θα \textbf{παραμένει αμετάβλητο κάθ' όλη τη διάρκεια λειτουργίας}.
|
|
||||||
Για το λόγο αυτό, δεν χρειάστηκε να το “περάσουμε” από τα στάδια.
|
|
||||||
|
|
||||||
\section{Λεπτομέρειες Υλοποίησης}
|
|
||||||
|
|
||||||
\subsection{\texttt{fp\_mult.sv} --- Floating Point Multiplier (Top Module)}
|
|
||||||
|
|
||||||
Το module \texttt{fp\_mult} υλοποιεί έναν πλήρως καταχωρημένο πολλαπλασιαστή αριθμών κινητής υποδιαστολής μονής ακρίβειας (IEEE-754).
|
|
||||||
Αποτελείται από ένα pipeline 3 σταδίων:
|
|
||||||
|
|
||||||
\begin{itemize}
|
|
||||||
\item \textbf{Stage 0 (Decode)}:
|
|
||||||
Εξάγει πρόσημο, εκθέτες και mantissas από τις εισόδους \texttt{a}, \texttt{b}.
|
|
||||||
Υπολογίζει το αρχικό γινόμενο mantissas και το bias-adjusted εκθέτη.
|
|
||||||
Η λειτουρία αυτή βρίσκεται σε ένα section με combinational logic.
|
|
||||||
\begin{verilogcode}
|
|
||||||
sign = a[31] ^ b[31];
|
|
||||||
exp_a = a[30:23];
|
|
||||||
exp_b = b[30:23];
|
|
||||||
s0_exponent = exp_a + exp_b - 127;
|
|
||||||
|
|
||||||
mant_a = (exp_a == 0) ? {1'b0, a[22:0]} : {1'b1, a[22:0]};
|
|
||||||
mant_b = (exp_b == 0) ? {1'b0, b[22:0]} : {1'b1, b[22:0]};
|
|
||||||
s0_mantissa = mant_a * mant_b;
|
|
||||||
\end{verilogcode}
|
|
||||||
\item \textbf{Stage 1 (Normalize)}:
|
|
||||||
Κανονικοποιεί το αποτέλεσμα, προσαρμόζοντας την mantissa και τον εκθέτη.
|
|
||||||
Παράγει επίσης guard και sticky bits για στρογγυλοποίηση.
|
|
||||||
\item \textbf{Stage 2 (Round)}:
|
|
||||||
Εφαρμόζει τον επιλεγμένο τρόπο στρογγυλοποίησης και υπολογίζει την τελική mantissa και εκθέτη καθώς και το σήμα inexact.
|
|
||||||
\item \textbf{Stage 3 (Exception Handling)}:
|
|
||||||
Εντοπίζει καταστάσεις όπως NaN, infinities, overflow/underflow, μηδενικά και υπολογίζει την τελική έξοδο \texttt{z} και το flag \texttt{status}.
|
|
||||||
\end{itemize}
|
|
||||||
|
|
||||||
Υποστηρίζει ασύγχρονη επαναφορά (\texttt{rst}) και συγχρονισμό μέσω ρολογιού (\texttt{clk}).
|
|
||||||
|
|
||||||
\subsection{\texttt{normalize\_mult.sv} --- Normalize Stage}
|
|
||||||
|
|
||||||
Το module αυτό δέχεται ένα 48-bit mantissa και έναν 10-bit εκθέτη. Ελέγχει εάν χρειάζεται shift για κανονικοποίηση της mantissa (ώστε να ξεκινά από MSB=1) και αντίστοιχα προσαρμόζει τον εκθέτη.
|
|
||||||
|
|
||||||
\begin{itemize}
|
|
||||||
\item \texttt{mantissa\_out}: Κανονικοποιημένη mantissa (23 bits)
|
|
||||||
\item \texttt{guard\_bit, sticky\_bit}: Χρήσιμα για την ακρίβεια στη στρογγυλοποίηση
|
|
||||||
\item \texttt{exponent\_out}: Νέος εκθέτης μετά την κανονικοποίηση
|
|
||||||
\end{itemize}
|
|
||||||
|
|
||||||
\subsection{\texttt{round\_mult.sv} --- Round Stage}
|
|
||||||
|
|
||||||
Το module εφαρμόζει έναν από τους υποστηριζόμενους τρόπους στρογγυλοποίησης σύμφωνα με το IEEE-754 standard:
|
|
||||||
|
|
||||||
\begin{itemize}
|
|
||||||
\item Round to Nearest Even
|
|
||||||
\item Round Toward Zero
|
|
||||||
\item Round Toward $\inf$
|
|
||||||
\item Round Toward $-\inf$
|
|
||||||
\item Near-Up
|
|
||||||
\item Away from Zero
|
|
||||||
\end{itemize}
|
|
||||||
|
|
||||||
Για κάθε διαφορετικό mode με βάση το round υλοποιεί διαφορετική προσέγγιση.
|
|
||||||
Για παράδειγμα για IEEE nearest\ event έχουμε:
|
|
||||||
\begin{verilogcode}
|
|
||||||
if (guard_bit && (sticky_bit || mantissa_extended[0])) begin
|
|
||||||
mantissa_rounded = mantissa_extended + 1;
|
|
||||||
end
|
|
||||||
\end{verilogcode}
|
|
||||||
Ενώ για IEEE pinf:
|
|
||||||
\begin{verilogcode}
|
|
||||||
if (!sign_in && (guard_bit | sticky_bit)) begin
|
|
||||||
mantissa_rounded = mantissa_extended + 1;
|
|
||||||
end
|
|
||||||
\end{verilogcode}
|
|
||||||
Η υλοποίηση των modes έγινε με διαφορετικές συναρτήσεις, μέσα στο module.
|
|
||||||
Οι είσοδοι περιλαμβάνουν την mantissa, τον εκθέτη, το πρόσημο και τα bits \texttt{guard} και \texttt{sticky}.
|
|
||||||
Οι έξοδοι είναι η νέα mantissa και ο εκθέτης μετά τη στρογγυλοποίηση, καθώς και το σήμα \texttt{inexact}.
|
|
||||||
|
|
||||||
\subsection{\texttt{round\_modes.sv} --- Round Mode Helpers}
|
|
||||||
|
|
||||||
Ορίζει ένα enumeration τύπο \texttt{round\_mode\_t} για τους 6 υποστηριζόμενους τρόπους στρογγυλοποίησης, που χρησιμοποιούνται κυρίως κατά τον χειρισμό overflow και underflow στην εξαίρεση.
|
|
||||||
\begin{verilogcode}
|
|
||||||
typedef enum logic [2:0] {
|
|
||||||
RND_IEEE_NEAREST_EVEN = 3'd0,
|
|
||||||
RND_IEEE_ZERO = 3'd1,
|
|
||||||
RND_IEEE_PINF = 3'd2,
|
|
||||||
RND_IEEE_NINF = 3'd3,
|
|
||||||
RND_NEAR_UP = 3'd4,
|
|
||||||
RND_AWAY_ZERO = 3'd5
|
|
||||||
} round_mode_t;
|
|
||||||
\end{verilogcode}
|
|
||||||
|
|
||||||
\subsection{\texttt{exception\_mult.sv} --- Exception Handling}
|
|
||||||
|
|
||||||
Αυτό το module χειρίζεται corner cases και ειδικές τιμές:
|
|
||||||
|
|
||||||
\begin{itemize}
|
|
||||||
\item Ανίχνευση και χειρισμός NaNs, infinities, zero
|
|
||||||
\item Overflow/underflow μετά τη στρογγυλοποίηση
|
|
||||||
\item Ορισμός της τελικής τιμής \texttt{z}
|
|
||||||
\item Ορισμός των status flags: \texttt{zero\_f}, \texttt{inf\_f}, \texttt{nan\_f}, \texttt{tiny\_f}, \texttt{huge\_f}, \texttt{inexact\_f}
|
|
||||||
\end{itemize}
|
|
||||||
|
|
||||||
Χρησιμοποιεί ένα \texttt{enum interp\_t} για την κατηγοριοποίηση αριθμών (ZERO, INF, NORM, MIN\_NORM, MAX\_NORM) και δύο συναρτήσεις:
|
|
||||||
\begin{itemize}
|
|
||||||
\item \texttt{num\_interp()}: Επιστρέφει το είδος του αριθμού (π.χ., αν είναι infinity ή zero)
|
|
||||||
\item \texttt{z\_num()}: Επιστρέφει την bitwise αναπαράσταση ενός αριθμού βάσει του είδους του
|
|
||||||
\end{itemize}
|
|
||||||
|
|
||||||
Η λογική ελέγχει τους συνδυασμούς εισόδων και εφαρμόζει τις κατάλληλες ενέργειες βάσει πίνακα (table 4) και του rounding mode.
|
|
||||||
Ο βασικός κορμός είναι μια switch case όπου γίνεται το dispatch όλων των corner cases:
|
|
||||||
\begin{verilogcode}
|
|
||||||
a_class = num_interp(a);
|
|
||||||
b_class = num_interp(b);
|
|
||||||
|
|
||||||
case ({a_class, b_class})
|
|
||||||
{ZERO, ZERO}, {ZERO, NORM}, {NORM, ZERO}: // ...
|
|
||||||
{ZERO, INF}, {INF, ZERO}: // ...
|
|
||||||
{INF, INF}, {NORM, INF}, {INF, NORM}: // ...
|
|
||||||
default: // {NORM, NORM} ...
|
|
||||||
endcase
|
|
||||||
\end{verilogcode}
|
|
||||||
Ειδικά στο default βρίσκεται η λογική του extra rounding όταν έχουμε NaN, Inf, κλπ.
|
|
||||||
|
|
||||||
\section{Επαλήθευση και Επικύρωση}
|
|
||||||
Όπως αναφέραμε παραπάνω οι επαλήθευση έγινε σταδιακά.
|
|
||||||
Σε κάθε αρχείο στον κατάλογο \textit{sim/} υπάρχουν tests που επιβεβαιώνουν την ορθή λειτουργία του κάθε module.
|
|
||||||
Για να τρέξουμε τα test χρησιμοποιήσαμε το vsim.
|
|
||||||
Για παράδειγμα για τα test του round\_mult:
|
|
||||||
\begin{verbatim}
|
|
||||||
vlog sim/round_mult_tb
|
|
||||||
vsim -voptargs=+acc work.round_tb
|
|
||||||
run 400ns
|
|
||||||
\end{verbatim}
|
|
||||||
Όλες οι εκτελέσεις εμφανίζουν μηνύματα στην κονσόλα με τα αποτελέσματα.
|
|
||||||
\par
|
|
||||||
Τα τελικά tests που ανήκουν στο fp\_mult\_top\_tb έχουν ελέγχους που ακολουθούν κάποια test vectors όπως παρακάτω:
|
|
||||||
\begin{verilogcode}
|
|
||||||
initial begin
|
|
||||||
$display("Starting fp_mult test...\n");
|
|
||||||
|
|
||||||
// Test cases
|
|
||||||
tests[0] = '{32'h3f800000, 32'h40000000, 32'h40000000, "+1.0 * +2.0 = +2.0"};
|
|
||||||
tests[1] = '{32'h40400000, 32'h40400000, 32'h41100000, "+3.0 * +3.0 = +9.0"};
|
|
||||||
tests[2] = '{32'hc0400000, 32'h40400000, 32'hc1100000, "-3.0 * +3.0 = -9.0"};
|
|
||||||
tests[3] = '{32'hbf800000, 32'h40000000, 32'hc0000000, "-1.0 * +2.0 = -2.0"};
|
|
||||||
// ...
|
|
||||||
end
|
|
||||||
\end{verilogcode}
|
|
||||||
Με βάση αυτά τα vectors, παράγονται μηνύματα που έχουν τη μορφή:
|
|
||||||
\begin{verbatim}
|
|
||||||
# [8] +12.34 * -0.0001 = -0.001234
|
|
||||||
# A=414570a4 B=b8d1b717 => Z=baa1be2b (expected baa1be2b) PASS
|
|
||||||
\end{verbatim}
|
|
||||||
Ένα στιγμιότυπο από την έξοδο φαίνεται στην εικόνα \ref{fig:output}.
|
|
||||||
\begin{figure}[!ht]
|
|
||||||
\centering
|
|
||||||
\includegraphics[width=0.9\textwidth]{img/ConsoleOutput.png}
|
|
||||||
\caption{Στιγμιότυπο εξόδου.}
|
|
||||||
\label{fig:output}
|
|
||||||
\end{figure}
|
|
||||||
|
|
||||||
|
|
||||||
\section{Συμπεράσματα}
|
|
||||||
|
|
||||||
Μέσα από την παρούσα εργασία υλοποιήθηκε με επιτυχία μια πλήρως καταχωρημένη αριθμητική μονάδα πολλαπλασιασμού αριθμών κινητής υποδιαστολής, σύμφωνα με το πρότυπο IEEE-754.
|
|
||||||
Η υλοποίηση με χρήση pipeline τριών σταδίων προσέφερε βελτιωμένη απόδοση και σαφή διαχωρισμό λειτουργιών, καθιστώντας τη σχεδίαση πιο ευέλικτη και επεκτάσιμη.
|
|
||||||
Ο διαχωρισμός σε modules με αυστηρά ορισμένα interfaces διευκόλυνε την ανάπτυξη και τον έλεγχο των επιμέρους λειτουργιών, ενώ η προσέγγιση βασισμένη σε επαλήθευση (test-driven development) διασφάλισε την ορθότητα κάθε σταδίου.
|
|
||||||
\par
|
|
||||||
Αν και δεν καλύφθηκαν όλοι οι δυνατοί συνδυασμοί corner cases, η λογική του κυκλώματος και οι ενδείξεις των αποτελεσμάτων επαληθεύουν ότι η λειτουργία του multiplier είναι σε μεγάλο βαθμό ορθή.
|
|
||||||
Η εργασία παρείχε μια ουσιαστική εμπειρία στην πρακτική υλοποίηση σύνθετων αριθμητικών μονάδων σε χαμηλό επίπεδο, αναδεικνύοντας τις προκλήσεις αλλά και τις δυνατότητες της σύγχρονης ψηφιακής σχεδίασης.
|
|
||||||
|
|
||||||
\end{document}
|
|
111
sim/fp_mult_tb.sv
Executable file → Normal file
111
sim/fp_mult_tb.sv
Executable file → Normal file
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
// sim/fp_mult_tb.sv
|
// sim/fp_mult_tb.sv
|
||||||
`timescale 1ns/1ps
|
`timescale 1ns/1ps
|
||||||
|
|
||||||
@ -7,8 +6,18 @@ module fp_mult_tb;
|
|||||||
logic [31:0] a, b, z;
|
logic [31:0] a, b, z;
|
||||||
logic [2:0] rnd;
|
logic [2:0] rnd;
|
||||||
logic [7:0] status;
|
logic [7:0] status;
|
||||||
logic clk = 0, rst = 1;
|
logic clk = 0, rst = 0;
|
||||||
|
/*
|
||||||
|
// DEBUG signals
|
||||||
|
logic sign_res_;
|
||||||
|
logic [9:0] exp_sum_;
|
||||||
|
logic [47:0] mant_prod_;
|
||||||
|
logic [22:0] mant_norm_;
|
||||||
|
logic [9:0] exp_norm_;
|
||||||
|
logic guard_, sticky_;
|
||||||
|
logic [24:0] mant_post_rnd_;
|
||||||
|
logic [9:0] exp_post_rnd_;
|
||||||
|
*/
|
||||||
// DUT
|
// DUT
|
||||||
fp_mult dut (
|
fp_mult dut (
|
||||||
.a(a),
|
.a(a),
|
||||||
@ -18,10 +27,21 @@ module fp_mult_tb;
|
|||||||
.status(status),
|
.status(status),
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst(rst)
|
.rst(rst)
|
||||||
|
/*
|
||||||
|
// DEBUG signals
|
||||||
|
.sign_res_(sign_res_),
|
||||||
|
.exp_sum_(exp_sum_),
|
||||||
|
.mant_prod_(mant_prod_),
|
||||||
|
.mant_norm_(mant_norm_),
|
||||||
|
.exp_norm_(exp_norm_),
|
||||||
|
.guard_(guard_),
|
||||||
|
.sticky_(sticky_),
|
||||||
|
.mant_post_rnd_(mant_post_rnd_),
|
||||||
|
.exp_post_rnd_(exp_post_rnd_)
|
||||||
|
*/
|
||||||
);
|
);
|
||||||
|
|
||||||
// Clock generation
|
// Clock generation
|
||||||
always #1 rst = 1;
|
|
||||||
always #5 clk = ~clk;
|
always #5 clk = ~clk;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -30,58 +50,59 @@ module fp_mult_tb;
|
|||||||
logic [31:0] expected;
|
logic [31:0] expected;
|
||||||
string desc;
|
string desc;
|
||||||
} test_vector_t;
|
} test_vector_t;
|
||||||
int i =0, j=0;
|
|
||||||
|
|
||||||
test_vector_t tests [20];
|
test_vector_t tests [14];
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
$display("Starting fp_mult test...\n");
|
$display("Starting fp_mult test...\n");
|
||||||
|
|
||||||
// Test vectors
|
// Normal multiplication cases
|
||||||
tests[0] = '{32'h3f800000, 32'h40000000, 32'h40000000, "+1.0 * +2.0 = +2.0"};
|
tests[0] = '{32'h3f800000, 32'h40000000, 32'h40000000, "1.0 * 2.0 = 2.0"};
|
||||||
tests[1] = '{32'h40400000, 32'h40400000, 32'h41100000, "+3.0 * +3.0 = +9.0"};
|
tests[1] = '{32'h40400000, 32'h40400000, 32'h41100000, "3.0 * 3.0 = 9.0"};
|
||||||
tests[2] = '{32'hc0400000, 32'h40400000, 32'hc1100000, "-3.0 * +3.0 = -9.0"};
|
tests[2] = '{32'hc0400000, 32'h40400000, 32'hc1100000, "-3.0 * 3.0 = 9.0"};
|
||||||
tests[3] = '{32'hbf800000, 32'h40000000, 32'hc0000000, "-1.0 * +2.0 = -2.0"};
|
tests[3] = '{32'hbf800000, 32'h40000000, 32'hc0000000, "-1.0 * 2.0 = -2.0"};
|
||||||
tests[4] = '{32'h3f000000, 32'h3f000000, 32'h3e800000, "+0.5 * +0.5 = +0.25"};
|
tests[4] = '{32'h3f000000, 32'h3f000000, 32'h3e800000, "0.5 * 0.5 = 0.25"};
|
||||||
tests[5] = '{32'h3f800000, 32'h00000000, 32'h00000000, "1.0 * +0.0 = +0.0"};
|
tests[5] = '{32'h3f800000, 32'h00000000, 32'h00000000, "1.0 * 0.0 = 0.0"};
|
||||||
tests[6] = '{32'h42280000, 32'hc0e00000, 32'hc3930000, "+42.0 * -7.0 = -294.0"};
|
tests[6] = '{32'h42280000, 32'hc0e00000, 32'hc3930000, "42.0 * -7.0 = -294.0"};
|
||||||
tests[7] = '{32'h414570a4, 32'hb8d1b717, 32'hbaa1be2b, "+12.34 * -0.0001 = -0.001234"};
|
tests[7] = '{32'h414570a4, 32'hb8d1b717, 32'hbaa1be2b, "12.34 * -0.0001 = -0.001234"};
|
||||||
|
|
||||||
tests[8] = '{32'h00000000, 32'h00000000, 32'h00000000, "0.0 * 0.0 = 0.0"};
|
// Corner cases (some may fail if not handled yet)
|
||||||
tests[9] = '{32'h80000000, 32'h80000000, 32'h00000000, "-0.0 * -0.0 = 0.0"};
|
tests[8] = '{32'h00000000, 32'h80000000, 32'h80000000, "0.0 * -0.0 = -0.0"};
|
||||||
tests[10] = '{32'h00000000, 32'h80000000, 32'h80000000, "0.0 * -0.0 = -0.0"};
|
tests[9] = '{32'h3f800000, 32'h80000000, 32'h80000000, "1.0 * -0.0 = -0.0"};
|
||||||
tests[11] = '{32'h3f800000, 32'h80000000, 32'h80000000, "1.0 * -0.0 = -0.0"};
|
tests[10] = '{32'h7f800000, 32'h3f800000, 32'h7f800000, "inf * 1.0 = inf"};
|
||||||
tests[12] = '{32'h7f800000, 32'h3f800000, 32'h7f800000, "inf * 1.0 = inf"};
|
tests[11] = '{32'hff800000, 32'h7f800000, 32'hff800000, "-inf * inf = -inf"};
|
||||||
tests[13] = '{32'hff800000, 32'h3f800000, 32'hff800000, "-inf * 1.0 = -inf"};
|
tests[12] = '{32'h00000000, 32'h7f800000, 32'h7f800000, "0.0 * inf = inf - nan"};
|
||||||
tests[14] = '{32'h7f800000, 32'hbf800000, 32'hff800000, "inf * -1.0 = -inf"};
|
tests[13] = '{32'h80000000, 32'hff800000, 32'h7f800000, "-0.0 * -inf = inf - nan"};
|
||||||
tests[15] = '{32'hff800000, 32'h7f800000, 32'hff800000, "-inf * inf = -inf"};
|
|
||||||
tests[16] = '{32'hff800000, 32'hff800000, 32'h7f800000, "-inf * -inf = +inf"};
|
|
||||||
tests[17] = '{32'h00000000, 32'h7f800000, 32'h7f800000, "0.0 * inf = inf"};
|
|
||||||
tests[18] = '{32'h80000000, 32'hff800000, 32'h7f800000, "-0.0 * -inf = inf"};
|
|
||||||
tests[19] = '{32'h00000000, 32'hff800000, 32'hff800000, "0.0 * -inf = -inf"};
|
|
||||||
end
|
|
||||||
|
|
||||||
logic [31:0] z_pipe [2:0];
|
|
||||||
|
|
||||||
always_ff @(negedge clk) begin
|
rnd = 3'b000; // default round to nearest
|
||||||
z_pipe[2] <= z_pipe[1];
|
rst = 1; #10;
|
||||||
z_pipe[1] <= z_pipe[0];
|
rst = 0; #10;
|
||||||
z_pipe[0] <= z;
|
|
||||||
|
|
||||||
if (i >= 5) begin
|
for (int i = 0; i < 14; i++) begin
|
||||||
j = i - 5;
|
a = tests[i].a;
|
||||||
$display("[%0d] %s", j+1, tests[j].desc);
|
b = tests[i].b;
|
||||||
$display(" A=%h B=%h => Z=%h (expected %h) %s\n",
|
#20;
|
||||||
tests[j].a, tests[j].b, z_pipe[0], tests[j].expected,
|
$display("[%0d] %s", i+1, tests[i].desc);
|
||||||
(z_pipe[0] === tests[j].expected) ? "PASS" : "FAIL");
|
/*
|
||||||
|
// DEBUG prints
|
||||||
|
$display("fp_mult: sign bit = %h", sign_res_);
|
||||||
|
$display("fp_mult: exp (pre norm) = %h", exp_sum_);
|
||||||
|
$display("fp_mult: mant (pre norm) = %h", mant_prod_);
|
||||||
|
$display("fp_mult: exp (norm) = %h", exp_norm_);
|
||||||
|
$display("fp_mult: mant (norm) = %h", mant_norm_);
|
||||||
|
$display("fp_mult: guard,sticky = %h,%h", guard_,sticky_);
|
||||||
|
$display("fp_mult: exp (post rnd) = %h", exp_post_rnd_);
|
||||||
|
$display("fp_mult: mant (post rnd) = %h", mant_post_rnd_);
|
||||||
|
*/
|
||||||
|
$display(" A=%h B=%h => Z=%h (expected %h) %s\n",
|
||||||
|
a, b, z, tests[i].expected,
|
||||||
|
(z === tests[i].expected) ? "PASS" : "FAIL");
|
||||||
end
|
end
|
||||||
|
|
||||||
a <= tests[i].a;
|
$display("\nFinished fp_mult test.");
|
||||||
b <= tests[i].b;
|
$stop;
|
||||||
i <= i + 1;
|
|
||||||
|
|
||||||
if (i == 19 + 5) $stop;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -1,89 +0,0 @@
|
|||||||
// sim/fp_mult_top_tb.sv
|
|
||||||
`timescale 1ns/1ps
|
|
||||||
|
|
||||||
module fp_mult_top_tb;
|
|
||||||
|
|
||||||
logic [31:0] a, b, z;
|
|
||||||
logic [2:0] rnd;
|
|
||||||
logic [7:0] status;
|
|
||||||
logic clk = 0, rst = 1;
|
|
||||||
|
|
||||||
// DUT
|
|
||||||
fp_mult_top dut (
|
|
||||||
.a(a),
|
|
||||||
.b(b),
|
|
||||||
.rnd(rnd),
|
|
||||||
.z(z),
|
|
||||||
.status(status),
|
|
||||||
.clk(clk),
|
|
||||||
.rst(rst)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Clock generation
|
|
||||||
always #1 rst = 1;
|
|
||||||
always #5 clk = ~clk;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
logic [31:0] a;
|
|
||||||
logic [31:0] b;
|
|
||||||
logic [31:0] expected;
|
|
||||||
string desc;
|
|
||||||
} test_vector_t;
|
|
||||||
int i =0, j=0;
|
|
||||||
|
|
||||||
// Test vectors
|
|
||||||
test_vector_t tests [20];
|
|
||||||
|
|
||||||
initial begin
|
|
||||||
|
|
||||||
$display("Starting fp_mult test...\n");
|
|
||||||
|
|
||||||
// Test cases
|
|
||||||
tests[0] = '{32'h3f800000, 32'h40000000, 32'h40000000, "+1.0 * +2.0 = +2.0"};
|
|
||||||
tests[1] = '{32'h40400000, 32'h40400000, 32'h41100000, "+3.0 * +3.0 = +9.0"};
|
|
||||||
tests[2] = '{32'hc0400000, 32'h40400000, 32'hc1100000, "-3.0 * +3.0 = -9.0"};
|
|
||||||
tests[3] = '{32'hbf800000, 32'h40000000, 32'hc0000000, "-1.0 * +2.0 = -2.0"};
|
|
||||||
tests[4] = '{32'h3f000000, 32'h3f000000, 32'h3e800000, "+0.5 * +0.5 = +0.25"};
|
|
||||||
tests[5] = '{32'h3f800000, 32'h00000000, 32'h00000000, "1.0 * +0.0 = +0.0"};
|
|
||||||
tests[6] = '{32'h42280000, 32'hc0e00000, 32'hc3930000, "+42.0 * -7.0 = -294.0"};
|
|
||||||
tests[7] = '{32'h414570a4, 32'hb8d1b717, 32'hbaa1be2b, "+12.34 * -0.0001 = -0.001234"};
|
|
||||||
|
|
||||||
tests[8] = '{32'h00000000, 32'h00000000, 32'h00000000, "0.0 * 0.0 = 0.0"};
|
|
||||||
tests[9] = '{32'h80000000, 32'h80000000, 32'h00000000, "-0.0 * -0.0 = 0.0"};
|
|
||||||
tests[10] = '{32'h00000000, 32'h80000000, 32'h80000000, "0.0 * -0.0 = -0.0"};
|
|
||||||
tests[11] = '{32'h3f800000, 32'h80000000, 32'h80000000, "1.0 * -0.0 = -0.0"};
|
|
||||||
tests[12] = '{32'h7f800000, 32'h3f800000, 32'h7f800000, "inf * 1.0 = inf"};
|
|
||||||
tests[13] = '{32'hff800000, 32'h3f800000, 32'hff800000, "-inf * 1.0 = -inf"};
|
|
||||||
tests[14] = '{32'h7f800000, 32'hbf800000, 32'hff800000, "inf * -1.0 = -inf"};
|
|
||||||
tests[15] = '{32'hff800000, 32'h7f800000, 32'hff800000, "-inf * inf = -inf"};
|
|
||||||
tests[16] = '{32'hff800000, 32'hff800000, 32'h7f800000, "-inf * -inf = +inf"};
|
|
||||||
tests[17] = '{32'h00000000, 32'h7f800000, 32'h7f800000, "0.0 * inf = inf"};
|
|
||||||
tests[18] = '{32'h80000000, 32'hff800000, 32'h7f800000, "-0.0 * -inf = inf"};
|
|
||||||
tests[19] = '{32'h00000000, 32'hff800000, 32'hff800000, "0.0 * -inf = -inf"};
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
logic [31:0] z_pipe [2:0];
|
|
||||||
|
|
||||||
always_ff @(negedge clk) begin
|
|
||||||
z_pipe[2] <= z_pipe[1];
|
|
||||||
z_pipe[1] <= z_pipe[0];
|
|
||||||
z_pipe[0] <= z;
|
|
||||||
|
|
||||||
if (i >= 7) begin
|
|
||||||
j = i - 7;
|
|
||||||
$display("[%0d] %s", j+1, tests[j].desc);
|
|
||||||
$display(" A=%h B=%h => Z=%h (expected %h) %s\n",
|
|
||||||
tests[j].a, tests[j].b, z_pipe[0], tests[j].expected,
|
|
||||||
(z_pipe[0] == tests[j].expected) ? "PASS" : "FAIL");
|
|
||||||
end
|
|
||||||
|
|
||||||
a <= tests[i].a;
|
|
||||||
b <= tests[i].b;
|
|
||||||
i <= i + 1;
|
|
||||||
|
|
||||||
if (i == 19 + 7) $stop;
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
|
@ -1,6 +1,7 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
// exception_mult.sv
|
|
||||||
// Handles the exceptional cases
|
|
||||||
`include "round_modes.sv"
|
`include "round_modes.sv"
|
||||||
|
|
||||||
module exception_mult (
|
module exception_mult (
|
||||||
@ -71,7 +72,7 @@ module exception_mult (
|
|||||||
|
|
||||||
{ZERO, INF}, {INF, ZERO}:
|
{ZERO, INF}, {INF, ZERO}:
|
||||||
begin
|
begin
|
||||||
z = {sign, z_num(INF)};
|
z = {1'b0, z_num(INF)};
|
||||||
nan_f = 1;
|
nan_f = 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
222
src/fp_mult.sv
222
src/fp_mult.sv
@ -6,151 +6,125 @@ module fp_mult (
|
|||||||
input logic [31:0] b, // input operand B
|
input logic [31:0] b, // input operand B
|
||||||
input logic [2:0] round, // rounding mode
|
input logic [2:0] round, // rounding mode
|
||||||
output logic [31:0] z, // result
|
output logic [31:0] z, // result
|
||||||
output logic [7:0] status, // status flags
|
output logic [7:0] status, // status flags (placeholder)
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic rst
|
input logic rst
|
||||||
|
/*
|
||||||
|
// debug outputs
|
||||||
|
output logic sign_res_,
|
||||||
|
output logic [9:0] exp_sum_,
|
||||||
|
output logic [47:0] mant_prod_,
|
||||||
|
output logic [22:0] mant_norm_,
|
||||||
|
output logic [9:0] exp_norm_,
|
||||||
|
output logic guard_, sticky_,
|
||||||
|
output logic [24:0] mant_post_rnd_,
|
||||||
|
output logic [9:0] exp_post_rnd_
|
||||||
|
*/
|
||||||
);
|
);
|
||||||
|
|
||||||
// Stage 0: Decode inputs
|
// === STEP 0: Parse inputs
|
||||||
logic sign;
|
logic sign_a, sign_b;
|
||||||
logic [7:0] exp_a, exp_b;
|
logic [7:0] exp_a, exp_b;
|
||||||
logic [23:0] mant_a, mant_b;
|
logic [23:0] mant_a, mant_b; // includes hidden bit
|
||||||
logic [47:0] s0_mantissa;
|
|
||||||
logic [9:0] s0_exponent;
|
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
sign = a[31] ^ b[31];
|
sign_a = a[31];
|
||||||
exp_a = a[30:23];
|
sign_b = b[31];
|
||||||
exp_b = b[30:23];
|
exp_a = a[30:23];
|
||||||
s0_exponent = exp_a + exp_b - 127;
|
exp_b = b[30:23];
|
||||||
|
mant_a = (exp_a == 8'd0) ? {1'b0, a[22:0]} : {1'b1, a[22:0]};
|
||||||
mant_a = (exp_a == 0) ? {1'b0, a[22:0]} : {1'b1, a[22:0]};
|
mant_b = (exp_b == 8'd0) ? {1'b0, b[22:0]} : {1'b1, b[22:0]};
|
||||||
mant_b = (exp_b == 0) ? {1'b0, b[22:0]} : {1'b1, b[22:0]};
|
// ^ Add hiden leading '1' on normalized numbers
|
||||||
s0_mantissa = mant_a * mant_b;
|
// This will lead to always 24-bits mantissa internal representation
|
||||||
|
// for multiplication
|
||||||
end
|
end
|
||||||
|
|
||||||
// === Stage 1: Normalize ===
|
// === STEP 1: Floating point number sign calculation
|
||||||
logic [47:0] s1_mant_in;
|
logic sign_res;
|
||||||
logic [9:0] s1_exp_in;
|
assign sign_res = sign_a ^ sign_b;
|
||||||
logic [22:0] s1_mant_out;
|
//assign sign_res_ = sign_res; // DEBUG
|
||||||
logic [9:0] s1_exp_out;
|
|
||||||
logic s1_guard_out, s1_sticky_out;
|
|
||||||
logic [31:0] s1_a, s1_b;
|
|
||||||
logic s1_sign;
|
|
||||||
|
|
||||||
normalize_mult normalize_inst (
|
// === STEP 2,3. Exponent addition, Exponent subtraction of bias
|
||||||
.mantissa_in(s1_mant_in),
|
logic [9:0] exp_sum;
|
||||||
.exponent_in(s1_exp_in),
|
always_comb begin
|
||||||
.mantissa_out(s1_mant_out),
|
exp_sum = exp_a + exp_b - 127; // apply bias
|
||||||
.exponent_out(s1_exp_out),
|
//exp_sum_ = exp_sum; // DEBUG
|
||||||
.guard_bit(s1_guard_out),
|
end
|
||||||
.sticky_bit(s1_sticky_out)
|
|
||||||
|
// === STEP 4: Mantissa multiplication (including leading ones)
|
||||||
|
logic [47:0] mant_prod;
|
||||||
|
always_comb begin
|
||||||
|
mant_prod = mant_a * mant_b;
|
||||||
|
//mant_prod_ = mant_prod; // DEBUG
|
||||||
|
end
|
||||||
|
|
||||||
|
// === STEP 5: Truncation and normalization
|
||||||
|
logic [22:0] mant_norm;
|
||||||
|
logic [9:0] exp_norm;
|
||||||
|
logic guard, sticky;
|
||||||
|
|
||||||
|
normalize_mult norm_inst (
|
||||||
|
.mantissa_in(mant_prod),
|
||||||
|
.exponent_in(exp_sum),
|
||||||
|
.mantissa_out(mant_norm),
|
||||||
|
.exponent_out(exp_norm),
|
||||||
|
.guard_bit(guard),
|
||||||
|
.sticky_bit(sticky)
|
||||||
);
|
);
|
||||||
|
//assign mant_norm_ = mant_norm; // DEBUG
|
||||||
|
//assign exp_norm_ = exp_norm; // DEBUG
|
||||||
|
//assign guard_ = guard; // DEBUG
|
||||||
|
//assign sticky_ = sticky; // DEBUG
|
||||||
|
|
||||||
always_ff @(posedge clk or negedge rst) begin
|
// === STEP 6: Pipeline stage
|
||||||
if (!rst) begin
|
// Ehhh... We dont do that here...
|
||||||
s1_mant_in <= 0;
|
|
||||||
s1_exp_in <= 0;
|
|
||||||
s1_a <= 0;
|
|
||||||
s1_b <= 0;
|
|
||||||
s1_sign <= 0;
|
|
||||||
end else begin
|
|
||||||
s1_mant_in <= s0_mantissa;
|
|
||||||
s1_exp_in <= s0_exponent;
|
|
||||||
s1_a <= a;
|
|
||||||
s1_b <= b;
|
|
||||||
s1_sign <= sign;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
// === Stage 2: Round ===
|
// === STEP 7: Rounding
|
||||||
logic [22:0] s2_mant_in;
|
logic [24:0] mant_post_rnd;
|
||||||
logic [9:0] s2_exp_in;
|
logic [9:0] exp_post_rnd;
|
||||||
logic s2_guard_in, s2_sticky_in;
|
logic inexact;
|
||||||
logic [31:0] s2_a, s2_b;
|
|
||||||
logic s2_sign;
|
|
||||||
logic [24:0] s2_mant_out;
|
|
||||||
logic [9:0] s2_exp_out;
|
|
||||||
logic s2_inexact;
|
|
||||||
|
|
||||||
round_mult round_inst (
|
round_mult round_inst (
|
||||||
.mantissa_in(s2_mant_in),
|
.mantissa_in(mant_norm),
|
||||||
.exponent_in(s2_exp_in),
|
.exponent_in(exp_norm),
|
||||||
.sign_in(s2_sign),
|
.sign_in(sign_res),
|
||||||
.guard_bit(s2_guard_in),
|
.guard_bit(guard),
|
||||||
.sticky_bit(s2_sticky_in),
|
.sticky_bit(sticky),
|
||||||
.round(round),
|
.round(round),
|
||||||
.mantissa_out(s2_mant_out),
|
.mantissa_out(mant_post_rnd),
|
||||||
.exponent_out(s2_exp_out),
|
.exponent_out(exp_post_rnd),
|
||||||
.inexact(s2_inexact)
|
.inexact(inexact)
|
||||||
);
|
);
|
||||||
|
//assign mant_post_rnd_ = mant_post_rnd; // DEBUG
|
||||||
|
//assign exp_post_rnd_ = exp_post_rnd; // DEBUG
|
||||||
|
|
||||||
always_ff @(posedge clk or negedge rst) begin
|
// === STEP 8: Exception handling
|
||||||
if (!rst) begin
|
// overflow / underflow:
|
||||||
s2_mant_in <= 0;
|
logic [31:0] z_calc;
|
||||||
s2_exp_in <= 0;
|
logic ovf, unf;
|
||||||
s2_guard_in <= 0;
|
|
||||||
s2_sticky_in <= 0;
|
assign z_calc = {sign_res, exp_post_rnd[7:0], mant_post_rnd[22:0]};
|
||||||
s2_a <= 0;
|
always_comb begin
|
||||||
s2_b <= 0;
|
ovf = (exp_post_rnd > 10'd254); // MAX normal exponent
|
||||||
s2_sign <= 0;
|
unf = (exp_post_rnd < 10'd1); // MIN normal exponent
|
||||||
end else begin
|
|
||||||
s2_mant_in <= s1_mant_out;
|
|
||||||
s2_exp_in <= s1_exp_out;
|
|
||||||
s2_guard_in <= s1_guard_out;
|
|
||||||
s2_sticky_in <= s1_sticky_out;
|
|
||||||
s2_a <= s1_a;
|
|
||||||
s2_b <= s1_b;
|
|
||||||
s2_sign <= s1_sign;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
// === Stage 3: Exception Handling ===
|
exception_mult exc_inst (
|
||||||
logic [31:0] s3_a, s3_b;
|
.a(a),
|
||||||
logic [31:0] s3_z_calc_in;
|
.b(b),
|
||||||
logic s3_ovf_in, s3_unf_in;
|
.z_calc(z_calc),
|
||||||
logic s3_inexact;
|
.ovf(ovf),
|
||||||
logic [31:0] s3_z_out;
|
.unf(unf),
|
||||||
logic [7:0] s3_status_out;
|
.inexact(inexact),
|
||||||
|
|
||||||
exception_mult exception_handler (
|
|
||||||
.a(s3_a),
|
|
||||||
.b(s3_b),
|
|
||||||
.z_calc(s3_z_calc_in),
|
|
||||||
.ovf(s3_ovf_in),
|
|
||||||
.unf(s3_unf_in),
|
|
||||||
.inexact(s3_inexact),
|
|
||||||
.round(round),
|
.round(round),
|
||||||
.z(s3_z_out),
|
.z(z),
|
||||||
.zero_f(s3_status_out[0]),
|
.zero_f(status[0]),
|
||||||
.inf_f(s3_status_out[1]),
|
.inf_f(status[1]),
|
||||||
.nan_f(s3_status_out[2]),
|
.nan_f(status[2]),
|
||||||
.tiny_f(s3_status_out[3]),
|
.tiny_f(status[3]),
|
||||||
.huge_f(s3_status_out[4]),
|
.huge_f(status[4]),
|
||||||
.inexact_f(s3_status_out[5])
|
.inexact_f(status[5])
|
||||||
);
|
);
|
||||||
|
|
||||||
always_ff @(posedge clk or negedge rst) begin
|
|
||||||
if (!rst) begin
|
|
||||||
s3_a <= 0;
|
|
||||||
s3_b <= 0;
|
|
||||||
s3_z_calc_in <= 0;
|
|
||||||
s3_ovf_in <= 0;
|
|
||||||
s3_unf_in <= 0;
|
|
||||||
s3_inexact <= 0;
|
|
||||||
z <= 0;
|
|
||||||
status <= 0;
|
|
||||||
end else begin
|
|
||||||
s3_a <= s2_a;
|
|
||||||
s3_b <= s2_b;
|
|
||||||
s3_z_calc_in <= {s2_sign, s2_exp_out[7:0], s2_mant_out[22:0]};
|
|
||||||
s3_ovf_in <= (s2_exp_out > 8'd254);
|
|
||||||
s3_unf_in <= (s2_exp_out < 8'd1);
|
|
||||||
s3_inexact <= s2_inexact;
|
|
||||||
z <= s3_z_out;
|
|
||||||
status <= s3_status_out;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user