BitSet Circuit in Verilog

1.2k views Asked by At

A specific type of bit-level manipulation consists in setting or clearing one single bit in a multi-bit value, given its index and its new value. This operation can be implemented in hardware by a BitSet circuit with the following interface:

  • Input x is a 4-bit value representing the original value.
  • Output y is a 4-bit value representing the modified value, after the bit-set operation.
  • Input index is a 2-bit value, ranging from 0 to 3, indicating the index of the bit to modify.
  • Input value is a 1-bit value set to 0 or 1, indicating the value that bit index should take in output y. Every other bit in y should match the corresponding bit in x.

Here's the code I have which I took from examples in class:

module BitSet(input [3:0]x,
         input [1:0]index,
         input value,
         output [3:0]y);
   always@(x,index,value);
   begin
      if (index = 2'b00) 
        y[0] = value;
     if(index = 2'b01)
        y[1]=value;
     if(index = 2'b10)
        y[2]=value;
     if(index=2'b11)
        y[3]=value;
   end
 endmodule

and here's the testbench:

module BitSet_tb();
    reg [3:0]x;
    reg [1:0]index;
    reg value;
    wire [3:0]y;

    BitSet uut(
      .x(x),
      .index(index),
      .value(value),
      .y(y)
    );

    initial begin
        $monitor ("%d %b %b %b %b", $time, x, index, value, y);
           x=4'b0000;
           index=2'b00;
           value=1'b0;
       #10 x=4'b0001;
           index=2'b01;
           value=1'b0;
       #10 x=4'b1111;
           index=2'b10;
           value=1'b0;
       #10 x=4'b1111;
           index=2'b11;
           value=1'b0;
       #10 $finish;
     end
 endmodule

When compiling, I get the following errors:

bitset.v:10: syntax error
bitset.v:12: error: invalid module item.
bitset.v:13: syntax error
bitset.v:14: error: invalid module item.
bitset.v:15: syntax error
bitset.v:16: error: invalid module item.
bitset.v:17: syntax error
bitset.v:18: error: invalid module item.
bitset.v:19: syntax error

I'm not even sure if this would do what I want, but can anyone help with the errors or how to fix the program to do what's asked?

1

There are 1 answers

2
Evan Cox On

No, this won't do what you want even when the syntax errors are fixed. I'll help you with the syntax errors and try to point you on the right path to get the problem solved (I think on SO we are not supposed to outright solve HW problems!)

module BitSet(input  [3:0] x,
              input  [1:0] index,
              input        value,
              output reg [3:0] y); // y needs to be of type reg if you're
                                   // going to use it in a procedural block
                                   // (like an always block)

   // The * infers the sensitivity list, no need to list out each signal.
   // Also, you can't have a semicolon here.
   always@(*) 
   begin
     // Like in C, a single "=" is an assignment, while a compare is "==".
     // You want to compare index to 2'b00, not assign it that value, 
     if (index == 2'b00) 
        y[0] = value;
     if (index == 2'b01)
        y[1] = value;
     if (index == 2'b10)
        y[2] = value;
     if (index == 2'b11)
        y[3] = value;
   end
 endmodule

Now, to get the correct functionality... you are almost there, could be done with a single additional line in fact. My question to you is this: in your code, what happens to the bits in y that are supposed to take the direct value of x and NOT get changed? Does your code accurately handle this? If not, what needs to be done to handle this?

And just for kicks, here's a version with updated SystemVerilog syntax:

module BitSet(input  [3:0] x,
              input  [1:0] index,
              input        value,
              output logic [3:0] y); // "logic" type can be used as a wire or reg

   // Just like always @(*), but directly indicates that this
   // is combinational logic. Tools will throw an error if you
   // accidentally encode a latch (which you have done!)
   always_comb 
   begin
     if (index == 2'b00)
        y[0] = value;
     if (index == 2'b01)
        y[1] = value;
     if (index == 2'b10)
        y[2] = value;
     if (index == 2'b11)
        y[3] = value;
   end
endmodule