{"id":75,"date":"2009-10-28T11:48:22","date_gmt":"2009-10-28T19:48:22","guid":{"rendered":"http:\/\/www.beyond-circuits.com\/wordpress\/?p=75"},"modified":"2016-10-11T13:59:21","modified_gmt":"2016-10-11T21:59:21","slug":"verilog-functions-in-xilinx-xst","status":"publish","type":"post","link":"https:\/\/www.beyond-circuits.com\/wordpress\/2009\/10\/verilog-functions-in-xilinx-xst\/","title":{"rendered":"Verilog functions in Xilinx XST"},"content":{"rendered":"<h2>A nice idea<\/h2>\n<p>The XST documentation says that Verilog functions are fully supported. I was frustrated\u00a0today to discover that this is not the case. I was trying to make a library for handling fixed point arithmetic. Module instantiation overhead in Verilog is quite high in terms of lines of code and excess verbiage. All the code I need to use is combinational, so the natural thing to do is have one module with all my functions and parameters which control the representation of the fixed point numbers. After this,\u00a0I can make instances of the library module with the various fixed point representations I need and use the functions.<\/p>\n<p>So I whip out the following:<\/p>\n<pre><code>\r\nmodule SignedInteger\r\n    parameter out_int = 1;\r\n    parameter out_frac = 1;\r\n    parameter in_a_int = out_int;\r\n    parameter in_a_frac = out_frac;\r\n    parameter in_b_int = in_a_int;\r\n    parameter in_b_frac = in_a_frac;\r\n    parameter out_width = out_int+out_frac;\r\n    parameter in_a_width = in_a_int+in_a_frac;\r\n    parameter in_b_width = in_b_int+in_b_frac;\r\n\r\n    function signed [out_width-1:0] sum;\r\n    input signed [in_a_width-1:0] a;\r\n    input signed [in_b_width-1:0] b;\r\n    begin\r\n      if (in_a_frac &gt; in_b_frac)\r\n\tsum = a + (b&lt;&lt;(in_a_frac-in_b_frac));\r\n      else\r\n\tsum = (a&lt;&lt;(in_b_frac-in_a_frac)) + b;\r\n    end\r\n  endfunction\r\n\r\nendmodule\r\n<\/code><\/pre>\n<p>Now I can instantiate <em>SignedInteger<\/em> in another module and call the <em>sum<\/em> function. I need the function in another module because I may have multiple instances of <em>SignedInteger<\/em> in the calling module with different parameter values\u2013 sort of a poor man&#8217;s class mechanism. Everything simulates just peachy. Now, I synthesize a test case in XST.<\/p>\n<h2>Prepare to crash and burn<\/h2>\n<p>I&#8217;ll spare you the details, but XST has a number of issues with doing things like this, though the first few are not insurmountable. XST will first error out because I used concatenation instead of shift operators in the sum function. XST didn&#8217;t like the fact that\u00a0one of the concatenation multipliers was negative. I got boxed into a corner here by Verilog too, because you can&#8217;t use a generate inside a function, and if I use a generate outside the function, it makes it really hard to call the function from outside the module. So, we&#8217;ll go back to the drawing board and use the shift operator. Next, XST believes that modules need at least one port. My guess is that the people who wrote XST never thought about just using a module as a container for its tasks and functions. Hmm&#8230; it&#8217;s not great, but I can add a port that I won&#8217;t use.<\/p>\n<p>At this point, I&#8217;m faced with an interesting error message:<\/p>\n<pre><code>\r\nAnalyzing top module .\r\nERROR:Xst:917 - Undeclared signal .\r\nERROR:Xst:2083 - \"test.v\" line 29: Unsupported range for function.\r\n<\/code><\/pre>\n<p>What do you mean, undeclared signal <em>out_width<\/em>? Firstly, it&#8217;s not a signal and secondly, it is <em>so<\/em> declared. The second message gives me pause. Crap\u2013 it really thinks that <em>out_width<\/em> is a signal. Why can&#8217;t it see it?<\/p>\n<h2>An experiment<\/h2>\n<p>Time for a test case. I try to synthesize this module, and guess what? It compiles without errors.<\/p>\n<pre><code>\r\nmodule test2\r\n  (\r\n   input signed [15:0] a,\r\n   input signed [15:0] b,\r\n   output signed [19:0] sum\r\n   );\r\n\r\n  localparam out_width = 20;\r\n  localparam in_a_width = 16;\r\n  localparam in_a_frac = 0;\r\n  localparam in_b_width = 16;\r\n  localparam in_b_frac = 4;\r\n\r\n  SignedInteger #(16,4,16,0,12,4) si_16_4_16_0_12_4(.value());\r\n\r\n  assign sum = si_16_4_16_0_12_4.sum(a,b);\r\nendmodule\r\n<\/code><\/pre>\n<p>If I give it the parameters it is looking for, the errors go away. I do get some strange warnings, however&#8230;<\/p>\n<pre><code>\r\nWARNING:Xst:616 - Invalid property \"out_width 00000014\": Did not attach to si_16_4_16_0_12_4.\r\nWARNING:Xst:616 - Invalid property \"in_a_frac 00000000\": Did not attach to si_16_4_16_0_12_4.\r\nWARNING:Xst:616 - Invalid property \"in_a_int 00000010\": Did not attach to si_16_4_16_0_12_4.\r\nWARNING:Xst:616 - Invalid property \"in_a_width 00000010\": Did not attach to si_16_4_16_0_12_4.\r\nWARNING:Xst:616 - Invalid property \"in_b_frac 00000004\": Did not attach to si_16_4_16_0_12_4.\r\nWARNING:Xst:616 - Invalid property \"in_b_int 0000000C\": Did not attach to si_16_4_16_0_12_4.\r\nWARNING:Xst:616 - Invalid property \"in_b_width 00000010\": Did not attach to si_16_4_16_0_12_4.\r\nWARNING:Xst:616 - Invalid property \"out_frac 00000004\": Did not attach to si_16_4_16_0_12_4.\r\nWARNING:Xst:616 - Invalid property \"out_int 00000010\": Did not attach to si_16_4_16_0_12_4.\r\n<\/code><\/pre>\n<p>Not sure what that means exactly, but it sounds like something is rotten with the parameters.<\/p>\n<h2>Incorrect logic<\/h2>\n<p>Now this could cause incorrect logic to be synthesized. So I tried this test case.<\/p>\n<pre><code>\r\nmodule sub(empty);\r\n  output empty;\r\n  parameter paramvalue = 1;\r\n\r\n  assign empty = 0;\r\n  function [3:0] myparam_plus;\r\n    input [3:0] in;\r\n    begin\r\n      myparam_plus = paramvalue + in;\r\n    end\r\n  endfunction\r\nendmodule \/\/ sub\r\n\r\nmodule test3(value,empty);\r\n  output [3:0] value;\r\n  output empty;\r\n  parameter paramvalue = 10;\r\n  sub #(2) mysub(.empty(empty));\r\n  assign value = mysub.myparam_plus(3);\r\nendmodule\r\n<\/code><\/pre>\n<p>The <em>value<\/em> output is a constant 5. That is, the <em>sub<\/em> module has a <em>paramvalue<\/em> of 2 and we add 3 to it. XST synthesizes this with no errors, warnings, or infos. The module is totally clean. Even so, the netlist it produces gives <em>value<\/em> a constant output of 13. Let&#8217;s see Xilinx support try to squirm their way out of this one. This seems like a bug to me.<\/p>\n<p>At any rate, I have to give up on a pure Verilog solution to a fixed point library. Time to use\u00a0Perl.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A nice idea The XST documentation says that Verilog functions are fully supported. I was frustrated\u00a0today to discover that this is not the case. I was trying to make a library for handling fixed point arithmetic. Module instantiation overhead in &hellip; <a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/2009\/10\/verilog-functions-in-xilinx-xst\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,3,4,5],"tags":[],"class_list":["post-75","post","type-post","status-publish","format-standard","hentry","category-fpga","category-hdl","category-verilog","category-xilinx"],"_links":{"self":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/posts\/75","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/comments?post=75"}],"version-history":[{"count":11,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/posts\/75\/revisions"}],"predecessor-version":[{"id":1141,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/posts\/75\/revisions\/1141"}],"wp:attachment":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/media?parent=75"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/categories?post=75"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/tags?post=75"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}