0

I am programming a basic ALU in system verilog. The ALU takes inputs from the 16 bit registers InDest and InSrc and outputs the result to the 16 bit register OutDest. One of the required instructions is MUH, which sets the value of register OutDest to the high half of the signed integer product InDest*InSrc.

For instance, if the result of the multiplication is:

1111 1111 1111 1111 0000 0000 0000 0000

The value of OutDest should be:

1111 1111 1111 1111

The use of other registers is not allowed.

My initial idea for this instruction was:

{OutDest,null} = {(InSrc*InDest)};

However this gives the error: near text: "null"; expecting "}".

I have also tried:

OutDest = {InSrc*InDest}[31:16];

This gives the error: near text : "["; expecting ";".

Any help on this instruction would be greatly appreciated, since alot of time has been spent on it and it is a important piece of coursework.

Xavier
  • 3
  • 3

2 Answers2

0
module tb ();
  
  logic signed [7:0]  rhs1,rhs2;
  logic signed [15:0] product;
  
  initial
    begin
      // 8 bits * 8 bits = 16 bits
      rhs1 = -1;
      rhs2 = 1;
      product = rhs1 * rhs2;
      // take the top half of the vector
      $display("lsh = %0h",product[15:8]);
    end
  
endmodule

Produces:

lsh = ff
Mikef
  • 1,572
  • 2
  • 10
  • 21
  • Thanks you, however this approach is not suitable since it requires the creation of extra registers. The only register allowed to written to is OutDest (16 bits). – Xavier Dec 06 '22 at 15:49
  • In this case the variable product is just a variable. There is no inferred RTL register. Sometimes there is confusion for new verilog users with the term register. Type register variables don't infer physical registers. The variable can infer physical registers if it is placed in a synchronous always block. So there is a difference necessary when interpreting the phrase 'no new registers' could mean 'no new type register variables' or 'no new RTL registers'. Which do you mean? It seems as if you will need something to represent the result of a multiplication? – Mikef Dec 06 '22 at 16:15
  • The way the assessment is set out, we are only allowed to insert code inside an always_comb block, the rest was given to us as a template. – Xavier Dec 06 '22 at 19:41
0

This is the correct syntax

OutDest = {(32'InSrc*InDest)}[31:16];

But it seems your version of Quartus is not supporting it.

You could write

OutDest = 32'(InSrc*InDest) >> 16;

dave_59
  • 39,096
  • 3
  • 24
  • 63
  • @dava_59 The first syntax you mentioned does not seem to work (syntax error) for me on EDA Playground. https://www.edaplayground.com/x/pnhh – Mikef Dec 06 '22 at 19:04
  • I am using Quartus Prime Lite, Version 18.1 I tried using your suggestion: ``` OutDest = InSrc*InDest >> 16; ``` This compiled, unlike the other attempts, however when testing in modelsim using a testbench, OutDest always inncorrectly showed: 0000 0000 0000 0000 – Xavier Dec 06 '22 at 19:50
  • @Mikefit works with all other simulators on EDAPlayground except the one you chose. – dave_59 Dec 06 '22 at 21:05
  • @Xavier You need to cast the multiplication to 32'bits. Updated example – dave_59 Dec 06 '22 at 21:10
  • @dave_59 I confirmed what you said about only one tool errors. The others warn and provide the hint about the solution. This is subtle to me. – Mikef Dec 06 '22 at 22:17
  • @dave_59 Thanks very much for your help, the updated example worked! – Xavier Jan 06 '23 at 18:14