wip lr4 report

This commit is contained in:
Ivan I. Ovchinnikov 2023-01-30 18:21:25 +03:00
parent c6fe1cc19d
commit 84277abd9d
14 changed files with 823 additions and 571 deletions

View File

@ -18,17 +18,21 @@
Осуществить полный цикл проектирования цифрового устройства на ПЛИС на языке SystemVerilog. Реализовать генератор периодических функций на основе метода прямого цифрового синтеза на микросхеме семейства Cyclone IV E.
\section{Задачи}
Прямой цифровой синтез -- это метод генерации сигнала заданной формы путём вычисления значений сигнала в последовательных дискретных отсчётах времени и преобразовании их в аналоговый сигнал с помощью ЦАП. Структура системы приведена на рис \hrf{pic:synth-scheme}.
\begin{itemize}
\item Реализовать модули «Накопителя фазы», «Просмотровой таблицы», «Сигма-Дельта модулятора».
\item Реализовать синтезатор по схеме (рис. \hrf{pic:synth-scheme}), используя разработанные модули.
\begin{figure}[H]
\centering
\fontsize{14}{1}\selectfont
\includesvg[scale=1.01]{pics/03-fpga-lab-04-01-synth.svg}
\caption{Схема цифрового синтезатора}
\label{pic:pic:synth-scheme}
\label{pic:synth-scheme}
\end{figure}
Инкремент фазы поступает на вход накопителя фазы и определяет скорость изменения фазы формируемого сигнала. Накопитель фазы выдаёт номер текущего отсчёта в периоде на просмотровую таблицу, содержащую образ одного периода синуса. Значение с выхода просмотровой таблицы поступает на дельта-сигма модулятор, который работает как однобитный ЦАП. Модулятор формирует последовательность нулей и единиц на высокой частоте, соответствующую текущему уровню на входе модулятора, после чего двухуровневый выходной сигнал модулятора подается на выход ПЛИС и сглаживается простым RC фильтром НЧ. При изменении приращения фазы изменяется частота формируемого на выходе сигнала.
\item Осуществить моделирование каждого этапа разработки.
\item В рамках самостоятельной подготовки провести расчёт значений $u_n$,$x_n$,$y'_n$ и $\varepsilon_n$ для 5 тактов работы дельта-сигма модулятора. Приведите значения для каждого такта и график выходного сигнала $y_n$.
\end{itemize}
\section{Выполнение работы}
\subsection{Самостоятельная подготовка}
@ -37,17 +41,44 @@
\begin{figure}[H]
\centering
\resizebox{\textwidth}{!}{\input{pics/03-fpga-04-sigdel.pgf}}
\caption{1}
\label{pic:1}
\caption{Пошаговая иллюстрация работы сигма-дельта модулятора}
\label{pic:sig-del-handjob}
\end{figure}
Регистр $u_{-1}$ по низкому уровню сигнала сброса инициализируется нулём, поэтому значение $y_{-1}$ становится равным 127, как следствие, $\varepsilon_{-1} = 0$. Далее, значения изменяются по следующим формулам:
\begin{equation*}
\begin{gathered}
x = 6;\\
u_n = x - y'_{n-1}\\
\varepsilon_n = y'_n - u_n
\end{gathered}
\end{equation*}
Несколько шагов алгоритма приведены в расчётах ниже. Из ручного прохождения алгоритма (и графика на рис \hrf{pic:sig-del-handjob}) очевидно, что постоянное малое значение на входе модулятора формирует переходы $y$ от -128 до 127 на каждом такте линии задержки, как если бы это было при входящем значении нуля, и изредка удерживает $y$ в значении 127 (примерно, один раз в 20 отсчётов).
\begin{enumerate}
\item $x_n = 6, \varepsilon_n = 127$, уровень квантования 127;
\item $u_{n + 1} = x_n - \varepsilon_n = 6 127 = -121$, при этом $\varepsilon_n = -128-(-121)=-7$, а уровень квантования -128;
\item $u_{n + 2} = x_n - \varepsilon_n = 6 (7) = 13$, при этом $\varepsilon_n = 127 - 13 = 104$, а уровень квантования 127;
\item $u_{n + 3} = x_n - \varepsilon_n = 6 104 = -98$, при этом $\varepsilon_n= -128-(-98) = -30$, а уровень квантования -128;
\item $u_{n + 4} = x_n - \varepsilon_n = 26 (30) = 106$, при этом ξn= 127-106 = 11, а уровень квантования 127 F: Un+1=XN-ξn=26 11 = 15, при этом ξn= 127-15 = 112, а уровень квантования 127
G: Un+1=XN-ξn=26 112 = -86, при этом ξn= -128-(-86) = -42, а уровень квантования -128 H: Un+1=XN-varepsilonn=26 (42) = 88, при этом ξn= 127-88 = 39, а уровень квантования 127
\item $x = 6, u_{1} = 6, y'_{0} = 127, \varepsilon_{1} = 121$
\item $x = 6, u_{2} = -115, y'_{1} = 127, \varepsilon_{2} = -13$
\item $x = 6, u_{3} = 19, y'_{2} = -128, \varepsilon_{3} = 108$
\item $x = 6, u_{4} = -102, y'_{3} = 127, \varepsilon_{4} = -26$
\item $x = 6, u_{5} = 32, y'_{4} = -128, \varepsilon_{5} = 95$
\item $x = 6, u_{6} = -89, y'_{5} = 127, \varepsilon_{6} = -39$
\item $x = 6, u_{7} = 45, y'_{6} = -128, \varepsilon_{7} = 82$
\item $x = 6, u_{8} = -76, y'_{7} = 127, \varepsilon_{8} = -52$
\item $x = 6, u_{9} = 58, y'_{8} = -128, \varepsilon_{9} = 69$
\item $x = 6, u_{10} = -63, y'_{9} = 127, \varepsilon_{10} = -65$
\item $x = 6, u_{11} = 71, y'_{10} = -128, \varepsilon_{11} = 56$
\item $x = 6, u_{12} = -50, y'_{11} = 127, \varepsilon_{12} = -78$
\item $x = 6, u_{13} = 84, y'_{12} = -128, \varepsilon_{13} = 43$
\item $x = 6, u_{14} = -37, y'_{13} = 127, \varepsilon_{14} = -91$
\item $x = 6, u_{15} = 97, y'_{14} = -128, \varepsilon_{15} = 30$
\item $x = 6, u_{16} = -24, y'_{15} = 127, \varepsilon_{16} = -104$
\item $x = 6, u_{17} = 110, y'_{16} = -128, \varepsilon_{17} = 17$
\item $x = 6, u_{18} = -11, y'_{17} = 127, \varepsilon_{18} = -117$
\item $x = 6, u_{19} = 123, y'_{18} = -128, \varepsilon_{19} = 4$
\item $x = 6, u_{20} = 2, y'_{19} = 127, \varepsilon_{20} = 125$
\item $x = 6, u_{21} = -119, y'_{20} = 127, \varepsilon_{21} = -9$
\item $x = 6, u_{22} = 15, y'_{21} = -128, \varepsilon_{22} = 112$
\end{enumerate}
\subsection{Разработка модулей}
@ -55,19 +86,109 @@
\textbf{Интерфейс модуля}
\begin{frm} \begin{itemize}
\item [] \textbf{Входы:}
\code{phinc[7:0]} -- величина приращения фазы за один период тактового сигнала;
\code{clk} -- тактовый сигнал;
\code{clr_n} -- вход асинхронного сброса;
\item [] \code{phinc[7:0]} -- величина приращения фазы за один период тактового сигнала;
\item [] \code{clk} -- тактовый сигнал;
\item [] \code{clr_n} -- вход асинхронного сброса;
\item [] \textbf{Выходы:}
\code{phase[7:0]} -- 8 старших значащих битов выхода накопителя;
\item [] \code{phase[7:0]} -- 8 старших значащих битов выхода накопителя;
\item [] \textbf{Параметры:}
\code{WIDTH} -- разрядность накопителя фазы (значение по умолчанию -- 14).
\item [] \code{WIDTH} -- разрядность накопителя фазы (значение по умолчанию -- 14).
\end{itemize} \end{frm}
\textbf{Принцип действия}
Накопитель фазы -- это классический аккумулятор, который сохраняет накопленную сумму в регистре и использует её в качестве одного из операндов сумматора на каждом такте. Второй операнд поступает с входа и определяет величину приращения фазы. Разрядность аккумулятора должна быть параметризирована. Входные значения складываются с младшими битами регистра аккумулятора, а на выход поступают старшие 8 разрядов аккумулятора, поэтому при разрядности аккумулятора M и значении N на входе приращения фазы выход фазы будет увеличиваться на единицу один раз в $2^{(M-8)}/N$ тактов.
\section{Индивидуальное задание}
\lstinputlisting[language=Verilog,style=VerilogStyle,caption={Накопитель фазы},label={lst:phacc}]{src/phacc.sv}
\lstinputlisting[language=Verilog,style=VerilogStyle,caption={Тестовый стенд накопителя фазы},label={lst:inc_lut}]{src/inc_lut_tb.sv}
\subsubsection{Просмотровая таблица}
Просмотровая таблица реализована на ПЗУ, шина адреса которого управляется входным значением фазы сигнала, а ячейки содержат соответствующие значения сигнала. Для реализации использован модуль ROM: 1-PORT с файлом инициализации памяти sine256.mif прилагавшемся в исходных файлах для лабораторной работы.
\begin{figure}[H]
\centering
\includegraphics[width=0.9\textwidth]{03-fpga-lab-04-02-phacc.png}
\caption{Результат симуляции работы накопителя фазы и просмотровой таблицы}
\label{pic:phacc-lut}
\end{figure}
\subsubsection{Дельта-сигма модулятор}
\textbf{Интерфейс модуля}
\begin{frm} \begin{itemize}
\item [] \textbf{Входы:}
\item [] \code{val[7:0]} - входные данные модулятора;
\item [] \code{clk} тактовый сигнал;
\item [] \code{clr_n} вход асинхронного сброса.
\item [] \textbf{Выход:}
\item [] \code{daco} - однобитная выходная последовательность.
\end{itemize}
\end{frm}
\textbf{Принцип действия}
На вход поступают 8-разрядные отсчеты $x_n$ (рис. \hrf{pic:sigdel-1}). Выход $y_n$ -- двухуровневый дискретизированный с большой частотой. Частота изменения отсчетов сигнала, выбираемых из памяти, ниже частоты работы модулятора. Это обеспечивает передискретизацию и возможность представления сигнала в аналоговом виде после НЧ фильтрации последовательности нулей и единиц.
\begin{figure}[H]
\centering
\fontsize{12}{1}\selectfont
\includesvg[scale=1.01]{pics/03-fpga-lab-04-01-sigdel.svg}
\caption{Схема дельта-сигма модулятора первого порядка}
\label{pic:sigdel-1}
\end{figure}
Если в работе модулятора использовать 8-разрядный регистр $u_n$ периодически в работе модулятора будут появляться переполнения и будет наблюдаться некорректное поведение, проявляющееся в смене фазы выходного сигнала (рис. \hrf{pic:unoverflow}). Переполнение регистра возможно наблюдать при моделировании достаточно большого числа шагов алгоритма (рис. \hrf{pic:unover-model}).
\begin{figure}[H]
\centering
\includegraphics[width=0.9\textwidth]{03-fpga-lab-04-02-unoverflow.png}
\caption{Смена фазы выходного сигнала}
\label{pic:unoverflow}
\end{figure}
\begin{figure}[H]
\centering
\includegraphics[width=0.9\textwidth]{03-fpga-lab-04-02-unover-model.png}
\caption{Переполнение значения регистра}
\label{pic:unover-model}
\end{figure}
\lstinputlisting[language=Verilog,style=VerilogStyle,caption={Код дельта-сигма модулятора},label={lst:phacc}]{src/sdmod.sv}
\lstinputlisting[language=Verilog,style=VerilogStyle,caption={Тестовый стенд дельта-сигма модулятора},label={lst:inc_lut}]{src/lut_mod_tb.sv}
\subsubsection{Реализация синтезатора}
\lstinputlisting[language=Verilog,style=VerilogStyle,caption={Код дельта-сигма синтезатора},label={lst:phacc}]{src/sigdel.sv}
\begin{figure}[H]
\centering
\includegraphics[width=0.9\textwidth]{03-fpga-lab-04-02-correct.png}
\caption{Моделирование работы синтезатора}
\label{pic:synth-model}
\end{figure}
\subsection{Контрольные вопросы}
\begin{itemize}
\item Почему именно за это время из памяти выбирается один период синуса?
Столько тратит времени 14-разрядный регистр накапливающий значения в 8 нижних разрядах так, чтобы изменилось значение в 8 верхних, отдаваемых аккумулятором.
\item Какая разрядность накопителя фазы требуется для формирования синусоидального сигнала в диапазоне частот от единиц до сотен Герц при изменении инкремента фазы от 1 до 255 (период синуса содержит 256 отсчетов, частота тактового импульса -- 50МГЦ)?
В данной работе использовался коэффициент накопления 16 при той же частоте ТИ, то есть на каждом такте значение в аккумуляторе менялось на 1 в 5м разряде. Это тоже самое, что если коэфициент будет равен единице, а разрядность снижена на 5. Один период синуса проходил за 20мкс. Таким образом можно сделать вывод, что при коэффициенте 16 и разрядности накопителя 20 период одного синуса будет составлять около 760мс, при разрядности 21 -- около 1,5сек.
\item Дельта-сигма модулятор первого порядка.
Позволяет снизить шум квантования относительно ШИМ, за счёт увеличения частоты выходного сигнала.
\item Конфигурация ПЛИС Altera на основе статической памяти.
Конфигурация ПЛИС хранится ячейках статической памяти, изготовленной по стандартной технологии. Достоинство этой технологии -- возможность многократного перепрограммирования ПЛИС. Недостатки -- не самое высокое быстродействие, поскольку после включения питания прошивку нужно вновь загружать из памяти. На плате необходимо дополнительно устанавливать загрузчик, специальная микросхема FLASH или микроконтроллер.
\item Язык SystemVerilog.
Языки описания схемотехники (HDL -- hardware design language) позволяют значительно сократить время описания схемотехнических решений и значительно повысить качество за счёт переиспользования кода, б\'{о}льших возможностей по моделированию и тестированию готовых схем. Также повышается переносимость решений. Язык SystemVerilog отличается от VHDL (Very High Speed Integrated Circuit HDL) лаконичностью описания, а от Verilog расширенными возможностями работы с абстракциями более верхнего уровня (не только сигналы, регистры и шины, но и знаковые переменные, матрицы и прочие).
\end{itemize}
\section{Выводы}
@ -78,8 +199,4 @@
\subsection{Исходные коды проекта}
\label{appendix:src}
% \lstinputlisting[language=Verilog,style=VerilogStyle,caption={Семафор},label={lst:dec}]{src/dec.sv}
% \lstinputlisting[language=C,style=CCodeStyle,caption={\code{sem.c}},label={lst:sem}]{src/sem.c}
\end{document}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,185 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg8"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
sodipodi:docname="03-fpga-lab-04-01-sigdel.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.9195959"
inkscape:cx="382.92847"
inkscape:cy="355.83023"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
showgrid="true"
inkscape:snap-global="true"
inkscape:object-paths="true"
inkscape:snap-bbox="true"
inkscape:bbox-nodes="false"
inkscape:window-width="1533"
inkscape:window-height="1205"
inkscape:window-x="45"
inkscape:window-y="72"
inkscape:window-maximized="0"
inkscape:bbox-paths="false"
inkscape:snap-bbox-edge-midpoints="false">
<inkscape:grid
type="xygrid"
id="grid833" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<text
xml:space="preserve"
style="font-size:4.9389px;line-height:1.25;font-family:'PT Astra Serif';-inkscape-font-specification:'PT Astra Serif';stroke-width:0.264583"
x="88.619423"
y="89.942841"
id="text837"><tspan
sodipodi:role="line"
id="tspan835"
x="88.619423"
y="89.942841"
style="stroke-width:0.264583">$Z^{-1}$</tspan></text>
<text
xml:space="preserve"
style="font-size:4.9389px;line-height:1.25;font-family:'PT Astra Serif';-inkscape-font-specification:'PT Astra Serif';stroke-width:0.264583"
x="103.17359"
y="84.649567"
id="text841"><tspan
sodipodi:role="line"
id="tspan839"
x="103.17359"
y="84.649567"
style="stroke-width:0.264583">$u_n$</tspan></text>
<text
xml:space="preserve"
style="font-size:4.9389px;line-height:1.25;font-family:'PT Astra Serif';-inkscape-font-specification:'PT Astra Serif';stroke-width:0.264583"
x="116.41666"
y="89.958336"
id="text845"><tspan
sodipodi:role="line"
id="tspan843"
x="116.41666"
y="89.958336"
style="stroke-width:0.264583">Q</tspan></text>
<text
xml:space="preserve"
style="font-size:4.9389px;line-height:1.25;font-family:'PT Astra Serif';-inkscape-font-specification:'PT Astra Serif';stroke-width:0.264583"
x="129.64583"
y="84.666664"
id="text849"><tspan
sodipodi:role="line"
id="tspan847"
x="129.64583"
y="84.666664"
style="stroke-width:0.264583">$y_n$</tspan></text>
<text
xml:space="preserve"
style="font-size:4.9389px;line-height:1.25;font-family:'PT Astra Serif';-inkscape-font-specification:'PT Astra Serif';stroke-width:0.264583"
x="129.64583"
y="97.895836"
id="text853"><tspan
sodipodi:role="line"
id="tspan851"
x="129.64583"
y="97.895836"
style="stroke-width:0.264583">$\varepsilon_n$</tspan></text>
<text
xml:space="preserve"
style="font-size:4.9389px;line-height:1.25;font-family:'PT Astra Serif';-inkscape-font-specification:'PT Astra Serif';stroke-width:0.264583"
x="54.239582"
y="85.989586"
id="text857"><tspan
sodipodi:role="line"
id="tspan855"
x="54.239582"
y="85.989586"
style="stroke-width:0.264583">$x_n$</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 52.916666,88.635416 h 15.875"
id="path859" />
<rect
style="fill:none;stroke:#000000;stroke-width:0.265;stroke-miterlimit:4;stroke-dasharray:none"
id="rect861"
width="11.90625"
height="9.2604113"
x="87.3125"
y="84.666664" />
<rect
style="fill:none;stroke:#000000;stroke-width:0.264999;stroke-miterlimit:4;stroke-dasharray:none"
id="rect863"
width="10.583333"
height="9.260417"
x="113.77083"
y="84.666664" />
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 99.218749,88.635416 H 113.77083"
id="path865" />
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 124.35417,87.312499 h 23.81249"
id="path867" />
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 124.35417,91.281249 h 3.96875 V 103.1875 l -54.239587,0 v -9.260417"
id="path869"
sodipodi:nodetypes="ccccc" />
<circle
style="fill:none;stroke:#000000;stroke-width:0.264999;stroke-miterlimit:4;stroke-dasharray:none"
id="path871"
cx="74.215836"
cy="88.502914"
r="5.2916665" />
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 79.374999,88.635416 7.937501,10e-7"
id="path873"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 74.083332,85.989582 v 5.291667"
id="path875" />
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 71.437499,88.635416 h 5.291667"
id="path877" />
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 75.406249,96.572915 h 2.645833"
id="path879" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -13,7 +13,7 @@
version="1.1"
id="svg8"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
sodipodi:docname="03-fpga-04-01-synth.svg">
sodipodi:docname="03-fpga-lab-04-01-synth.svg">
<defs
id="defs2" />
<sodipodi:namedview
@ -23,20 +23,20 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="381.52629"
inkscape:cy="338.43264"
inkscape:zoom="1.4"
inkscape:cx="348.3892"
inkscape:cy="386.19683"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
showgrid="true"
inkscape:snap-global="true"
inkscape:snap-text-baseline="true"
inkscape:window-width="2356"
inkscape:window-height="1205"
inkscape:window-x="88"
inkscape:window-y="115"
inkscape:window-maximized="0">
inkscape:window-width="2560"
inkscape:window-height="1376"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid10" />
@ -49,7 +49,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
@ -227,13 +227,13 @@
<text
xml:space="preserve"
style="font-size:4.9389px;line-height:1.25;font-family:'PT Astra Serif';-inkscape-font-specification:'PT Astra Serif';stroke-width:0.264583"
x="87.3125"
x="84.666664"
y="100.54166"
id="text901"><tspan
sodipodi:role="line"
id="tspan899"
x="87.3125"
x="84.666664"
y="100.54166"
style="stroke-width:0.264583">к осцилографу</tspan></text>
style="stroke-width:0.264583">к осциллографу</tspan></text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

47
src/inc_lut_tb.sv Normal file
View File

@ -0,0 +1,47 @@
`timescale 1 ns/1 ns
module inc_lut_tb();
// Parameters
localparam CLK_PRD = 20;
localparam PHACC_WIDTH = 14;
logic clk, clr_n, wr_n;
logic [7:0] phinc_val, phase, sine;
// Instantiate UUT and connect used ports
phacc phacc(.phinc(phinc_val), .clk(clk), .reset(clr_n), .phase(phase));
defparam phacc.WIDTH = PHACC_WIDTH;
sinelut sinelut_inst (
.address (phase), .clock (clk), .q(sine)
);
// Clock definition
initial begin
clk = 0;
forever #(CLK_PRD/2) clk = ~clk;
end
// Reset and initial values definition
initial begin
clr_n = 0;
#(CLK_PRD*5) clr_n = 1;
end
// Bus write transaction simulation
initial begin
// Wait until system is out of reset
@(posedge clr_n);
phinc_val=(2**(PHACC_WIDTH - 8));
if ((phinc_val <= 255) && (phinc_val != 0)) begin
#(CLK_PRD * 256 * 5) $stop;
end else begin
$display("Error: value of phase increment is out of range! Stopped simulation.");
#1 $stop;
end
end
endmodule

55
src/lut_mod_tb.sv Executable file
View File

@ -0,0 +1,55 @@
`timescale 1 ns/1 ns
module lut_mod_tb();
// Parameters
localparam CLK_PRD = 20;
localparam PHACC_WIDTH = 14;
logic clk, clr_n, wr_n, daco;
logic [7:0] phinc_val, phase, sine;
// Instantiate UUT and connect used ports
phacc phacc (
.phinc(phinc_val), .clk(clk), .reset(clr_n), .phase(phase)
);
defparam phacc.WIDTH = PHACC_WIDTH;
sinelut sinelut_inst (
.address(phase), .clock(clk), .q(sine)
);
sdmod sdmod_inst (
.val(sine), .clk(clk), .reset(clr_n), .daco(daco)
// .val(8'd0), .clk(clk), .reset(clr_n), .daco(daco)
// .val(8'd255), .clk(clk), .reset(clr_n), .daco(daco)
);
// Clock definition
initial begin
clk = 0;
forever #(CLK_PRD/2) clk = ~clk;
end
// Reset and initial values definition
initial begin
clr_n = 0;
#(CLK_PRD*5) clr_n = 1;
end
// Bus write transaction simulation
initial begin
// Wait until system is out of reset
@(posedge clr_n);
phinc_val=(2**(PHACC_WIDTH - 8));
if ((phinc_val <= 255) && (phinc_val != 0)) begin
#(CLK_PRD * 256 * 10) $stop;
end else begin
$display("Error: value of phase increment is out of range! Stopped simulation.");
#1 $stop;
end
end
endmodule

23
src/phacc.sv Normal file
View File

@ -0,0 +1,23 @@
module phacc
#(
parameter unsigned WIDTH = 14
) (
input logic [7:0] phinc,
input clk,
input reset,
output [7:0] phase
);
logic [WIDTH - 1 : 0] sum;
always_ff @(posedge clk, negedge reset) begin
if (~reset) begin
sum <= 0;
end else begin
sum <= sum + phinc;
end
end
assign phase = sum[WIDTH - 1 : WIDTH - 8];
endmodule

23
src/sdmod.sv Executable file
View File

@ -0,0 +1,23 @@
module sdmod (
input signed [7:0] val,
input clk,
input reset,
output daco
);
logic out;
logic signed [7:0] eps;
logic signed [8:0] un;
always_ff @(posedge clk, negedge reset) begin
if (~reset) begin
un <= 9'd0;
end else begin
un <= val - eps;
end
end
assign out = (un >= $signed(9'd0)) ? 1'd1 : 1'd0;
assign eps = (un >= $signed(9'd0)) ? $signed(9'd127) - un : $signed(-9'd128) - un;
assign daco = out;
endmodule

37
src/sigdel.sv Executable file
View File

@ -0,0 +1,37 @@
//top-level module
module sigdel
#(
PHACC_WIDTH = 14
) (
//clock and reset
input logic clk, clr_n,
//control slave
input logic [31:0] wr_data,
input logic wr_n,
output logic fout
);
logic [7:0] phinc_val;
//control slave logic
always_ff @ (posedge clk or negedge clr_n) begin
if (!clr_n) begin
phinc_val[7:0] <= 8'd0;
end else begin
if (!wr_n) begin
phinc_val[7:0] <= wr_data[31:0];
end
end
end
phacc phacc_inst (.phinc(phinc_val), .clk(clk), .reset(clr_n), .phase(phase));
defparam phacc_inst.WIDTH = PHACC_WIDTH;
sinelut sinelut_inst (
.address (phase), .clock (clk), .q(sine)
);
sdmod sdmod_inst (
.val(sine), .clk(clk), .reset(clr_n), .daco(fout)
);
endmodule

76
src/sigdel_tb.sv Executable file
View File

@ -0,0 +1,76 @@
`timescale 1 ns/1 ns
module sigdel_tb();
// Parameters
localparam CLK_PRD = 20;
localparam SAMPLES_PRD = 256;
localparam OVERSAMPLING = 4;
localparam PHACC_WIDTH = 14;
// Wires and variables to connect to UUT (unit under test)
logic clk, clr_n, wr_n;
logic [31:0] wr_data;
logic [31:0] phinc_val;
logic fout;
// Instantiate UUT and connect used ports
sigdel dut(.clk(clk), .clr_n(clr_n), .wr_n(wr_n), .wr_data(wr_data), .fout(fout));
defparam dut.PHACC_WIDTH = PHACC_WIDTH;
// Clock definition
initial begin
clk = 0;
forever #(CLK_PRD/2) clk = ~clk;
end
// Reset and initial values definition
initial begin
clr_n = 0;
wr_n = 1;
wr_data = 'bx;
#(CLK_PRD*5) clr_n = 1;
end
// Bus write transaction simulation
initial begin
// Wait until system is out of reset
@(posedge clr_n);
// Check if phase increment for required accumulator width
// and oversamlpling ratio will fit in 8 bits
phinc_val=(2**(PHACC_WIDTH-8))/OVERSAMPLING;
if ((phinc_val <= 255) && (phinc_val != 0)) begin
// Write phase increment several clock cycles after reset
#(CLK_PRD*3) write_transaction(phinc_val);
// Wait for one sine period (for 14-bit phase accumulator case)
#(CLK_PRD*SAMPLES_PRD*OVERSAMPLING)
#(CLK_PRD*3) write_transaction(phinc_val*5);
#(CLK_PRD*SAMPLES_PRD*OVERSAMPLING)
$stop;
end else begin
//Output simulation error
$display("Error: value of phase increment is out of range! Stopped simulation.");
//Stop simulation (small delay needed for $display to work)
#1 $stop;
end
end
//Single write transaction task
task write_transaction;
//input signals
input [31:0] val;
//transaction implementation
begin
@(posedge clk);
//assert signals for one clock cycle
wr_n = 0;
wr_data = val;
@(posedge clk);
//deassert signals
wr_n = 1;
wr_data = 'bx;
end
endtask
endmodule