diff --git a/.gitignore b/.gitignore index d1dede4..b963f95 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,6 @@ *.o *.ghw -*.gtkw work-*.cf svg-inkscape/ diff --git a/vhdl_intro/counter_gtkwave.png b/vhdl_intro/counter_gtkwave.png new file mode 100644 index 0000000..67d89cc Binary files /dev/null and b/vhdl_intro/counter_gtkwave.png differ diff --git a/vhdl_intro/d_flip_flop.pdf_tex b/vhdl_intro/d_flip_flop.pdf_tex deleted file mode 100644 index 653435a..0000000 --- a/vhdl_intro/d_flip_flop.pdf_tex +++ /dev/null @@ -1,62 +0,0 @@ -%% Creator: Inkscape inkscape 0.92.4, www.inkscape.org -%% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010 -%% Accompanies image file 'd_flip_flop.pdf' (pdf, eps, ps) -%% -%% To include the image in your LaTeX document, write -%% \input{.pdf_tex} -%% instead of -%% \includegraphics{.pdf} -%% To scale the image, write -%% \def\svgwidth{} -%% \input{.pdf_tex} -%% instead of -%% \includegraphics[width=]{.pdf} -%% -%% Images with a different path to the parent latex file can -%% be accessed with the `import' package (which may need to be -%% installed) using -%% \usepackage{import} -%% in the preamble, and then including the image with -%% \import{}{.pdf_tex} -%% Alternatively, one can specify -%% \graphicspath{{/}} -%% -%% For more information, please see info/svg-inkscape on CTAN: -%% http://tug.ctan.org/tex-archive/info/svg-inkscape -%% -\begingroup% - \makeatletter% - \providecommand\color[2][]{% - \errmessage{(Inkscape) Color is used for the text in Inkscape, but the package 'color.sty' is not loaded}% - \renewcommand\color[2][]{}% - }% - \providecommand\transparent[1]{% - \errmessage{(Inkscape) Transparency is used (non-zero) for the text in Inkscape, but the package 'transparent.sty' is not loaded}% - \renewcommand\transparent[1]{}% - }% - \providecommand\rotatebox[2]{#2}% - \newcommand*\fsize{\dimexpr\f@size pt\relax}% - \newcommand*\lineheight[1]{\fontsize{\fsize}{#1\fsize}\selectfont}% - \ifx\svgwidth\undefined% - \setlength{\unitlength}{67.5bp}% - \ifx\svgscale\undefined% - \relax% - \else% - \setlength{\unitlength}{\unitlength * \real{\svgscale}}% - \fi% - \else% - \setlength{\unitlength}{\svgwidth}% - \fi% - \global\let\svgwidth\undefined% - \global\let\svgscale\undefined% - \makeatother% - \begin{picture}(1,0.88888888)% - \lineheight{1}% - \setlength\tabcolsep{0pt}% - \put(0,0){\includegraphics[width=\unitlength,page=1]{d_flip_flop.pdf}}% - \put(0.24113854,0.61362848){\color[rgb]{0,0,0}\makebox(0,0)[lt]{\lineheight{0}\smash{\begin{tabular}[t]{l}D\end{tabular}}}}% - \put(0.76564026,0.61111112){\color[rgb]{0,0,0}\makebox(0,0)[rt]{\lineheight{0}\smash{\begin{tabular}[t]{r}Q\end{tabular}}}}% - \put(0.76472863,0.16666667){\color[rgb]{0,0,0}\makebox(0,0)[rt]{\lineheight{0}\smash{\begin{tabular}[t]{r}Q\end{tabular}}}}% - \put(0.24113854,0.16666667){\color[rgb]{0,0,0}\makebox(0,0)[lt]{\lineheight{0}\smash{\begin{tabular}[t]{l}E\end{tabular}}}}% - \end{picture}% -\endgroup% diff --git a/vhdl_intro/d_flip_flop.svg b/vhdl_intro/d_flip_flop.svg deleted file mode 100644 index 173783c..0000000 --- a/vhdl_intro/d_flip_flop.svg +++ /dev/null @@ -1,165 +0,0 @@ - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - D - Q - Q - E - - diff --git a/vhdl_intro/flipflop_gtkwave.png b/vhdl_intro/flipflop_gtkwave.png deleted file mode 100644 index a849b4c..0000000 Binary files a/vhdl_intro/flipflop_gtkwave.png and /dev/null differ diff --git a/vhdl_intro/vhdl/.gitignore b/vhdl_intro/vhdl/.gitignore new file mode 100644 index 0000000..e9fe0fd --- /dev/null +++ b/vhdl_intro/vhdl/.gitignore @@ -0,0 +1,5 @@ +*.json +*.fasm +*.frames +*.bit +counter_tb diff --git a/vhdl_intro/vhdl/counter.vhd b/vhdl_intro/vhdl/counter.vhd new file mode 100644 index 0000000..5daf97c --- /dev/null +++ b/vhdl_intro/vhdl/counter.vhd @@ -0,0 +1,33 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity counter is + port ( + clk : in std_logic; + reset : in std_logic; + enable : in std_logic; + direction : in std_logic; + + count_out : out std_logic_vector(7 downto 0) + ); +end counter; + +architecture behaviour of counter is + signal count : unsigned(7 downto 0) := (others => '0'); +begin + proc: process(clk) + begin + if reset then + count <= (others => '0'); + elsif rising_edge(clk) and enable = '1' then + if direction = '1' then + count <= count + 1; + else + count <= count - 1; + end if; + end if; + end process; + + count_out <= std_logic_vector(count); +end behaviour; diff --git a/vhdl_intro/vhdl/counter.xdc b/vhdl_intro/vhdl/counter.xdc new file mode 100644 index 0000000..3a06215 --- /dev/null +++ b/vhdl_intro/vhdl/counter.xdc @@ -0,0 +1,27 @@ +set_property LOC D9 [get_ports clk] +set_property LOC C9 [get_ports reset] +set_property LOC A8 [get_ports enable] +set_property LOC C11 [get_ports direction] + +set_property LOC F6 [get_ports count_out[0]] +set_property LOC J4 [get_ports count_out[1]] +set_property LOC J2 [get_ports count_out[2]] +set_property LOC H6 [get_ports count_out[3]] +set_property LOC H5 [get_ports count_out[4]] +set_property LOC J5 [get_ports count_out[5]] +set_property LOC T9 [get_ports count_out[6]] +set_property LOC T10 [get_ports count_out[7]] + +set_property IOSTANDARD LVCMOS33 [get_ports clk] +set_property IOSTANDARD LVCMOS33 [get_ports reset] +set_property IOSTANDARD LVCMOS33 [get_ports enable] +set_property IOSTANDARD LVCMOS33 [get_ports direction] +set_property IOSTANDARD LVCMOS33 [get_ports count_out[0]] +set_property IOSTANDARD LVCMOS33 [get_ports count_out[1]] +set_property IOSTANDARD LVCMOS33 [get_ports count_out[2]] +set_property IOSTANDARD LVCMOS33 [get_ports count_out[3]] +set_property IOSTANDARD LVCMOS33 [get_ports count_out[4]] +set_property IOSTANDARD LVCMOS33 [get_ports count_out[5]] +set_property IOSTANDARD LVCMOS33 [get_ports count_out[6]] +set_property IOSTANDARD LVCMOS33 [get_ports count_out[7]] + diff --git a/vhdl_intro/vhdl/counter_tb.gtkw b/vhdl_intro/vhdl/counter_tb.gtkw new file mode 100644 index 0000000..b0f2cee --- /dev/null +++ b/vhdl_intro/vhdl/counter_tb.gtkw @@ -0,0 +1,30 @@ +[*] +[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI +[*] Fri Mar 6 16:40:57 2020 +[*] +[dumpfile] "/home/xiretza/Nextcloud/School/Diplomarbeit/Diplomschrift/vhdl_intro/vhdl/counter_tb.ghw" +[dumpfile_mtime] "Fri Mar 6 16:40:14 2020" +[dumpfile_size] 814 +[savefile] "/home/xiretza/Nextcloud/School/Diplomarbeit/Diplomschrift/vhdl_intro/vhdl/counter_tb.gtkw" +[timestart] 0 +[size] 910 543 +[pos] 357 86 +*-25.819012 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] top. +[treeopen] top.counter_tb. +[treeopen] top.counter_tb.uut. +[sst_width] 221 +[signals_width] 169 +[sst_expanded] 1 +[sst_vpaned_height] 125 +@28 +top.counter_tb.uut.clk +top.counter_tb.uut.reset +top.counter_tb.uut.enable +top.counter_tb.uut.direction +@200 +- +@24 +#{top.counter_tb.count_out[7:0]} top.counter_tb.count_out[7] top.counter_tb.count_out[6] top.counter_tb.count_out[5] top.counter_tb.count_out[4] top.counter_tb.count_out[3] top.counter_tb.count_out[2] top.counter_tb.count_out[1] top.counter_tb.count_out[0] +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/vhdl_intro/vhdl/counter_tb.vhd b/vhdl_intro/vhdl/counter_tb.vhd new file mode 100644 index 0000000..b48619e --- /dev/null +++ b/vhdl_intro/vhdl/counter_tb.vhd @@ -0,0 +1,71 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity counter_tb is +end counter_tb; + +architecture test of counter_tb is + signal clk, reset, enable, direction : std_logic; + signal s_count_out : std_logic_vector(7 downto 0); + + signal count_out : unsigned(7 downto 0); +begin + uut: entity work.counter + port map ( + clk => clk, + reset => reset, + enable => enable, + direction => direction, + + count_out => s_count_out + ); + + count_out <= unsigned(s_count_out); + + simulate: process + begin + clk <= '0'; + reset <= '1'; + enable <= '0'; + + wait for 30 ns; + assert count_out = 0; + + reset <= '0'; + + clk <= '0'; + wait for 10 ns; + clk <= '1'; + wait for 10 ns; + + assert count_out = 0; + + enable <= '1'; + direction <= '0'; + + clk <= '0'; + wait for 10 ns; + clk <= '1'; + wait for 10 ns; + + assert count_out = 255; + + direction <= '1'; + + clk <= '0'; + wait for 10 ns; + clk <= '1'; + wait for 10 ns; + + clk <= '0'; + wait for 10 ns; + clk <= '1'; + wait for 10 ns; + + assert count_out = 1; + + wait for 30 ns; + wait; + end process; +end test; diff --git a/vhdl_intro/vhdl/flipflop.vhd b/vhdl_intro/vhdl/flipflop.vhd deleted file mode 100644 index b48e244..0000000 --- a/vhdl_intro/vhdl/flipflop.vhd +++ /dev/null @@ -1,25 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; - -entity flipflop is - port ( - d : in std_logic; - e : in std_logic; - q : out std_logic; - q_n : out std_logic - ); -end entity; - -architecture rtl of flipflop is - signal state : std_logic; -begin - store: process(e) - begin - if rising_edge(e) then - state <= d; - end if; - end process; - - q <= state; - q_n <= not state; -end architecture; diff --git a/vhdl_intro/vhdl/flipflop_tb b/vhdl_intro/vhdl/flipflop_tb deleted file mode 100755 index f101e92..0000000 Binary files a/vhdl_intro/vhdl/flipflop_tb and /dev/null differ diff --git a/vhdl_intro/vhdl/flipflop_tb.vhd b/vhdl_intro/vhdl/flipflop_tb.vhd deleted file mode 100644 index dcdce40..0000000 --- a/vhdl_intro/vhdl/flipflop_tb.vhd +++ /dev/null @@ -1,44 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; - -entity flipflop_tb is -end entity; - -architecture test of flipflop_tb is - signal s_d, s_e, s_q : std_logic; -begin - uut: entity work.flipflop - port map ( - d => s_d, - e => s_e, - q => s_q - ); - - simulate: process - begin - s_d <= '0'; - s_e <= '0'; - - wait for 100 ns; - - s_e <= '1'; - wait for 10 ns; - s_e <= '0'; - - assert s_q = '0'; - - wait for 50 ns; - s_d <= '1'; - wait for 50 ns; - - assert s_q = '0'; - - s_e <= '1'; - wait for 10 ns; - s_e <= '0'; - assert s_q = '1'; - - wait for 100 ns; - wait; - end process; -end architecture; diff --git a/vhdl_intro/vhdl_intro.tex b/vhdl_intro/vhdl_intro.tex index ce3c35d..b2da496 100644 --- a/vhdl_intro/vhdl_intro.tex +++ b/vhdl_intro/vhdl_intro.tex @@ -11,42 +11,64 @@ Other than a text editor, the following Free Software packages have to be instal \begin{savenotes} \begin{description} - \item[\icode{ghdl}\footnote{\url{https://github.com/ghdl/ghdl}}] to compile and simulate the design - \item[\icode{gtkwave}\footnote{\url{http://gtkwave.sourceforge.net/}}] to view the generated waveform files - \item[GNU \icode{make}] to coordinate simulating designs, compiling firmware and generating images - \item[\icode{python}] for helper scripts + \item[\icode{ghdl}\footnote{\url{https://github.com/ghdl/ghdl}}] to analyze, compile, and simulate the design + \item[\icode{gtkwave}\footnote{\url{http://gtkwave.sourceforge.net/}}] to view the simulation waveform files + \item[\icode{yosys}\footnote{\url{http://www.clifford.at/yosys/}}] to synthesize the design + \item[\icode{nextpnr-xilinx}\footnote{\url{https://github.com/daveshah1/nextpnr-xilinx}}] to place and route the design + \item[\icode{Project X-Ray}\footnote{\url{https://github.com/SymbiFlow/prjxray}}] for FPGA layout data and bitstream tools + \item[\icode{xc3sprog}\footnote{\url{https://sourceforge.net/projects/xc3sprog/}}] to load the bitstream onto the FPGA \end{description} \end{savenotes} \section{Creating a design} -A simple starting design is a D flip flop: +A simple starting design is an up/down counter. The following VHDL code describes the device: -\def\svgwidth{2cm} -\input{d_flip_flop.pdf_tex} - -The following VHDL code describes the device: - -\lstinputlisting[title=\texttt{flipflop.vhd}]{vhdl/flipflop.vhd} +\lstinputlisting[title=\texttt{counter.vhd}]{vhdl/counter.vhd} In order to test this design, a test bench has to be created: -\lstinputlisting[title=\texttt{flipflop\_tb.vhd}]{vhdl/flipflop_tb.vhd} +\lstinputlisting[title=\texttt{counter\_tb.vhd}]{vhdl/counter_tb.vhd} \section{Simulating a design} \begin{lstlisting}[style=default,language=sh] # analyze the design files -ghdl -a *.vhd +ghdl -a --std=08 *.vhd # elaborate the test bench entity -ghdl -e flipflop_tb +ghdl -e --std=08 counter_tb # run the test bench, saving the signal trace to a GHW file -ghdl -r flipflop_tb --wave=flipflop_tb.ghw -# open the trace with gtkwave -gtkwave flipflop_tb.ghw +ghdl -r --std=08 counter_tb --wave=counter_tb.ghw +# open the trace with gtkwave (using the view configuration in counter_tb.gtkw) +gtkwave counter_tb.ghw counter_tb.gtkw \end{lstlisting} \begin{center} -\includegraphics[width=\textwidth]{flipflop_gtkwave.png} +\includegraphics[width=\textwidth]{counter_gtkwave.png} \end{center} + +\section{Synthesizing a design} + +An additional Xilinx Design Constraints (XDC) file is required to assign the signals to pins on the FPGA: + +\lstinputlisting[style=default,title=\texttt{counter.xdc}]{vhdl/counter.xdc} + +\begin{lstlisting}[style=default,language=sh] +# synthesize with yosys +yosys -m ghdl.so -p ' + ghdl --std=08 counter.vhd -e counter; + synth_xilinx -flatten; + write_json counter.json' +# place and route the design with nextpnr +nextpnr-xilinx --chipdb xc7a35tcsg324-1.bin --xdc counter.xdc --json counter.json --fasm counter.fasm +# convert the FPGA assembly to frames +fasm2frames.py --part xc7a35tcsg324-1 counter.fasm counter.frames +# convert the frames to a bitstream +xc7frames2bit --part-name xc7a35tcsg324-1 --frm-file counter.frames --output-file counter.bit +# upload the bitstream to the FPGA +xc3sprog -c nexys4 counter.bit +\end{lstlisting} + +The current value of the counter is displayed in binary on the eight LEDs on the board. When switch 0 (enable) is in the high position, the counter can be advanced using button 0, with the direction set by switch 1. Button 1 resets the counter to zero. + \end{document}