{"id":673,"date":"2013-04-11T07:22:41","date_gmt":"2013-04-11T12:22:41","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/?p=673"},"modified":"2017-02-06T13:11:16","modified_gmt":"2017-02-06T18:11:16","slug":"matlab-to-fpga-using-hdl-codertm","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2013\/04\/11\/matlab-to-fpga-using-hdl-codertm\/","title":{"rendered":"MATLAB to FPGA using HDL Coder(TM)"},"content":{"rendered":"<div class=\"content\"><!--introduction--><p>It's my pleasure to introduce guest blogger Kiran Kintali. Kiran is the product development lead for <a href=\"https:\/\/www.mathworks.com\/products\/hdl-coder\">HDL Coder<\/a> at MathWorks. In this post, Kiran introduces a new capability in HDL Coder&#8482; that generates synthesizable VHDL\/Verilog code directly from MATLAB and highlights some of the key features of this new MATLAB based workflow.<\/p><!--\/introduction--><h3>Contents<\/h3><div><ul><li><a href=\"#70424a2f-088b-4758-8de0-5fac5103cdcd\">Introduction to HDL Code Generation from MATLAB<\/a><\/li><li><a href=\"#91a6f507-30f4-41eb-9876-b2d47f392316\">MATLAB to Hardware Workflow<\/a><\/li><li><a href=\"#ae2259c5-71e6-4582-ae3c-dd8824b7a4f5\">Example MATLAB Algorithm<\/a><\/li><li><a href=\"#e5de1a1f-d9cb-4b08-9982-2f47f2c5d4e2\">Example MATLAB Test Bench<\/a><\/li><li><a href=\"#eb8b6ef6-825c-43f1-8ea0-8d9f9ed13006\">HDL Workflow Advisor<\/a><\/li><li><a href=\"#d1cf933b-d17d-4d81-8d56-2a0f984df493\">Design Space Exploration and Optimization Options<\/a><\/li><li><a href=\"#08ade249-3944-44d2-95db-db0d7060c5de\">Best Practices<\/a><\/li><li><a href=\"#cdf41669-3ba0-44ac-8908-22d323960590\">Conclusion<\/a><\/li><\/ul><\/div><h4>Introduction to HDL Code Generation from MATLAB<a name=\"70424a2f-088b-4758-8de0-5fac5103cdcd\"><\/a><\/h4><p>If you are using MATLAB to model digital signal processing (DSP) or video and image processing algorithms that eventually end up in FPGAs or ASICs, read on...<\/p><p>FPGAs provide a good compromise between general purpose processors (GPPs) and application specific integrated circuits (ASICs). GPPs are fully programmable but are less efficient in terms of power and performance; ASICs implement dedicated functionality and show the best power and performance characteristics, but require extremely expensive design validation and implementation cycles. FPGAs are also used for prototyping in ASIC workflows for hardware verification and early software development.<\/p><p>Due to the order of magnitude performance improvement when running high-throughput, high-performance applications, algorithm designers are increasingly using FPGAs to prototype and validate their innovations instead of using traditional processors. However, many of the algorithms are implemented in MATLAB due to the simple-to-use programming model and rich analysis and visualization capabilities. When targeting FPGAs or ASICs these MATLAB algorithms have to be manually translated to HDL.<\/p><p>For many algorithm developers who are well-versed with software programming paradigms, mastering the FPGA design workflow is a challenge. Unlike software algorithm development, hardware development requires them to <b><i>think parallel<\/i><\/b>. Other obstacles include: learning the VHDL or Verilog language, mastering IDEs from FPGA vendors, and understanding esoteric terms like \"multi-cycle path\" and \"delay balancing\".<\/p><p>In this post, I describe an easier path from MATLAB to FPGAs. I will show how you can automatically generate HDL code from your MATLAB algorithm, implement the HDL code on an FPGA, and use MATLAB to verify your HDL code.<\/p><h4>MATLAB to Hardware Workflow<a name=\"91a6f507-30f4-41eb-9876-b2d47f392316\"><\/a><\/h4><p>The process of translating MATLAB designs to hardware consists of the following steps:<\/p><div><ol><li>Model your algorithm in MATLAB - use MATLAB to simulate, debug, and iteratively test and optimize the design.<\/li><li>Generate HDL code - automatically create HDL code for FPGA prototyping.<\/li><li>Verify HDL code - reuse your MATLAB test bench to verify the generated HDL code.<\/li><li>Create and verify FPGA prototype - implement and verify your design on FPGAs.<\/li><\/ol><\/div><p>There are some unique challenges in translating MATLAB to hardware. MATLAB code is procedural and can be highly abstract; it can use floating-point data and has no notion of time. Complex loops can be inferred from matrix operations and toolbox functions.<\/p><p>Implementing MATLAB code in hardware involves:<\/p><div><ul><li>Converting floating-point MATLAB code to fixed-point MATLAB code with optimized bit widths suitable for efficient hardware generation.<\/li><li>Identifying and mapping procedural constructs to concurrent area- and speed-optimized hardware operations.<\/li><li>Introducing the concept of time by adding clocks and clock rates to schedule the operations in hardware.<\/li><li>Creating resource-shared architectures to implement expensive operators like multipliers and for-loop bodies.<\/li><li>Mapping large persistent arrays to block RAM in hardware<\/li><\/ul><\/div><p>HDL Coder&#8482; simplifies the above tasks though workflow automation.<\/p><h4>Example MATLAB Algorithm<a name=\"ae2259c5-71e6-4582-ae3c-dd8824b7a4f5\"><\/a><\/h4><p>Let&#8217;s take a MATLAB function implementing histogram equalization and go through this workflow. This algorithm, implemented in MATLAB, enhances image contrast by transforming the values in an intensity image so that the histogram of the output image is approximately flat.<\/p><p><i>type mlhdlc_heq.m<\/i><\/p><pre class=\"language-matlab\"><span class=\"comment\">% Histogram Equalization Algorithm<\/span>\r\n<span class=\"keyword\">function<\/span> [pixel_out] = mlhdlc_heq(x_in, y_in, pixel_in, width, height)\r\n<\/pre><pre class=\"language-matlab\"><span class=\"keyword\">persistent<\/span> histogram\r\n<span class=\"keyword\">persistent<\/span> transferFunc\r\n<span class=\"keyword\">persistent<\/span> histInd\r\n<span class=\"keyword\">persistent<\/span> cumSum\r\n<\/pre><pre class=\"language-matlab\"><span class=\"keyword\">if<\/span> isempty(histogram)\r\n    histogram = zeros(1, 2^8);\r\n    transferFunc = zeros(1, 2^8);\r\n    histInd = 0;\r\n    cumSum = 0;\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><pre class=\"language-matlab\"><span class=\"comment\">% Figure out indices based on where we are in the frame<\/span>\r\n<span class=\"keyword\">if<\/span> y_in &lt; height &amp;&amp; x_in &lt; width <span class=\"comment\">% valid pixel data<\/span>\r\n    histInd = pixel_in + 1;\r\n<span class=\"keyword\">elseif<\/span> y_in == height &amp;&amp; x_in == 0 <span class=\"comment\">% first column of height+1<\/span>\r\n    histInd = 1;\r\n<span class=\"keyword\">elseif<\/span> y_in &gt;= height <span class=\"comment\">% vertical blanking period<\/span>\r\n    histInd = min(histInd + 1, 2^8);\r\n<span class=\"keyword\">elseif<\/span> y_in &lt; height <span class=\"comment\">% horizontal blanking - do nothing<\/span>\r\n    histInd = 1;\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><pre class=\"language-matlab\"><span class=\"comment\">%Read histogram<\/span>\r\nhistValRead = histogram(histInd);\r\n<\/pre><pre class=\"language-matlab\"><span class=\"comment\">%Read transfer function<\/span>\r\ntransValRead = transferFunc(histInd);\r\n<\/pre><pre class=\"language-matlab\"><span class=\"comment\">%If valid part of frame add one to pixel bin and keep transfer func val<\/span>\r\n<span class=\"keyword\">if<\/span> y_in &lt; height &amp;&amp; x_in &lt; width\r\n    histValWrite = histValRead + 1; <span class=\"comment\">%Add pixel to bin<\/span>\r\n    transValWrite = transValRead; <span class=\"comment\">%Write back same value<\/span>\r\n    cumSum = 0;\r\n<span class=\"keyword\">elseif<\/span> y_in &gt;= height <span class=\"comment\">%In blanking time index through all bins and reset to zero<\/span>\r\n    histValWrite = 0;\r\n    transValWrite = cumSum + histValRead;\r\n    cumSum = transValWrite;\r\n<span class=\"keyword\">else<\/span>\r\n    histValWrite = histValRead;\r\n    transValWrite = transValRead;\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><pre class=\"language-matlab\"><span class=\"comment\">%Write histogram<\/span>\r\nhistogram(histInd) = histValWrite;\r\n<\/pre><pre class=\"language-matlab\"><span class=\"comment\">%Write transfer function<\/span>\r\ntransferFunc(histInd) = transValWrite;\r\n<\/pre><pre class=\"language-matlab\">pixel_out = transValRead;\r\n<\/pre><h4>Example MATLAB Test Bench<a name=\"e5de1a1f-d9cb-4b08-9982-2f47f2c5d4e2\"><\/a><\/h4><p>Here is the test bench that verifies that the algorithm works with an example image. (Note that this testbench uses Image Processing Toolbox functions for reading the original image and plotting the transformed image after equalization.)<\/p><p><i>type mlhdlc_heq_tb.m<\/i><\/p><pre class=\"language-matlab\"><span class=\"comment\">%% Test bench for Histogram Equalization Algorithm<\/span>\r\nclear <span class=\"string\">mlhdlc_heq<\/span>;\r\ntestFile = <span class=\"string\">'office.png'<\/span>;\r\nRGB = imread(testFile);\r\n<\/pre><pre class=\"language-matlab\"><span class=\"comment\">% Get intensity part of color image<\/span>\r\nYCBCR = rgb2ycbcr(RGB);\r\nimgOrig = YCBCR(:,:,1);\r\n<\/pre><pre class=\"language-matlab\">[height, width] = size(imgOrig);\r\nimgOut = zeros(height,width);\r\nhBlank = 20;\r\n<span class=\"comment\">% make sure we have enough vertical blanking to filter the histogram<\/span>\r\nvBlank = ceil(2^14\/(width+hBlank));\r\n<\/pre><pre class=\"language-matlab\"><span class=\"keyword\">for<\/span> frame = 1:2\r\n    disp([<span class=\"string\">'working on frame: '<\/span>, num2str(frame)]);\r\n    <span class=\"keyword\">for<\/span> y_in = 0:height+vBlank-1\r\n        <span class=\"comment\">%disp(['frame: ', num2str(frame), ' of 2, row: ', num2str(y_in)]);<\/span>\r\n        <span class=\"keyword\">for<\/span> x_in = 0:width+hBlank-1\r\n            <span class=\"keyword\">if<\/span> x_in &lt; width &amp;&amp; y_in &lt; height\r\n                pixel_in = double(imgOrig(y_in+1, x_in+1));\r\n            <span class=\"keyword\">else<\/span>\r\n                pixel_in = 0;\r\n            <span class=\"keyword\">end<\/span>\r\n<\/pre><pre>             [pixel_out] = mlhdlc_heq(x_in, y_in, pixel_in, width, height);<\/pre><pre>             if x_in &lt; width &amp;&amp; y_in &lt; height\r\n                 imgOut(y_in+1,x_in+1) = pixel_out;\r\n             end\r\n         end\r\n     end\r\n end<\/pre><pre class=\"language-matlab\"><span class=\"comment\">% Make color image from equalized intensity image<\/span>\r\n<span class=\"comment\">% Rescale image<\/span>\r\nimgOut = double(imgOut);\r\nimgOut(:) = imgOut\/max(imgOut(:));\r\nimgOut = uint8(imgOut*255);\r\n<\/pre><pre class=\"language-matlab\">YCBCR(:,:,1) = imgOut;\r\nRGBOut = ycbcr2rgb(YCBCR);\r\n<\/pre><pre class=\"language-matlab\">figure(1)\r\nsubplot(2,2,1); imshow(RGB, []);\r\ntitle(<span class=\"string\">'Original Image'<\/span>);\r\nsubplot(2,2,2); imshow(RGBOut, []);\r\ntitle(<span class=\"string\">'Equalized Image'<\/span>);\r\nsubplot(2,2,3); hist(double(imgOrig(:)),2^14-1);\r\ntitle(<span class=\"string\">'Histogram of original Image'<\/span>);\r\nsubplot(2,2,4); hist(double(imgOut(:)),2^14-1);\r\ntitle(<span class=\"string\">'Histogram of equalized Image'<\/span>);\r\n<\/pre><p>Let's simulate this algorithm to see the results.<\/p><pre class=\"codeinput\">mlhdlc_heq_tb\r\n<\/pre><pre class=\"codeoutput\">working on frame: 1\r\nworking on frame: 2\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2013\/ml2hdlBlog_01.png\" alt=\"\"> <h4>HDL Workflow Advisor<a name=\"eb8b6ef6-825c-43f1-8ea0-8d9f9ed13006\"><\/a><\/h4><p>The HDL Workflow Advisor (see the snapshot below) helps automate the steps and provides a guided path from MATLAB to hardware. You can see the following key steps of the workflow in the left pane of the workflow advisor:<\/p><div><ol><li>Fixed-Point Conversion<\/li><li>HDL Code Generation<\/li><li>HDL Verification<\/li><li>HDL Synthesis and Analysis<\/li><\/ol><\/div><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2013\/hdlwfa.png\" alt=\"\"> <\/p><p>Let's look at each workflow step in detail.<\/p><p><b>Fixed-Point Conversion<\/b><\/p><p>Signal processing applications are typically implemented using floating-point operations in MATLAB. However, for power, cost, and performance reasons, these algorithms need to be converted to use fixed-point operations when targeting hardware. Fixed-point conversion can be very challenging and time-consuming, typically demanding 25 to 50 percent of the total design and implementation time.  The automatic floating-point to fixed-point conversion workflow in HDL Coder&#8482; can greatly simplify and accelerate this conversion process.<\/p><p>The floating-point to fixed-point conversion workflow consists of the following steps:<\/p><div><ol><li>Verify that the floating-point design is compatible with code generation.<\/li><li>Propose fixed-point types based on computed ranges, either through the simulation of the testbench or through static analysis that propagates design ranges to compute derived ranges for all the variables.<\/li><li>Generate fixed-point MATLAB code by applying proposed fixed-point types.<\/li><li>Verify the generated fixed-point code and compare the numerical accuracy of the generated fixed-point code with the original floating point code.<\/li><\/ol><\/div><p>Note that this step is optional. You can skip this step if your MATLAB design is already implemented in fixed-point.<\/p><p><b>HDL Code Generation<\/b><\/p><p>The HDL Code Generation step generates HDL code from the fixed-point MATLAB code. You can generate either VHDL or Verilog code that implements your MATLAB design. In addition to generating synthesizable HDL code, HDL Coder&#8482; also generates various reports, including a traceability report that helps you navigate between your MATLAB code and the generated HDL code, and a resource utilization report that shows you, at the algorithm level, approximately what hardware resources are needed to implement the design, in terms of adders, multipliers, and RAMs.<\/p><p>During code generation, you can specify various optimization options to explore the design space without having to modify your algorithm. In the Design Space Exploration and Optimization Options section below, you can see how you can modify code generation options and optimize your design for speed or area.<\/p><p><b>HDL Verification<\/b><\/p><p>Standalone HDL test bench generation:<\/p><p>HDL Coder&#8482; generates VHDL and Verilog test benches from your MATLAB scripts for rapid verification of generated HDL code. You can customize an HDL test bench using a variety of options that apply stimuli to the HDL code. You can also generate script files to automate the process of compiling and simulating your code in HDL simulators. These steps help to ensure the results of MATLAB simulation match the results of HDL simulation.<\/p><p>HDL Coder&#8482; also works with <a href=\"https:\/\/www.mathworks.com\/products\/hdl-verifier\">HDL Verifier<\/a> to automatically generate two types of cosimulation testbenches:<\/p><div><ul><li>HDL cosimulation-based verification works with Mentor Graphics&reg; ModelSim&reg; and QuestaSim&reg;, where MATLAB and HDL simulation happen in lockstep.<\/li><li>FPGA-in-the-Loop simulation allows you to run a MATLAB simulation with an FPGA board in strict synchronization. You can use MATLAB to feed real world data into your design on the FPGA, and ensure that the algorithm will behave as expected when implemented in hardware.<\/li><\/ul><\/div><p><b>HDL Synthesis<\/b><\/p><p>Apart from the language-related challenges, programming for FPGAs requires the use of complex EDA tools. Generating a bitstream from the HDL design and programming the FPGA can be daunting tasks. HDL Coder&#8482; provides automation here, by creating project files for Xilinx&reg; and Altera&reg; that are configured with the generated HDL code. You can use the workflow steps to synthesize the HDL code within the MATLAB environment, see the results of synthesis, and iterate on the MATLAB design to improve synthesis results.<\/p><h4>Design Space Exploration and Optimization Options<a name=\"d1cf933b-d17d-4d81-8d56-2a0f984df493\"><\/a><\/h4><p>HDL Coder&#8482; provides the following optimizations to help you explore the design space trade-offs between area and speed. You can use these options to explore various architectures and trade-offs without having to manually rewrite your algorithm.<\/p><p><b>Speed Optimizations<\/b><\/p><div><ul><li><b>Pipelining<\/b> : To improve the design&#8217;s clock frequency, HDL Coder enables you to insert pipeline registers in various locations within your design. For example, you can insert registers at the design inputs and outputs, and also at the output of a given MATLAB variable in your algorithm.<\/li><li><b>Distributed Pipelining<\/b> : HDL Coder also provides an optimization based on retiming to automatically move pipeline registers you have inserted to maximize clock frequency, by minimizing the delay through combinational paths in your design.<\/li><\/ul><\/div><p><b>Area Optimizations<\/b><\/p><div><ul><li><b>RAM mapping<\/b>: HDL Coder&#8482; maps matrices to wires or registers in hardware. If persistent matrix variables are mapped to registers, they can take up a large amount of FPGA area. HDL Coder&#8482; automatically maps persistent matrices to block RAM to improve area efficiency. The challenge in mapping MATLAB matrices to block RAM is that block RAM in hardware typically has a limited set of read and write ports. HDL Coder&#8482; solves this problem by automatically partitioning and scheduling the matrix reads and writes to honor the block RAM&#8217;s port constraints, while still honoring the other control- and data-dependencies in the design.<\/li><li><b>Resource sharing<\/b>: This optimization identifies functionally equivalent multiplier operations in MATLAB code and shares them. You can control the amount of multiplier sharing in the design.<\/li><li><b>Loop streaming<\/b>: A MATLAB for-loop creates a FOR_GENERATE loop in VHDL. The body of the loop is replicated as many times in hardware as the number of loop iterations. This results in an inefficient use of area. The loop streaming optimization creates a single hardware instance of the loop body that is time-multiplexed across loop iterations.<\/li><li><b>Constant multiplier optimization<\/b>: This design level optimization converts constant multipliers into shift and add operations using canonical signed digit (CSD) techniques.<\/li><\/ul><\/div><h4>Best Practices<a name=\"08ade249-3944-44d2-95db-db0d7060c5de\"><\/a><\/h4><p>Now, let's look at few best practices related to writing MATLAB code when targeting FPGAs.<\/p><p><b>When writing a MATLAB design:<\/b><\/p><div><ul><li>Use the code generation subset of MATLAB supported for HDL code generation.<\/li><li>Keep the top-level interface as simple as possible. The top-level function size, types, and complexity determine the interface of the chip implemented in hardware.<\/li><li>Do not pass in a big chunk of parallel data into the design. Parallel data requires a large number of IO pins on the chip, and would probably not be synthesizable.  In a typical image processing design, you should serialize the pixels as inputs and buffer them internally in the algorithm.<\/li><\/ul><\/div><p><b>When writing a MATLAB test bench:<\/b><\/p><div><ul><li>Call the design from the testbench function.<\/li><li>Exercise the design thoroughly. This is particularly important for floating-point to fixed-point conversion, where HDL Coder&#8482; determines the ranges of the variables in the algorithm based on the values the testbench assigns to the variables. You can reuse this testbench to generate an HDL testbench for testing the generated hardware.<\/li><li>Simulate the design with the testbench prior to code generation to make sure there are no simulation errors, and to make sure all the required files are on the path.<\/li><\/ul><\/div><h4>Conclusion<a name=\"cdf41669-3ba0-44ac-8908-22d323960590\"><\/a><\/h4><p>HDL Coder&#8482; provides a seamless workflow when you want to implement your algorithm in an FPGA. In this post, I have shown you how to take an image processing algorithm written in MATLAB, convert it to fixed-point, generate HDL code, verify the generated HDL code using the test bench, and finally, synthesize the design and implement it in hardware.<\/p><p>See this <a href=\"https:\/\/www.mathworks.com\/company\/user_stories\/flir-accelerates-development-of-thermal-imaging-fpga.html\">article<\/a> about how one of the HDL Coder customers, FLIR has used MATLAB to HDL workflow to achieve good results. You can also learn more about this workflow using the product examples <a href=\"https:\/\/www.mathworks.com\/products\/hdl-coder\/code-examples.html\">located here.<\/a><\/p><p>We hope this brief introduction to the HDL Coder&#8482; and MATLAB-to-HDL code generation, verification framework has shown how you can quickly get started on implementing your MATLAB designs and target FPGAs. Please let us know in the comments for this post how you might use this new functionality. Or, if you've already tried using HDL Coder&#8482;, let us know about your experiences <a href=\"https:\/\/blogs.mathworks.com\/loren\/?p=673#respond\">here<\/a>.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_62189eb44b6e46ffafdbf080e751390b() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='62189eb44b6e46ffafdbf080e751390b ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 62189eb44b6e46ffafdbf080e751390b';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2013 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_62189eb44b6e46ffafdbf080e751390b()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2013a<br><\/p><p class=\"footer\"><br>\r\n      Published with MATLAB&reg; R2013a<br><\/p><\/div><!--\r\n62189eb44b6e46ffafdbf080e751390b ##### SOURCE BEGIN #####\r\n%% MATLAB to FPGA using HDL Coder(TM)\r\n% It's my pleasure to introduce guest blogger Kiran Kintali. Kiran is the\r\n% product development lead for <https:\/\/www.mathworks.com\/products\/hdl-coder\r\n% HDL Coder> at MathWorks. In this post, Kiran introduces a new capability\r\n% in HDL Coder(TM) that generates synthesizable VHDL\/Verilog code directly\r\n% from MATLAB and highlights some of the key features of this new MATLAB\r\n% based workflow.\r\n\r\n%% Introduction to HDL Code Generation from MATLAB\r\n% If you are using MATLAB to model digital signal processing (DSP) or video\r\n% and image processing algorithms that eventually end up in FPGAs or ASICs,\r\n% read on...\r\n%% \r\n% FPGAs provide a good compromise between general purpose processors (GPPs)\r\n% and application specific integrated circuits (ASICs). GPPs are fully\r\n% programmable but are less efficient in terms of power and performance;\r\n% ASICs implement dedicated functionality and show the best power and\r\n% performance characteristics, but require extremely expensive design\r\n% validation and implementation cycles. FPGAs are also used for prototyping\r\n% in ASIC workflows for hardware verification and early software\r\n% development.\r\n%%\r\n% Due to the order of magnitude performance improvement when running\r\n% high-throughput, high-performance applications, algorithm designers are\r\n% increasingly using FPGAs to prototype and validate their innovations\r\n% instead of using traditional processors. However, many of the algorithms\r\n% are implemented in MATLAB due to the simple-to-use programming model and\r\n% rich analysis and visualization capabilities. When targeting FPGAs or\r\n% ASICs these MATLAB algorithms have to be manually translated to HDL.\r\n%\r\n%% \r\n% For many algorithm developers who are well-versed with software\r\n% programming paradigms, mastering the FPGA design workflow is a challenge.\r\n% Unlike software algorithm development, hardware development requires them\r\n% to *_think parallel_*. Other obstacles include: learning the VHDL or\r\n% Verilog language, mastering IDEs from FPGA vendors, and understanding\r\n% esoteric terms like \"multi-cycle path\" and \"delay balancing\".\r\n%%\r\n% In this post, I describe an easier path from MATLAB to FPGAs. I will show\r\n% how you can automatically generate HDL code from your MATLAB algorithm,\r\n% implement the HDL code on an FPGA, and use MATLAB to verify your HDL\r\n% code.\r\n\r\n%% MATLAB to Hardware Workflow\r\n% The process of translating MATLAB designs to hardware consists of the\r\n% following steps:\r\n%\r\n% # Model your algorithm in MATLAB - use MATLAB to simulate, debug, and\r\n% iteratively test and optimize the design.\r\n% # Generate HDL code - automatically create HDL code for FPGA prototyping.\r\n% # Verify HDL code - reuse your MATLAB test bench to verify the generated\r\n% HDL code.\r\n% # Create and verify FPGA prototype - implement and verify your design on\r\n% FPGAs.\r\n%\r\n% There are some unique challenges in translating MATLAB to hardware.\r\n% MATLAB code is procedural and can be highly abstract; it can use\r\n% floating-point data and has no notion of time. Complex loops can be\r\n% inferred from matrix operations and toolbox functions.\r\n%\r\n% Implementing MATLAB code in hardware involves:\r\n%\r\n% * Converting floating-point MATLAB code to fixed-point MATLAB code with\r\n% optimized bit widths suitable for efficient hardware generation.\r\n% * Identifying and mapping procedural constructs to concurrent area- and\r\n% speed-optimized hardware operations.\r\n% * Introducing the concept of time by adding clocks and clock rates to\r\n% schedule the operations in hardware.\r\n% * Creating resource-shared architectures to implement expensive operators\r\n% like multipliers and for-loop bodies.\r\n% * Mapping large persistent arrays to block RAM in hardware\r\n%\r\n% HDL Coder(TM) simplifies the above tasks though workflow automation.\r\n\r\n%% Example MATLAB Algorithm\r\n% Let\u00e2\u20ac\u2122s take a MATLAB function implementing histogram equalization and go\r\n% through this workflow. This algorithm, implemented in MATLAB, enhances\r\n% image contrast by transforming the values in an intensity image so that\r\n% the histogram of the output image is approximately flat.\r\n%%\r\n% \r\n% _type mlhdlc_heq.m_ \r\n%% \r\n%   % Histogram Equalization Algorithm\r\n%   function [pixel_out] = mlhdlc_heq(x_in, y_in, pixel_in, width, height)\r\n%   \r\n%   persistent histogram\r\n%   persistent transferFunc\r\n%   persistent histInd\r\n%   persistent cumSum\r\n%   \r\n%   if isempty(histogram)\r\n%       histogram = zeros(1, 2^8);\r\n%       transferFunc = zeros(1, 2^8);\r\n%       histInd = 0;\r\n%       cumSum = 0;\r\n%   end\r\n%   \r\n%   % Figure out indices based on where we are in the frame\r\n%   if y_in < height && x_in < width % valid pixel data\r\n%       histInd = pixel_in + 1;\r\n%   elseif y_in == height && x_in == 0 % first column of height+1\r\n%       histInd = 1;\r\n%   elseif y_in >= height % vertical blanking period\r\n%       histInd = min(histInd + 1, 2^8);\r\n%   elseif y_in < height % horizontal blanking - do nothing\r\n%       histInd = 1;\r\n%   end\r\n%   \r\n%   %Read histogram\r\n%   histValRead = histogram(histInd);\r\n%   \r\n%   %Read transfer function\r\n%   transValRead = transferFunc(histInd);\r\n%   \r\n%   %If valid part of frame add one to pixel bin and keep transfer func val\r\n%   if y_in < height && x_in < width\r\n%       histValWrite = histValRead + 1; %Add pixel to bin\r\n%       transValWrite = transValRead; %Write back same value\r\n%       cumSum = 0;\r\n%   elseif y_in >= height %In blanking time index through all bins and reset to zero\r\n%       histValWrite = 0;\r\n%       transValWrite = cumSum + histValRead;\r\n%       cumSum = transValWrite;\r\n%   else\r\n%       histValWrite = histValRead;\r\n%       transValWrite = transValRead;\r\n%   end\r\n%   \r\n%   %Write histogram\r\n%   histogram(histInd) = histValWrite;\r\n%   \r\n%   %Write transfer function\r\n%   transferFunc(histInd) = transValWrite;\r\n%   \r\n%   pixel_out = transValRead;\r\n%   \r\n\r\n%% Example MATLAB Test Bench\r\n% Here is the test bench that verifies that the algorithm works with an\r\n% example image. (Note that this testbench uses Image Processing Toolbox\r\n% functions for reading the original image and plotting the transformed\r\n% image after equalization.)\r\n%%\r\n% \r\n% _type mlhdlc_heq_tb.m_ \r\n%%\r\n%   %% Test bench for Histogram Equalization Algorithm\r\n%   clear mlhdlc_heq;\r\n%   testFile = 'office.png';\r\n%   RGB = imread(testFile);\r\n%   \r\n%   % Get intensity part of color image\r\n%   YCBCR = rgb2ycbcr(RGB);\r\n%   imgOrig = YCBCR(:,:,1);\r\n%   \r\n%   [height, width] = size(imgOrig);\r\n%   imgOut = zeros(height,width);\r\n%   hBlank = 20;\r\n%   % make sure we have enough vertical blanking to filter the histogram\r\n%   vBlank = ceil(2^14\/(width+hBlank));\r\n%   \r\n%   for frame = 1:2\r\n%       disp(['working on frame: ', num2str(frame)]);\r\n%       for y_in = 0:height+vBlank-1\r\n%           %disp(['frame: ', num2str(frame), ' of 2, row: ', num2str(y_in)]);\r\n%           for x_in = 0:width+hBlank-1\r\n%               if x_in < width && y_in < height\r\n%                   pixel_in = double(imgOrig(y_in+1, x_in+1));\r\n%               else\r\n%                   pixel_in = 0;\r\n%               end\r\n%               \r\n%               [pixel_out] = mlhdlc_heq(x_in, y_in, pixel_in, width, height);\r\n%                          \r\n%               if x_in < width && y_in < height\r\n%                   imgOut(y_in+1,x_in+1) = pixel_out;\r\n%               end\r\n%           end\r\n%       end\r\n%   end\r\n%   \r\n%   % Make color image from equalized intensity image   \r\n%   % Rescale image\r\n%   imgOut = double(imgOut);\r\n%   imgOut(:) = imgOut\/max(imgOut(:));\r\n%   imgOut = uint8(imgOut*255);\r\n%   \r\n%   YCBCR(:,:,1) = imgOut;\r\n%   RGBOut = ycbcr2rgb(YCBCR);\r\n%   \r\n%   figure(1)\r\n%   subplot(2,2,1); imshow(RGB, []);\r\n%   title('Original Image');\r\n%   subplot(2,2,2); imshow(RGBOut, []);\r\n%   title('Equalized Image');\r\n%   subplot(2,2,3); hist(double(imgOrig(:)),2^14-1);\r\n%   title('Histogram of original Image');\r\n%   subplot(2,2,4); hist(double(imgOut(:)),2^14-1);\r\n%   title('Histogram of equalized Image');\r\n\r\n%%\r\n% Let's simulate this algorithm to see the results.\r\nmlhdlc_heq_tb\r\n\r\n%% HDL Workflow Advisor\r\n% The HDL Workflow Advisor (see the snapshot below) helps automate the\r\n% steps and provides a guided path from MATLAB to hardware. You can see the\r\n% following key steps of the workflow in the left pane of the workflow\r\n% advisor:\r\n%\r\n% # Fixed-Point Conversion\r\n% # HDL Code Generation\r\n% # HDL Verification\r\n% # HDL Synthesis and Analysis\r\n%\r\n% <<hdlwfa.png>>\r\n%\r\n%\r\n% Let's look at each workflow step in detail.\r\n% \r\n% *Fixed-Point Conversion*\r\n%\r\n% Signal processing applications are typically implemented using\r\n% floating-point operations in MATLAB. However, for power, cost, and\r\n% performance reasons, these algorithms need to be converted to use\r\n% fixed-point operations when targeting hardware. Fixed-point conversion\r\n% can be very challenging and time-consuming, typically demanding 25 to 50\r\n% percent of the total design and implementation time.  The automatic\r\n% floating-point to fixed-point conversion workflow in HDL Coder(TM) can\r\n% greatly simplify and accelerate this conversion process.\r\n%\r\n% The floating-point to fixed-point conversion workflow consists of the\r\n% following steps:\r\n%\r\n% # Verify that the floating-point design is compatible with code\r\n% generation.\r\n% # Propose fixed-point types based on computed ranges, either through the\r\n% simulation of the testbench or through static analysis that propagates\r\n% design ranges to compute derived ranges for all the variables.\r\n% # Generate fixed-point MATLAB code by applying proposed fixed-point\r\n% types.\r\n% # Verify the generated fixed-point code and compare the numerical\r\n% accuracy of the generated fixed-point code with the original floating\r\n% point code.\r\n%\r\n% Note that this step is optional. You can skip this step if your MATLAB\r\n% design is already implemented in fixed-point.\r\n%\r\n% *HDL Code Generation*\r\n%\r\n% The HDL Code Generation step generates HDL code from the fixed-point\r\n% MATLAB code. You can generate either VHDL or Verilog code that implements\r\n% your MATLAB design. In addition to generating synthesizable HDL code, HDL\r\n% Coder(TM) also generates various reports, including a traceability report\r\n% that helps you navigate between your MATLAB code and the generated HDL\r\n% code, and a resource utilization report that shows you, at the algorithm\r\n% level, approximately what hardware resources are needed to implement the\r\n% design, in terms of adders, multipliers, and RAMs.\r\n%\r\n% During code generation, you can specify various optimization options to\r\n% explore the design space without having to modify your algorithm. In the\r\n% Design Space Exploration and Optimization Options section below, you can\r\n% see how you can modify code generation options and optimize your design\r\n% for speed or area.\r\n%\r\n% *HDL Verification*\r\n% \r\n% Standalone HDL test bench generation:\r\n%\r\n% HDL Coder(TM) generates VHDL and Verilog test benches from your MATLAB\r\n% scripts for rapid verification of generated HDL code. You can customize\r\n% an HDL test bench using a variety of options that apply stimuli to the\r\n% HDL code. You can also generate script files to automate the process of\r\n% compiling and simulating your code in HDL simulators. These steps help to\r\n% ensure the results of MATLAB simulation match the results of HDL\r\n% simulation.\r\n%\r\n% HDL Coder(TM) also works with\r\n% <https:\/\/www.mathworks.com\/products\/hdl-verifier HDL Verifier> to\r\n% automatically generate two types of cosimulation testbenches:\r\n%\r\n% * HDL cosimulation-based verification works with Mentor Graphics(R)\r\n% ModelSim(R) and QuestaSim(R), where MATLAB and HDL simulation happen in\r\n% lockstep.\r\n% * FPGA-in-the-Loop simulation allows you to run a MATLAB simulation with\r\n% an FPGA board in strict synchronization. You can use MATLAB to feed real\r\n% world data into your design on the FPGA, and ensure that the algorithm\r\n% will behave as expected when implemented in hardware.\r\n%\r\n% *HDL Synthesis*\r\n%\r\n% Apart from the language-related challenges, programming for FPGAs\r\n% requires the use of complex EDA tools. Generating a bitstream from the\r\n% HDL design and programming the FPGA can be daunting tasks. HDL Coder(TM)\r\n% provides automation here, by creating project files for Xilinx(R) and\r\n% Altera(R) that are configured with the generated HDL code. You can use\r\n% the workflow steps to synthesize the HDL code within the MATLAB\r\n% environment, see the results of synthesis, and iterate on the MATLAB\r\n% design to improve synthesis results.\r\n\r\n%% Design Space Exploration and Optimization Options\r\n% HDL Coder(TM) provides the following optimizations to help you explore\r\n% the design space trade-offs between area and speed. You can use these\r\n% options to explore various architectures and trade-offs without having to\r\n% manually rewrite your algorithm.\r\n%\r\n% *Speed Optimizations*\r\n%\r\n% * *Pipelining* : To improve the design\u00e2\u20ac\u2122s clock frequency, HDL Coder\r\n% enables you to insert pipeline registers in various locations within your\r\n% design. For example, you can insert registers at the design inputs and\r\n% outputs, and also at the output of a given MATLAB variable in your\r\n% algorithm.\r\n% * *Distributed Pipelining* : HDL Coder also provides an optimization\r\n% based on retiming to automatically move pipeline registers you have\r\n% inserted to maximize clock frequency, by minimizing the delay through\r\n% combinational paths in your design.\r\n%\r\n%\r\n% *Area Optimizations*\r\n%\r\n% * *RAM mapping*: HDL Coder(TM) maps matrices to wires or registers in\r\n% hardware. If persistent matrix variables are mapped to registers, they\r\n% can take up a large amount of FPGA area. HDL Coder(TM) automatically maps\r\n% persistent matrices to block RAM to improve area efficiency. The\r\n% challenge in mapping MATLAB matrices to block RAM is that block RAM in\r\n% hardware typically has a limited set of read and write ports. HDL\r\n% Coder(TM) solves this problem by automatically partitioning and\r\n% scheduling the matrix reads and writes to honor the block RAM\u00e2\u20ac\u2122s port\r\n% constraints, while still honoring the other control- and\r\n% data-dependencies in the design.\r\n% * *Resource sharing*: This optimization identifies functionally\r\n% equivalent multiplier operations in MATLAB code and shares them. You can\r\n% control the amount of multiplier sharing in the design.\r\n% * *Loop streaming*: A MATLAB for-loop creates a FOR_GENERATE loop in\r\n% VHDL. The body of the loop is replicated as many times in hardware as the\r\n% number of loop iterations. This results in an inefficient use of area.\r\n% The loop streaming optimization creates a single hardware instance of the\r\n% loop body that is time-multiplexed across loop iterations.\r\n% * *Constant multiplier optimization*: This design level optimization\r\n% converts constant multipliers into shift and add operations using\r\n% canonical signed digit (CSD) techniques.\r\n%\r\n\r\n%% Best Practices\r\n% Now, let's look at few best practices related to writing MATLAB code when\r\n% targeting FPGAs.\r\n%\r\n% *When writing a MATLAB design:*\r\n%\r\n% * Use the code generation subset of MATLAB supported for HDL code\r\n% generation.\r\n% * Keep the top-level interface as simple as possible. The top-level\r\n% function size, types, and complexity determine the interface of the chip\r\n% implemented in hardware.\r\n% * Do not pass in a big chunk of parallel data into the design. Parallel\r\n% data requires a large number of IO pins on the chip, and would probably\r\n% not be synthesizable.  In a typical image processing design, you should\r\n% serialize the pixels as inputs and buffer them internally in the\r\n% algorithm.\r\n%\r\n% *When writing a MATLAB test bench:*\r\n%\r\n% * Call the design from the testbench function.\r\n% * Exercise the design thoroughly. This is particularly important for\r\n% floating-point to fixed-point conversion, where HDL Coder(TM) determines\r\n% the ranges of the variables in the algorithm based on the values the\r\n% testbench assigns to the variables. You can reuse this testbench to\r\n% generate an HDL testbench for testing the generated hardware.\r\n% * Simulate the design with the testbench prior to code generation to make\r\n% sure there are no simulation errors, and to make sure all the required\r\n% files are on the path.\r\n\r\n%% Conclusion\r\n% HDL Coder(TM) provides a seamless workflow when you want to implement\r\n% your algorithm in an FPGA. In this post, I have shown you how to take an\r\n% image processing algorithm written in MATLAB, convert it to fixed-point,\r\n% generate HDL code, verify the generated HDL code using the test bench,\r\n% and finally, synthesize the design and implement it in hardware.\r\n%\r\n% See this\r\n% <https:\/\/www.mathworks.com\/company\/newsroom\/FLIR-Speeds-Thermal-Imaging-FPGA-Development-Through-Automatic-HDL-Generation-From-MATLAB.html\r\n% article> about how one of the HDL Coder customers, FLIR has used MATLAB\r\n% to HDL workflow to achieve good results. You can also learn more about\r\n% this workflow using the product examples\r\n% <https:\/\/www.mathworks.com\/products\/hdl-coder\/examples.html located here.>\r\n%\r\n% We hope this brief introduction to the HDL Coder(TM) and MATLAB-to-HDL\r\n% code generation, verification framework has shown how you can quickly get\r\n% started on implementing your MATLAB designs and target FPGAs. Please let\r\n% us know in the comments for this post how you might use this new\r\n% functionality. Or, if you've already tried using HDL Coder(TM), let us\r\n% know about your experiences\r\n% <https:\/\/blogs.mathworks.com\/loren\/?p=673#respond here>.\r\n%\r\n##### SOURCE END ##### 62189eb44b6e46ffafdbf080e751390b\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2013\/ml2hdlBlog_01.png\" onError=\"this.style.display ='none';\" \/><\/div><!--introduction--><p>It's my pleasure to introduce guest blogger Kiran Kintali. Kiran is the product development lead for <a href=\"https:\/\/www.mathworks.com\/products\/hdl-coder\">HDL Coder<\/a> at MathWorks. In this post, Kiran introduces a new capability in HDL Coder&#8482; that generates synthesizable VHDL\/Verilog code directly from MATLAB and highlights some of the key features of this new MATLAB based workflow.... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2013\/04\/11\/matlab-to-fpga-using-hdl-codertm\/\">read more >><\/a><\/p>","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[40],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/673"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/comments?post=673"}],"version-history":[{"count":8,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/673\/revisions"}],"predecessor-version":[{"id":2222,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/673\/revisions\/2222"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=673"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=673"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=673"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}