rugyi
rugyi

Reputation: 13

(System)Verilog bit cut out from arbitrary position

I'd like to make an output bus 1 bit shorter than the input, by cutting a bit from arbitrary position, like this:

module jdoodle;
    integer i;
    reg [8:0] in;
    reg [7:0] out;
    reg [3:0] idx;
    
    always @* 
    begin
        case(idx)
            0: out = in[8:1];
            1: out = {in[8:2], in[0]};
            2: out = {in[8:3], in[1:0]};
            3: out = {in[8:4], in[2:0]};
            4: out = {in[8:5], in[3:0]};
            5: out = {in[8:6], in[4:0]};
            6: out = {in[8:7], in[5:0]};
            7: out = {in[8], in[6:0]};
            default: out = in[7:0];
        endcase
    end

    initial begin
        in = 9'b010101010;
        for (i = 0; i < 9; i++)
        begin
            idx = i; #10;
            $display ("%x - %08b", idx, out);
        end
        $finish;
    end
endmodule

I found a way to write it in one line:

module jdoodle;
    integer i;
    reg [8:0] in;
    reg [3:0] idx;

    wire [7:0] out;
    assign out = ((in >> 1) & (16'h00ff << idx)) | (in & (16'hff00 >> (16-idx)));

    initial begin
        in = 9'b010101010;
        for (i = 0; i < 9; i++)
        begin
            idx = i; #10;
            $display ("%x - %08b", idx, out);
        end
        $finish;
    end
endmodule

But its less readable than the first, but the first is quite bad for larger buses. Is there a more elegant way to do it? Also is there standard library for verilog like std for c++, containing common modules like arbitrary rotate?

Thanks

Edit: here's the expected output:

0 - 01010101
1 - 01010100
2 - 01010110
3 - 01010010
4 - 01011010
5 - 01001010
6 - 01101010
7 - 00101010
8 - 10101010

Upvotes: 1

Views: 345

Answers (1)

nguthrie
nguthrie

Reputation: 2685

You can use a loop to work on each bit:

module jdoodle #(parameter INW = 'd9)
 (
  input [INW-1:0] in,
  output[INW-2:0] out,
  input [$clog2(INW)-1:0] idx
 );    
  always_comb begin
      for(int i = 0; i<INW; i++) begin
          if      (i < idx) out[i]   = in[i];
          else if (i > idx) out[i-1] = in[i];
          // do nothing if i == idx
      end
  end
endmodule

Upvotes: 1

Related Questions