summaryrefslogtreecommitdiffstats
path: root/verilog.tex
diff options
context:
space:
mode:
authorYann Herklotz <git@yannherklotz.com>2020-06-29 09:23:04 +0100
committerYann Herklotz <git@yannherklotz.com>2020-06-29 09:23:04 +0100
commit9797dabf78b306183766c2446b3ee62406d9623f (patch)
tree461650d91df21b8c1445a913fb6ed0a32088cacb /verilog.tex
parent20315caeabd1f76f89c6b16c633d7d0ec013f64d (diff)
downloadoopsla21_fvhls-9797dabf78b306183766c2446b3ee62406d9623f.tar.gz
oopsla21_fvhls-9797dabf78b306183766c2446b3ee62406d9623f.zip
Add more to Verilog section
Diffstat (limited to 'verilog.tex')
-rw-r--r--verilog.tex10
1 files changed, 8 insertions, 2 deletions
diff --git a/verilog.tex b/verilog.tex
index d4954d7..6f1e5ee 100644
--- a/verilog.tex
+++ b/verilog.tex
@@ -73,6 +73,10 @@ Taking the \textsc{CondTrue} rule as an example, this rule will only apply if th
One main difference between these semantics and the Verilog semantics by \citet{loow19_verif_compil_verif_proces} is that there is no function for external nondeterministic effects, such as memories and inputs and outputs. These are instead handled explicitly in the semantics by using two dimensional unpacked arrays to model memories and assuming that inputs to modules cannot change. Another difference with these semantics is that partial updates to arrays are fully supported, due to the fact that there are two different queues for arrays and variables. Originally, if there was a blocking assignment to an array, and then a nonblocking assignment to a different region in the array, then the blocking assignment would disappear at the end of the clock cycle. This is because the complete array would be overwritten with the updated array in the nonblocking association maps. However, in our semantics, only the values that were changed in the array are actually recorded in the nonblocking assignment queue, meaning once the blocking and nonblocking array association maps are merged, only the actual indices that changed with nonblocking assignment are updated in the blocking assignment map.
+In these semantics, module instantiations are not supported, as they can be modelled by inlining the logic that modules would have produced. This therefore means that function calls are implemented by inlining all the functions as well. Consequently, recursive function calls are not supported, however, these are not supported by other high-level synthesis tools either, as allocating memory dynamically is not possible with fixed size RAM blocks.
+
+To integrate our semantics with CompCert, we need to define the same states that CompCert uses to define their semantics, which are the \texttt{State}, \texttt{Callstate} and \texttt{Returnstate}. The \texttt{Callstate} and \texttt{Returnstate} are needed because the initial state describes a call to main, and the final state results in the return value from the main function. Even though the Verilog semantics do not support function calls, semantics for the initial function call and final return state need to be implemented to be properly shown equivalent to the Verilog semantics. Firstly, the \texttt{State} is contains all the information necessary to identify the current execution state of the function or module. In Verilog, we therefore keep track of the current module $m$ we are working on, the current value of the program counter $v$, which translates to the current value of the state register $s_{t}$, the current contents of the stack frame \textit{sf} and finally the current states of the association maps for variables $\Gamma_{r}$ and arrays $\Gamma_{a}$. We can therefore define the state as \texttt{State} \textit{sf} $m$ $v$ $\Gamma_{r}$ $\Gamma_{a}$. The \texttt{Callstate} only needs to be supported for the initial call to the function and the \texttt{Returnstate} only needs to be supported for the return of the main function. As function calls are not supported in the semantics, there cannot be any other possible calling state or return state in the program.
+
We then define the semantics of running the module for one clock cycle in the following way:
\begin{gather*}
@@ -80,12 +84,14 @@ We then define the semantics of running the module for one clock cycle in the fo
%
\inferrule[Finish]{\Gamma_{r}!\textit{fin} = \texttt{Some } 1 \\ \Gamma_{r}!\textit{ret} = \texttt{Some } r}{\texttt{State } \textit{sf }\ m\ s_{t}\ \Gamma_{r}\ \Gamma_{a} \longrightarrow \texttt{Returnstate } \textit{sf }\ r}\\
%
- \inferrule[Call]{ }{\texttt{Callstate } \textit{st }\ m\ \vec{r} \longrightarrow \texttt{State } \textit{st }\ m\ n\ (\textit{init\_params }\ \vec{r}\ a // \{s_{t} \rightarrow n\})}\\
+ \inferrule[Call]{ }{\texttt{Callstate } \textit{sf }\ m\ \vec{r} \longrightarrow \texttt{State } \textit{sf }\ m\ n\ (\textit{init\_params }\ \vec{r}\ a // \{s_{t} \rightarrow n\})}\\
%
\inferrule[Return]{ }{\texttt{Returnstate } (\texttt{Stackframe } r\ m\ \textit{pc }\ \Gamma_{r}\ \Gamma_{a} :: \textit{sf}) \longrightarrow \texttt{State } \textit{sf }\ m\ \textit{pc }\ (\Gamma_{r} // \{ \textit{st} \rightarrow \textit{pc}, r \rightarrow i \})\ \epsilon}
\end{gather*}
-The top level structure of a Verilog module consists of a list of module items $\vec{m}$. These are then executed sequentially while changing the associations of all the variables. We can define a function \textit{mis\_step}, which steps through all of the module items and executes them.
+\YH{TODO:\@ Need to fix the last rule, as it is actually only used for a case that shouldn't ever be hit.}
+
+The \textsc{Module} rule is the main rule for the execution of one clock cycle of the module. Given that the value of the $s_{t}$ register is the value of the program counter at the current instruction and that the value of the $s_{t}$ register in the resulting association map is equal to the next program counter value, we can then say that if all the module items in the body go from one state to another, that the whole module will step from that state to the other.
\input{verilog_notes}