Skip to content

Commit

Permalink
Fix Specification Memory Port Types (chipsalliance#2319)
Browse files Browse the repository at this point in the history
Correct incorrect type specified for memories in the FIRRTL
specification.  This is important because the memory type determines
what is a legal bundle to try to connect to a memory port.

I based this off of FIRRTL accepting the following circuit:

    circuit MemOrder:
      module MemOrder:
        input r: {addr : UInt<3>, en : UInt<1>, clk : Clock, flip data : UInt<1>}
        input w: {addr : UInt<3>, en : UInt<1>, clk : Clock, data : UInt<1>, mask : UInt<1>}
        input rw: {addr : UInt<3>, en : UInt<1>, clk : Clock, flip rdata : UInt<1>, wmode : UInt<1>, wdata : UInt<1>, wmask : UInt<1>}

        mem memory:
          data-type => UInt<1>
          depth => 8
          reader => r
          writer => w
          readwriter => rw
          read-latency => 1
          write-latency => 1
          read-under-write => undefined

        memory.r <= r
        memory.w <= w
        memory.rw <= rw

Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
  • Loading branch information
seldridge committed Aug 5, 2021
1 parent 747b374 commit 8abf308
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 14 deletions.
Binary file modified spec/spec.pdf
Binary file not shown.
27 changes: 13 additions & 14 deletions spec/spec.tex
Original file line number Diff line number Diff line change
Expand Up @@ -892,35 +892,35 @@ \subsection{Memories}

In the example above, the type of \verb|mymem| is:
\begin{lstlisting}
{flip r1: {flip data: {real:SInt<16>, imag:SInt<16>},
addr: UInt<8>,
{flip r1: {addr: UInt<8>,
en: UInt<1>,
clk: Clock}
flip r2: {flip data: {real:SInt<16>, imag:SInt<16>},
addr: UInt<8>,
clk: Clock,
flip data: {real:SInt<16>, imag:SInt<16>}}
flip r2: {addr: UInt<8>,
en: UInt<1>,
clk: Clock}
flip w: {data: {real:SInt<16>, imag:SInt<16>},
mask: {real:UInt<1>, imag:UInt<1>},
addr: UInt<8>,
clk: Clock,
flip data: {real:SInt<16>, imag:SInt<16>}}
flip w: {addr: UInt<8>,
en: UInt<1>,
clk: Clock}}
clk: Clock},
data: {real:SInt<16>, imag:SInt<16>},
mask: {real:UInt<1>, imag:UInt<1>}}
\end{lstlisting}

The following sections describe how a memory's field types are calculated and the behavior of each type of memory port.

\subsubsection{Read Ports}
If a memory is declared with element type \verb|T|, has a size less than or equal to $2^N$, then its read ports have type:
\begin{lstlisting}
{flip data:T, addr:UInt<N>, en:UInt<1>, clk:Clock}
{addr:UInt<N>, en:UInt<1>, clk:Clock, flip data:T}
\end{lstlisting}

If the \verb|en| field is high, then the element value associated with the address in the \verb|addr| field can be retrieved by reading from the \verb|data| field after the appropriate read latency. If the \verb|en| field is low, then the value in the \verb|data| field, after the appropriate read latency, is undefined. The port is driven by the clock signal in the \verb|clk| field.

\subsubsection{Write Ports}
If a memory is declared with element type \verb|T|, has a size less than or equal to $2^N$, then its write ports have type:
\begin{lstlisting}
{data:T, mask:M, addr:UInt<N>, en:UInt<1>, clk:Clock}
{addr:UInt<N>, en:UInt<1>, clk:Clock, data:T, mask:M}
\end{lstlisting}
where \verb|M| is the mask type calculated from the element type \verb|T|. Intuitively, the mask type mirrors the aggregate structure of the element type except with all ground types replaced with a single bit unsigned integer type. The {\em non-masked portion} of the data value is defined as the set of data value leaf sub-elements where the corresponding mask leaf sub-element is high.

Expand All @@ -929,8 +929,7 @@ \subsubsection{Write Ports}
\subsubsection{Readwrite Ports}
Finally, the readwrite ports have type:
\begin{lstlisting}
{wmode:UInt<1>, flip rdata:T, wdata:T, wmask:M,
addr:UInt<N>, en:UInt<1>, clk:Clock}
{addr:UInt<N>, en:UInt<1>, clk:Clock, flip rdata:T, wmode:UInt<1>, wdata:T, wmask:M}
\end{lstlisting}
A readwrite port is a single port that, on a given cycle, can be used either as a read or a write port. If the readwrite port is not in write mode (the \verb|wmode| field is low), then the \verb|rdata|, \verb|addr|, \verb|en|, and \verb|clk| fields constitute its read port fields, and should be used accordingly. If the readwrite port is in write mode (the \verb|wmode| field is high), then the \verb|wdata|, \verb|wmask|, \verb|addr|, \verb|en|, and \verb|clk| fields constitute its write port fields, and should be used accordingly.

Expand Down

0 comments on commit 8abf308

Please sign in to comment.