diff --git a/code/always_ff.svh b/code/always_ff.svh new file mode 100644 index 0000000..d7231ba --- /dev/null +++ b/code/always_ff.svh @@ -0,0 +1,20 @@ + + // not cumulative + always_ff @(posedge clk) begin + data1_q <= data1_q + 1; + data1_q <= data1_q + 1; + data1_q <= data1_q + 1; + data1_q <= data1_q + 1; + end + + // doesn't warn that there is no default case + always_ff @(posedge clk) begin + if (rst) + data2_q <= '0; + end + + // unclear whether this is a DFF or DFFE + always_ff @(posedge clk) begin + if ( pkg::func(data3_i) ) + data3_q <= data3_d; + end diff --git a/figures/always_ff.tex b/figures/always_ff.tex new file mode 100644 index 0000000..d91a563 --- /dev/null +++ b/figures/always_ff.tex @@ -0,0 +1,7 @@ + +\begin{figure}[t] + \centering + \inputminted[frame=single]{systemverilog}{code/always_ff.svh} + \caption{Potentially confusing behaviors of \mintinline{systemverilog}{always_ff} blocks} + \label{fig:always_ff} +\end{figure} diff --git a/figures/asicworld.pdf b/figures/asicworld.pdf new file mode 100644 index 0000000..908e173 Binary files /dev/null and b/figures/asicworld.pdf differ diff --git a/figures/asicworld.tex b/figures/asicworld.tex new file mode 100644 index 0000000..de0a122 --- /dev/null +++ b/figures/asicworld.tex @@ -0,0 +1,7 @@ + +\begin{figure}[t] + \centering + \frame{\includegraphics[width=\textwidth,height=0.9\textheight,keepaspectratio]{figures/asicworld.pdf}} + \caption{This is an example provided by ASIC World that encourages bad design practices \cite{asicworld}} + \label{fig:asicworld} +\end{figure} diff --git a/figures/chipdev_hack.pdf b/figures/chipdev_hack.pdf new file mode 100644 index 0000000..815a558 Binary files /dev/null and b/figures/chipdev_hack.pdf differ diff --git a/figures/chipdev_hack.tex b/figures/chipdev_hack.tex new file mode 100644 index 0000000..c10959e --- /dev/null +++ b/figures/chipdev_hack.tex @@ -0,0 +1,7 @@ + +\begin{figure}[t] + \centering + \frame{\includegraphics[width=0.9\linewidth]{figures/chipdev_hack.pdf}} + \caption{This example shows ChipDev \cite{ChipDev} incorrectly accepting this submission despite a potential mismatch between simulation and synthesis. For example, Verilator will override the \mintinline{systemverilog}{always_comb} with the \mintinline{systemverilog}{assign}, but Yosys will override the \mintinline{systemverilog}{assign} with the \mintinline{systemverilog}{always_comb}. This could be corrected if ChipDev chooses to incorporate a similar verification flow to what is outlined in \autoref{section:complex_tool_setups}.} + \label{fig:chipdev_hack} +\end{figure} diff --git a/figures/chipdev_questions.pdf b/figures/chipdev_questions.pdf new file mode 100644 index 0000000..ac10ca1 Binary files /dev/null and b/figures/chipdev_questions.pdf differ diff --git a/figures/chipdev_questions.tex b/figures/chipdev_questions.tex new file mode 100644 index 0000000..c977064 --- /dev/null +++ b/figures/chipdev_questions.tex @@ -0,0 +1,7 @@ + +\begin{figure}[t] + \centering + \frame{\includegraphics[width=0.7\linewidth]{figures/chipdev_questions.pdf}} + \caption{An example of questions that ChipDev offers. \cite{ChipDev}} + \label{fig:chipdev_questions} +\end{figure} diff --git a/tex/chapters/1_introduction.tex b/tex/chapters/1_introduction.tex index 983975d..20006ad 100644 --- a/tex/chapters/1_introduction.tex +++ b/tex/chapters/1_introduction.tex @@ -2,11 +2,11 @@ \chapter{Introduction} \label{chapter:introduction} -At the end of Dennard scaling, it may be tempting to think that VLSI and digital design are becoming less-important engineering fields. However, the United States government wouldn't agree, considering they are investing \$280 billion over the next ten years into the CHIPS Act. \cite{mckinsey} Similarly, TSMC, the world's leading semiconductor manufacturer, is expecting to open three new advanced-node fabs in 2024. \cite{taipeitimes} In addition, in 2020, Google started a partnership with GlobalFoundries, SkyWater Technology, and Efabless to provide fully open-source Process Design Kits (PDKs) and toolchains to lower the barrier of entry for new Silicon engineers. \cite{GooglePartnersWithSkyWater, googleSilicon} Investments like these have created a never-ending demand for chip developers, and Universities should be working to meet this demand. +At the end of Dennard scaling, it may be tempting to think that VLSI and digital design are becoming less-important engineering fields. However, the United States government wouldn't agree, considering they are investing \$280 billion over the next ten years into the CHIPS Act \cite{mckinsey}. Similarly, TSMC, the world's leading semiconductor manufacturer, is expecting to open three new advanced-node fabs in 2024 \cite{taipeitimes}. In addition, in 2020, Google started a partnership with GlobalFoundries, SkyWater Technology, and Efabless to provide fully open-source Process Design Kits (PDKs) and toolchains to lower the barrier of entry for new Silicon engineers \cite{GooglePartnersWithSkyWater, googleSilicon}. Investments like these have created a never-ending demand for chip developers, and Universities should be working to meet this demand. \input{figures/asic_flow} -In the semiconductor industry, the process of designing an application-specific integrated circuit (ASIC) follows a well-defined sequence, where each step requires training and practice. \cite{intelDesignFlow, anysiliconDesignFlow, kynixDesignFlow} The following presents an abbreviated flow tailored for students and open-source tool usage, as illustrated in \autoref{fig:asic_flow}. This process begins with the design phase, where engineers specify the functionality and requirements of the finished integrated circuit (IC). Then, they use hardware description languages (HDLs) like SystemVerilog to detail the circuit's operations and verify its correctness through simulation. After the HDL implementation passes a series of behavioral simulations, it is synthesized for the standard cell library of the target and paired with additional digital and mixed-signal IP blocks. Further testing can include running logical equivalence checks (LECs) to ensure the synthesized netlist is correct, rerunning the behavioral simulations on the synthesized netlist to check for reset behavior, or by running intensive simulations on an FPGA. Once these circuit-level tests pass, layout is completed according to timing constraints and design rule checks (DRC). If timing cannot be met, the layout or HDL implementation may need to be adjusted. Finally, after the layout and simulations checks pass, the design is converted into a Graphic Data Stream (GDS) file which is sent to a semiconductor foundry for mass-production. +In the semiconductor industry, the process of designing an application-specific integrated circuit (ASIC) follows a well-defined sequence, where each step requires training and practice \cite{intelDesignFlow, anysiliconDesignFlow, kynixDesignFlow}. The following presents an abbreviated flow tailored for students and open-source tool usage, as illustrated in \autoref{fig:asic_flow}. This process begins with the design phase, where engineers specify the functionality and requirements of the finished integrated circuit (IC). Then, they use hardware description languages (HDLs) like SystemVerilog to detail the circuit's operations and verify its correctness through simulation. After the HDL implementation passes a series of behavioral simulations, it is synthesized for the standard cell library of the target and paired with additional digital and mixed-signal IP blocks. Further testing can include running logical equivalence checks (LECs) to ensure the synthesized netlist is correct, rerunning the behavioral simulations on the synthesized netlist to check for reset behavior, or by running intensive simulations on an FPGA. Once these circuit-level tests pass, layout is completed according to timing constraints and design rule checks (DRC). If timing cannot be met, the layout or HDL implementation may need to be adjusted. Finally, after the layout and simulations checks pass, the design is converted into a Graphic Data Stream (GDS) file which is sent to a semiconductor foundry for mass-production. Because of how many skills are required to create an ASIC design it is crucial for Universities to offer a strong foundation for writing and working with HDLs to design hardware. Nevertheless, HDLs come with a formidable learning curve, partly due to the difficulties of distinguishing between what code is synthesizable (able to be converted into hardware) and what should be used solely for verification purposes. Additionally, the prevalence of bugs in common HDL tools, the extraordinary inaccessibility of proprietary tools, and the lack of reliable online educational resources are a major deterrent for students and hobbyists who wish to experiment with digital design on their own. Another factor contributing to the complexity is the interdisciplinary nature of ASIC design. For many students, especially those with a software background, this may be their first experience with hardware design, while hardware students must also transition into a more software-centric environment. Bridging this gap and understanding both aspects is vital in today's world of using computer-aided design (CAD) software to design hardware. Universities must recognize the formidable learning curve associated with HDLs and provide comprehensive educational resources, practical hands-on experiences, and interdisciplinary exposure to prepare students for the intricate realm of ASIC design. diff --git a/tex/chapters/2_open_source_tools.tex b/tex/chapters/2_open_source_tools.tex index 9846216..66065fb 100644 --- a/tex/chapters/2_open_source_tools.tex +++ b/tex/chapters/2_open_source_tools.tex @@ -6,7 +6,7 @@ \chapter{Advantages of Open-Source Tools in Education} \section{Proprietary tool prices deter students.} -Many students choose to pursue a degree in computer engineering due to the plethora of creative outlets that it introduces them to. Consider the hands-on process of purchasing affordable components and assembling circuits on breadboards. Likewise, platforms like Arduinos and Raspberry Pis are often explored alongside the utilization of programming languages such as C++, Python, and JavaScript. The accessibility and low cost of these mediums often foster self-directed learning. Similarly, introductory Verilog courses can serve as yet another avenue for creative expression, particularly when orchestrated using free and open-source tools. However, a significant obstruction emerges when proprietary alternatives such as Questa, VCS, and Xcelium, coupled with licensing fees over \$5,000, \cite{olofssonLatchUp, licensePricesReddit} become the focal point of a student's introduction to Verilog. Such financial barriers can easily deter enthusiasm for self-guided learning, particularly when students anticipate losing access to the software upon graduation. This is likely the reason why several students in UC Santa Barbara's Verilog courses choose to disobey the requirement of using ModelSim, and instead use Icarus and GTKWave. Students don't want to feel like their time is wasted learning a tool if they lose access to it upon graduation. +Many students choose to pursue a degree in computer engineering due to the plethora of creative outlets that it introduces them to. Consider the hands-on process of purchasing affordable components and assembling circuits on breadboards. Likewise, platforms like Arduinos and Raspberry Pis are often explored alongside the utilization of programming languages such as C++, Python, and JavaScript. The accessibility and low cost of these mediums often foster self-directed learning. Similarly, introductory Verilog courses can serve as yet another avenue for creative expression, particularly when orchestrated using free and open-source tools. However, a significant obstruction emerges when proprietary alternatives such as Questa, VCS, and Xcelium, coupled with licensing fees over \$5,000 \cite{olofssonLatchUp, licensePricesReddit}, become the focal point of a student's introduction to Verilog. Such financial barriers can easily deter enthusiasm for self-guided learning, particularly when students anticipate losing access to the software upon graduation. This is likely the reason why several students in UC Santa Barbara's Verilog courses choose to disobey the requirement of using ModelSim, and instead use Icarus and GTKWave. Students don't want to feel like their time is wasted learning a tool if they lose access to it upon graduation. \section{Open-source tools are easy to install.} diff --git a/tex/chapters/4_resources.tex b/tex/chapters/4_resources.tex index cdecbaf..41b6705 100644 --- a/tex/chapters/4_resources.tex +++ b/tex/chapters/4_resources.tex @@ -6,7 +6,7 @@ \chapter{Best Resources for Learning Synthesizable SystemVerilog} \section{Stuart Sutherland's synthesis guide is most valuable.} -``Synthesizing SystemVerilog: Busting the Myth that SystemVerilog is only for Verification'' by Stuart Sutherland and Don Mills acts as a comprehensive list of synthesizable SystemVerilog features. Despite the absence of an official SystemVerilog synthesis standard, this paper gives valuable insight into synthesizable language features, emphasizing their practical application into modern hardware designs. Sutherland and Mills surveyed the Synopsys tools Design Compiler and Synplify-Pro to trace the evolution of Verilog-1984 though SystemVerilog-2009 as a comprehensive hardware design and verification language. To assist students, I compiled a summary of Sutherland's synthesis guide which I shared with UCSB ECE 152A and ECE 154B students, [ref]. Providing both of these resources ensures that students receive a strong introduction to synthesizable Verilog syntax and best practices. +``Synthesizing SystemVerilog: Busting the Myth that SystemVerilog is only for Verification'' by Stuart Sutherland and Don Mills acts as a comprehensive list of synthesizable SystemVerilog features. Despite the absence of an official SystemVerilog synthesis standard, this paper gives valuable insight into synthesizable language features, emphasizing their practical application into modern hardware designs. Sutherland and Mills surveyed the Synopsys tools Design Compiler and Synplify-Pro to trace the evolution of Verilog-1984 though SystemVerilog-2009 as a comprehensive hardware design and verification language. To assist those working on ``Labs with CVA6'', I composed a summary of Sutherland's synthesis guide \cite{labsWithCVA6}. Since then, I have shared this summary with dozens of students looking to improve their understanding of synthesizable Verilog. Providing both Sutherland's guide and my summary ensures that students receive a strong introduction to synthesizable Verilog syntax and best practices. \section{Style guides record synthesizable features and best-practices.} @@ -18,8 +18,16 @@ \section{Verilog tutorial websites should be treated cautiously.} It is important to stress the importance of following the provided style guides for Verilog syntax over some of the most popular Verilog tutorial websites, such as ASIC World, Chipverify, and Nandland. Despite the user-friendly approach adopted by these websites, which mirror renowned programming tutorial platforms such as GeekforGeeks, Verilog tutorial websites often propagate misguided advice for novice hardware developers. While style-guides can act as a reference to well-verified practices for beginners and professionals alike, tutorial websites do not always teach current-day, synthesizable design syntax that is compatible with a multitude of tools. Only if students maintain adherence to the instructor-specified style-guides and the subset of synthesizable features, then tutorial websites can be used as resources. -For example, while a TA for ECE 152A, 154A, and 154B, the most prevalent misinformation they encouraged in students was to put combinational logic inside of \mintinline{systemverilog}{always_ff} blocks. [fig] The lowRISC Style Guide, the BSG SystemVerilog Coding Standards, and the IEEE 1364.1-2005 Verilog Synthesis Standard all recommend only putting resets, sets, and enables in \mintinline{systemverilog}{always_ff} blocks. [ref] Unnecessarily large \mintinline{systemverilog}{always_ff} blocks are prone to bugs because \mintinline{systemverilog}{always_ff} blocks don't offer warnings on unhandled code paths, blocking and nonblocking-assignment mismatches can lead to undefined behavior, and synthesis tools may incorrectly infer the incorrect type of flip-flop. (See Figure [fig]) In my experience teaching SystemVerilog, whenever a student asked for help solving a bug, but followed this design practice, I immediately asked them to separate the block into an \mintinline{systemverilog}{always_comb} and \mintinline{systemverilog}{always_ff}. Over half the time, that simple refactor incidentally fixed the student's bug. +\input{figures/asicworld} +\input{figures/always_ff} + +For example, while a TA for ECE 152A, 154A, and 154B, the most prevalent misinformation they encouraged in students was to put combinational logic inside of \mintinline{systemverilog}{always_ff} blocks. (See \autoref{fig:asicworld}). The lowRISC Style Guide, the BSG SystemVerilog Coding Standards, and the IEEE 1364.1-2005 Verilog Synthesis Standard all recommend only putting resets, sets, and enables in \mintinline{systemverilog}{always_ff} blocks \cite{lowRISCstyleguides, BSGstyleguide, 1364.1-2005}. Unnecessarily large \mintinline{systemverilog}{always_ff} blocks are prone to bugs because \mintinline{systemverilog}{always_ff} blocks don't offer warnings on unhandled code paths, blocking and nonblocking-assignment mismatches can lead to undefined behavior, and synthesis tools may incorrectly infer the incorrect type of flip-flop. (See \autoref{fig:always_ff}) In my experience teaching SystemVerilog, whenever a student asked for help solving a bug, but followed this design practice, I immediately asked them to separate the block into an \mintinline{systemverilog}{always_comb} and \mintinline{systemverilog}{always_ff}. Over half the time, that simple refactor incidentally fixed the student's bug. + +\FloatBarrier \section{ChipDev.io can be used to practice Verilog (if used effectively).} -The final resource I like to share with students is ChipDev.io, which offers an online collection of popular Verilog questions, paired with an online IDE and testbench. The 30+ questions range from implementing a shift register to designing an ALU. [fig] If students are looking for lots of practice questions as job interview preparation or to gain general practice, I always recommend ChipDev. Unfortunately, they do not run gate-level simulation or logical equivalence checks, so it may incorrectly reward answers that are unsynthesizable. [ref] Plus, after speaking with the ChipDev team, they notified me that synthesis was not on their priority list. Therefore, I strongly urge students to verify their answers with DigitalJS Online before feeling they have a mastery over the current question. +\input{figures/chipdev_questions} +\input{figures/chipdev_hack} + +The final resource I like to share with students is ChipDev.io, which offers an online collection of popular Verilog questions, paired with an online IDE and testbench. The 30+ questions range from implementing a shift register to designing an ALU; (see \autoref{fig:chipdev_questions}.) If students are looking for lots of practice questions as job interview preparation or for general practice, I always recommend ChipDev. However, ChipDev does not run gate-level simulation or logical equivalence checks, so bad submissions may be incorrectly rewarded; (see \autoref{fig:chipdev_hack}.) Plus, after speaking with the ChipDev team, they notified me that synthesis was not on their priority list. Therefore, I strongly urge students to verify their answers with DigitalJS Online or other synthesis tools before feeling they have a mastery over any question. diff --git a/tex/chapters/5_scalability.tex b/tex/chapters/5_scalability.tex index b4204e7..3440ae1 100644 --- a/tex/chapters/5_scalability.tex +++ b/tex/chapters/5_scalability.tex @@ -14,4 +14,4 @@ \section{Version control should be used in Verilog designs.} \section{SystemVerilog assertions and in-module verification are important.} -The final design strategy for promoting code scalability is to promote in-module verification. Waveform viewers are incredibly powerful and useful tools, but work best when supplemented with \mintinline{systemverilog}{$display} statements that have already identified where and when a simulation error occurred. Most SystemVerilog in industry designs is full of self-verifying modules by use of SystemVerilog assertions (SVA) and Universal Verification Methodology (UVM). Note that as of 9/10/23, since there is poor SVA and UVM support in open-source tools, many open-source projects have success using \mintinline{systemverilog}{`ifdef} macros to disable UVM and SVA calls on a per-tool basis, or projects only may use a subset of the features which are supported, or the projects resort to a basic always blocks instead. [fig] But no matter the specific implementation, in-module verification is a valuable design practice to teach students. In ECE 154A, ECE 154B, and ECE 152A, students were often required to design modules that incorporated simulation-only logic to test basic functionality. By adopting these universal standards, Verilog education becomes better aligned with real-world methodologies for enhanced scalability and proficiency. +The final design strategy for promoting code scalability is to promote in-module verification. Waveform viewers are incredibly powerful and useful tools, but work best when supplemented with \mintinline{systemverilog}{$display} statements that have already identified where and when a simulation error occurred. Most SystemVerilog in industry designs is full of self-verifying modules by use of SystemVerilog assertions (SVA) and Universal Verification Methodology (UVM). Note that as of 9/10/23, since there is poor SVA and UVM support in open-source tools, many open-source projects have success using \mintinline{systemverilog}{`ifdef} macros to disable UVM and SVA calls on a per-tool basis, or projects only may use a subset of the features which are supported, or the projects resort to a basic \mintinline{systemverilog}{always} blocks instead. [fig] But no matter the specific implementation, in-module verification is a valuable design practice to teach students. In ECE 154A, ECE 154B, and ECE 152A, students were often required to design modules that incorporated simulation-only logic to test basic functionality. By adopting these universal standards, Verilog education becomes better aligned with real-world methodologies for enhanced scalability and proficiency. diff --git a/tex/chapters/6_autograders.tex b/tex/chapters/6_autograders.tex index 5518385..19626ef 100644 --- a/tex/chapters/6_autograders.tex +++ b/tex/chapters/6_autograders.tex @@ -9,6 +9,7 @@ \section{Autograders offer instant, high-quality feedback.} Students are empowered to submit their code multiple times, enabling them to refine their solutions and learn from their mistakes in real time. This back-and-forth approach ensures that students can practice a Verilog concept and receive as much help as they need until they pass all the instructor-defined tests. Autograders fall under the educational approach known as ``Ungrading,'' where the emphasis shifts strongly toward providing valuable feedback over assigning traditional grades. In the autograders that I set up, it's worth noting that a significant majority of students eventually achieve a 100\% score by the assignment deadline. This phenomenon essentially transforms the grading system into a confidence-building mechanism rather than a competitive ranking system. Ungrading has been shown to help students by reducing stress, inspiring creativity, and encouraging healthy risk taking. [ref] However, arguably Ungrading's largest downside is that the instructor may not have time to provide personalized feedback to all students. [ref] Fortunately, an intrinsic attribute of software, (such as HDL implementations), is that code quality and correctness can be run with automatic, subjective computer algorithms. Therefore, by implementing autograders, Verilog educators can tap into this pedagogical insight extremely easily, offering students a more effective way to grasp digital design principles. \section{Autograders can run remotely without complex local-setup.} +\label{section:complex_tool_setups} When instructing students on crafting Verilog code that maintains accurate synthesizability across various platforms, it is essential to follow the industry standard of verifying a design with a wide selection of tools. Autograders streamline this process, making it accessible and efficient for students to perform comprehensive testing without the need for local installation. For example, the autograders that I created for ECE 152A, 154A, and 154B would consistently use anywhere from 6 to 10 different tools, sometimes requiring complex installation and setup procedures. Expecting students to complete these setup procedures is often tedious and counterproductive. Therefore, simply giving students access to a fully prepared autograder can remove the setup barrier completely. diff --git a/tex/thesis.bib b/tex/thesis.bib index f79c930..bafcae1 100644 --- a/tex/thesis.bib +++ b/tex/thesis.bib @@ -196,6 +196,15 @@ @article{1800-2017 note = {\doi{10.1109/IEEESTD.2018.8299595}} } +@article{1364.1-2005, + author = {IEEE}, + journal = {IEC 62142-2005 First edition 2005-06 IEEE Std 1364.1}, + title = {IEC/IEEE International Standard - Verilog(R) Register Transfer Level Synthesis}, + year = {2005}, + doi = {10.1109/IEEESTD.2005.339572}, + note = {\doi{10.1109/IEEESTD.2005.339572}} +} + @misc{DigitalJSOnline, author = {Marek Materzok}, title = {{D}igital{J}{S} {O}nline}, @@ -209,3 +218,32 @@ @misc{labsWithCVA6 howpublished = {\url{https://github.com/sifferman/labs-with-cva6}}, note = {[Accessed 18-09-2023]}, } + +@misc{lowRISCstyleguides, + author = {lowRISC}, + title = {low{R}{I}{S}{C} {S}tyle {G}uides}, + howpublished = {\url{https://github.com/lowRISC/style-guides/tree/master}}, + note = {[Accessed 19-09-2023]}, +} + +@misc{BSGstyleguide, + author = {Taylor, Michael and {The Bespoke Silicon Group}}, + title = {{B}{S}{G} {S}ystem{V}erilog {C}oding {S}tandards}, + howpublished = {\url{https://docs.google.com/document/d/1xA5XUzBtz_D6aSyIBQUwFk_kSUdckrfxa2uzGjMgmCU/}}, + note = {[Accessed 19-09-2023]}, +} + +@misc{asicworld, + author = {Deepak Kumar Tala and {ASIC World}}, + title = {{V}erilog {E}xamples}, + howpublished = {\url{https://www.asic-world.com/examples/verilog/}}, + year = {2014}, + note = {[Accessed 19-09-2023]}, +} + +@misc{ChipDev, + author = {ChipDev}, + title = {{C}hip{D}ev}, + howpublished = {\url{https://chipdev.io/}}, + note = {[Accessed 19-09-2023]}, +} diff --git a/tex/thesis.tex b/tex/thesis.tex index 11c7766..623e662 100644 --- a/tex/thesis.tex +++ b/tex/thesis.tex @@ -6,12 +6,13 @@ \usepackage[lofdepth,lotdepth,caption=false]{subfig} \usepackage{fancyhdr} \usepackage[hyphens]{url} -\usepackage{hyperref} -\usepackage{amsmath, amssymb, graphicx} -\usepackage{xspace} -\usepackage{braket} -\usepackage{color} -\usepackage{setspace} +% \usepackage{hyperref} +\usepackage{graphicx} +% \usepackage{amsmath, amssymb} +% \usepackage{xspace} +% \usepackage{braket} +% \usepackage{color} +% \usepackage{setspace} \usepackage{titlesec} \usepackage{soul} \usepackage[outputdir=build]{minted}