3
\$\begingroup\$

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?

\$\endgroup\$
0

3 Answers 3

3
\$\begingroup\$

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}};
\$\endgroup\$
4
  • \$\begingroup\$ can I not just write assign Data = RD == 1? register:{(n-1){1'bz}}; ??? \$\endgroup\$ Commented Jan 30, 2018 at 16:18
  • \$\begingroup\$ 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. \$\endgroup\$
    – Oldfart
    Commented Jan 30, 2018 at 16:25
  • \$\begingroup\$ @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. \$\endgroup\$ Commented Jan 30, 2018 at 16:57
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – dave_59
    Commented Jan 30, 2018 at 18:23
1
\$\begingroup\$

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
   
\$\endgroup\$
0
\$\begingroup\$

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?)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.