SulfoCyaNate
SulfoCyaNate

Reputation: 426

always module in Verilog RTL file not working, but working once included in testbench

This might seem like a very naive question, but I have just started working with Verilog (I use Xilinx ISE, if that helps).

I am trying to implement a shift register that shifts input PI by the value specified in the shft port. When I include the shifting logic in the RTL file, the shifting does not work, but when I move the always block corresponding to shifting to the testbench, it works. Please help me with this!

module shift (PI, shft, clk, PO);
input  [7:0] PI;
input clk;
input [7:0] shft; 
output reg [13:0] PO;
reg [7:0] shft_reg;
always @(posedge clk) begin
  if  (shft_reg[0]||shft_reg[1]||shft_reg[2]||shft_reg[3]||shft_reg[4]||shft_reg[5]||shft_reg[6]||shft_reg[7]) begin 
      PO <= {PO, 0};
      shft_reg <= shft_reg-1;
  end 
end
endmodule

Upvotes: 1

Views: 273

Answers (2)

Morgan
Morgan

Reputation: 20554

Note that || is a logical or and idealy should be used with logical statments such as (shft_reg[0] == 1'b1 ) || ( shft_reg[1] == 1'b1).

Your if statment is really bitwise ORing all of the bits ie

shft_reg[0] | shft_reg[1] | shft_reg[2] | ...

You can use the OR Reduction operator :

|shft_reg

Your supplied code had typo'd PI for PO.

always @(posedge clk) begin
  if  (|shft_reg) begin 
      PO       <= {PI, 0}; //PI input 
      shft_reg <= shft_reg-1;
  end 
end

Upvotes: 0

mcleod_ideafix
mcleod_ideafix

Reputation: 11448

module shift (
    input wire clk;
    input wire load;  // load shift register from input
    input wire [7:0] PI;
    input wire [7:0] shft; // this might need less bits
    output wire [13:0] PO;
    );

    reg [7:0] shft_reg;
    reg [13:0] value;
    assign PO = value; // PO follows value 
    always @(posedge clk) begin
      if (load) begin  // initialize shift register and counter
        shft_reg <= shft;
        value <= {6'b0,PI};
      end
      else if (shft_reg) begin // if counter not reached end...
        shft_reg <= shft_reg - 1;  // decrement, and
        value <= {value[13:1],1'b0};  // shift left value 1 bit
      end
  end 
end
endmodule

Recall that Verilog supports the >> and << operators. For non-constants many-bit operands, this may be a waste of multiplexers, though:

module shiftcomb (
    input wire [7:0] PI;   // this value is left shifted
    input wire [2:0] shft; // 0 to 7 bits positions
    output wire [14:0] PO; // and is outputted to PO
    );

    assign PO = PI<<shft; // this will generate 15 mutlplexers:
                          // each one with 8 inputs, 3 bit select,
                          // and 1 output.
endmodule

Upvotes: 1

Related Questions