2

I know VHDL, and just learning verilog. I'm trying to do a simple assignment with bit shift, and I get undefined 'X' in the result. I don't understand why. This is in simulation with Xilinx ISim software.

This assignment:

assign dout = $signed(data_out >>> shift_bits);

Results in 'X' wherever a '1' should be. For example, if data_out = '00001100', and shift_bits = 1, dout will = '00000XX0'.

Below is the module definition and the assignment operation:

module SensorINV(
    input clk,
     input [23:0] din,
     input idv,
     input [4:0] shift_bits,
     output [23:0] dout,
     output reg odv
    );


reg [47:0] data_out = 0;        // initialize the output
assign dout = $signed(data_out >>> shift_bits);
// assign dout = data_out[44:21];   // this didn't work either

reg [1:0] state = 0;

always @(posedge clk) begin
    case (state)
        0   :   begin       // waiting for new data
            ...
        end
        1   :   begin
            ...
            data_out <= data_out + temp1_w;
            state <= 2;
        end
        2   :   begin
            ...
            state <= 0;
        end
        default :   state <= 0;
    endcase
end
7
  • Could be because of the different widths of data_out and dout. Also not sure why you're taking some middle 24 bits (in your commented out line). You could maybe try assign dout = $signed(data_out >>> shift_bits)[UB:LB]. Also why is data_out a reg instead of a wire? Is there a synchronous block you're not showing us? Commented Jun 18, 2015 at 18:46
  • 1
    Without more code, I would assume it has to do with the reg [47:0] data_out = 0; line, which is setting up a continuous assign for data_out to value 48'd0. As such, whenever you try to assign a value of 1 to any bits of data_out, you get 1'bx instead. Try removing the = 0; part and see if you code works now. Commented Jun 18, 2015 at 19:04
  • @mstbaum, yes data_out is in a synchronous block, i posted more code to show. Commented Jun 18, 2015 at 20:28
  • @Unn, the data_out = 0 line I believe is just initialization value, not a continuous assign. Am I wrong? Commented Jun 18, 2015 at 20:29
  • @ScottC In theory, for type reg it should be an initialization. If it were a net, it would be treated as a continuous assignment (ie wire [47:0] data_out = 0 would be a continuous assignment). I think its possible this tool is doing that even though I think you are right that it shouldnt be. I wasnt able to find what the LRM says about variable types being set at declaration so Im not 100% sure on what the behavior of reg [47:0] data_out = 0; is strictly defined as. Still worth a short removing the initialization and seeing what happens for the simulator. Commented Jun 18, 2015 at 21:04

1 Answer 1

4

The problem turned out to be conflicting drivers of dout, only one of which was shown in the code above. In the next module up, where this one was instantiated (not shown), I had a line like this:

wire [23:0] dout = 0;

This created a continuous assignment, not an initialization value. This conflict didn't show up in simulation until I tried to make dout non-zero. If it were a register reg, it would be an initialization value, but in this case it was a wire. Got rid of the continuous assign = 0, and problem solved.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.