# High impedance in RTL Verilog

I am designing a shift register. It has a control signal called RD which is asynchronous (so I can't use it inside the procedural block). The whole point is my n-1 bit shift register is value of the input if RD==1 or else it has high impedance; I am not sure how to write the assign the high impedance value because my n bit is a parameter so I can't define the number of bits.

inout [n-1:0] Data;
input RD;

reg [n-1:0] register;  //my register


Example: Data = (RD==1'b1)? [n-1:0] register: 'z ;

It's giving me an error. How can I define that if RD is 1, then I need to see what is there inside the register, and if it's 0 then, it should be high impedance?

Unless you are using SystemVerilog, you cant declare a constant like that.

Instead use the replication operator. {(WIDTH){1'bz}} is a WIDTH bit wise constant of all z's. Just replace the width with however wide you need (can be a parameter).

Furthermore, it should be register[n-1:0] not [n-1:0]register.

The following should work:

assign Data = (RD == 1'b1) ? register : {(n){1'bz}};

• can I not just write assign Data = RD == 1? register:{(n-1){1'bz}}; ??? Commented Jan 30, 2018 at 16:18
• No. And you keep asking us "I can't do <some totally illegal obscure code sequence>" whilst the compiler already told you that you can't. Your bit select operator = []. The {} are concatenation operators. Commented Jan 30, 2018 at 16:25
• @Digital_Treasure mostly correct. You would need to do {(n){1'bz}} as your number is n-bits wide. Also, I would keep the (RD==1'b1) in brackets for better readability and less chance of the compiler misinterpreting. Commented Jan 30, 2018 at 16:57
• Just to clarify 'z is a SystemVerilog constant construct that automatically sizes itself to width required by the context of the expression where it is located. Commented Jan 30, 2018 at 18:23

Thank you for the suggestions and guidance. I was able to code in the right pattern and get the expected results.

module shifter #(parameter Length = 1) (

input clk,
input rst,
input EN,
input WR,
input RD,
input SI,
output reg SO,
inout [Length-1:0] Data
);

reg [Length-1:0] register;

always@(posedge clk or posedge rst)
begin
if(rst == 1'b1)
begin
register <= 0;
end
else
begin
if(WR == 1'b1 && EN == 1'b0)
begin
register <= Data;
end

else if(WR == 1'b0 && EN == 1'b1)
begin
register <= {SI, register[Length-1:1]};
SO <= register [0];
end

else if(WR == 1'b1 && EN == 1'b1)
begin
\$display ("Illegal state");
end

else
begin
register <= register;
end

end
end

assign Data = (RD == 1'b1) ? register [Length-1:0] : {(Length){1'bz}};

endmodule



One thing to think about is whether WR and RD can be high at the same time, in which case you could be driving a value onto Data at the same time you're expecting someone else to be driving Data, which could result in X's on some (or all) Data bits. This restriction would need to be enforced where WR/EN/RD are generated. This also might be a place where an assertion could be useful, if you're using SystemVerilog (and if your tools support SV, why wouldn't you use it?)