wip lr4 report
|
@ -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}
|
||||
|
|
|
@ -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 |
|
@ -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 |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 83 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 5.5 KiB |
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|