title: signed and unsigned fixed point multiplication in SystemVerilog
body: <p>I have a specific question and a request for more general guidance.</p>
  
  <p>My question is what is the cleanest way to multiply a signed number by an unsigned number in SystemVerilog?</p>
  
  <p>Below is a little test code that illustrates the problem. 'a' is the unsigned number. 'b' is the signed number. In order to produce a correct signed result SystemVerilog seems to require that both operands of the multiplication be signed. To make that work here I had to add an extra '0' to the front of the unsigned number to make it a valid signed number.  I'm thinking there must be a cleaner way.</p>
  
  <p>More generally, I am just getting started doing fixed point math in SystemVerilog. In VHDL there is very concrete syntax and even a standard package to support signed and unsigned fixed point math, with rounding, etc.  Is there something like that in the SystemVerilog world?</p>
  
  <p>Thanks,</p>
  
  <pre><code>module testbench ();
      localparam int Wa = 8;
      localparam int Wb = 8;
  
      logic  [Wa-1:0] a;       // unsigned
      logic  [Wa:0] a_signed;  // signed word with extra bit to hold unsigned number.
      logic  [Wb-1:0] b;       // signed
      logic  [Wa+Wb-1:0] c;    // result
  
      localparam clk_period = 10;
  
      assign a_signed = {1'b0, a};
      assign c = $signed(a_signed)*$signed(b);
  
      initial begin
          a = +5;
          b = +10;
          #(clk_period*1);
          $display("Hex: a=%x,b=%x, c=%x; Dec: a=%d, b=%d, c=%d", a, b, c, a, $signed(b), $signed(c));
  
          a = +5;
          b = -10;
          #(clk_period*1);
          $display("Hex: a=%x,b=%x, c=%x; Dec: a=%d, b=%d, c=%d", a, b, c, a, $signed(b), $signed(c));
  
          a = +255;
          b = +10;
          #(clk_period*1);
          $display("Hex: a=%x,b=%x, c=%x; Dec: a=%d, b=%d, c=%d", a, b, c, a, $signed(b), $signed(c));
  
          a = +255;
          b = -10;
          #(clk_period*1);
          $display("Hex: a=%x,b=%x, c=%x; Dec: a=%d, b=%d, c=%d", a, b, c, a, $signed(b), $signed(c));
  
          $stop;
      end
  
  endmodule
  </code></pre>