0

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
6
  • Assignments in an always block should be to regs (as you rightfully declared f_zero and f_carry). You put the wire declaration and assignment inside the always so the error is for trying to update a wire in an always block which is illegal... Commented Jun 9, 2020 at 16:48
  • @Tomerikoo Ok, but how can I declare something like a temporary variable? Commented Jun 9, 2020 at 16:53
  • Just like any other wire... You have the answer below. By the way, reg_accumulator and reg_x are not defined... Commented Jun 9, 2020 at 17:06
  • How should I declare a wire in a function with it's parameters? This is not going to work: function compare; input [data_width-1:0] a; input [data_width-1:0] b; wire [data_width:0] tmp = a - b; begin end endfunction Commented Jun 9, 2020 at 17:12
  • You shouldn't ask this in the comments. Either edit your question to properly reflect your question or open a new one Commented Jun 9, 2020 at 17:24

2 Answers 2

1

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
Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.