sb27
sb27

Reputation: 392

Verilog Temporary Variable

I tried to make a CMP instruction in Verilog. To keep the result of the substraction, I declared a wire. This is what the code looks like (It is executed in an always statement).

wire [data_width:0] tmp_wire = reg_accumulator - reg_x;

f_zero <= tmp_wire & 'hFF == 0;
f_carry <= tmp_wire & 'h100;

Now Icarus Verilog complains about a syntax error and that reg_accumulator - reg_x is not an l-value:

cpu.v:149: syntax error
cpu.v:149: Syntax in assignment statement l-value.

And why does it complain? What would be the right approach to declare a temporary variable in a function / task?

module comparator(
    input clk,
    input [7:0] op_a,
    input [7:0] op_b
);

reg f_zero;
reg f_carry;

function compare;
    input [data_width-1:0] a;
    input [data_width-1:0] b;
begin
    wire [7:0] tmp_wire = reg_accumulator - reg_x;

    f_zero <= tmp_wire & 'hFF == 0;
    f_carry <= tmp_wire & 'h100;
end
endfunction

always @(posedge clk) begin
    compare(op_a, op_b);
end

endmodule // comparator

Upvotes: 0

Views: 5508

Answers (2)

m4j0rt0m
m4j0rt0m

Reputation: 354

Either you should use systemverilog and include this in a class or you can create a parameterized module:

module compare_zero_n_carry
# (
    parameter DATA_WIDTH = 8
  )
(zero, carry, a, b);

  /* ports */
  input [DATA_WIDTH-1:0] a;  //.."reg_accumulator"
  input [DATA_WIDTH-1:0] b;  //.."reg_x"
  output zero;
  output carry;

  wire [DATA_WIDTH-1:0] tmp_wire = a - b;

  assign zero = (tmp_wire & {DATA_WIDTH{1'b1}}) == {DATA_WIDTH{1'b0}};
  //..HERE IM NOT REALLY SURE WHAT IS THE LOGIC FOR THE CARRY,
  //..IT SHOULD BE ONE BIT
  assign carry = (tmp_wire & {1'b1,{(DATA_WIDTH-1){1'b0}}});     
endmodule // compare_zero_n_carry

And instantiate it in the main comparator module as:

  input                   clk;
  input [DATA_WIDTH-1:0]  op_a;
  input [DATA_WIDTH-1:0]  op_b;

  wire f_zero;
  wire f_carry;
  reg f_zero_reg;
  reg f_carry_reg;

  compare_zero_n_carry
    # (
        .DATA_WIDTH (DATA_WIDTH)
      )
    compare_zero_n_carry_inst (
        .a      (op_a),
        .b      (op_b),
        .zero   (f_zero),
        .carry  (f_carry)
      );

  always @ (posedge clk) begin
    f_zero_reg <= f_zero;
    f_carry_reg <= f_carry;
  end

Upvotes: 1

toolic
toolic

Reputation: 62037

You cannot declare a wire inside the always block.

wire [7:0] tmp_wire = reg_accumulator - reg_x;

always @(posedge clk) begin
    f_zero <= tmp_wire & 'hFF == 0;
    f_carry <= tmp_wire & 'h100;
end

Upvotes: 1

Related Questions