Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Best way to decodebits and attribute 0 to not used registers.

Status
Not open for further replies.

pbernardi

Full Member level 3
Joined
Nov 21, 2013
Messages
151
Helped
30
Reputation
60
Reaction score
31
Trophy points
1,308
Activity points
2,903
Hello,

I would like to decode a table of bits into register according predeterminated conditions:

a) we have a input of n bits (Typical 16, 32 or 64 bits)
b) Some of these bits are or condition bits, and determines what others bits mean, and to with register they should go.
c) If a register is not decoded, it must be set to 0.

I think the best way to explain is by example, it is the best I could do until now (in Verilog):

Code:
reg A, B;
reg [1:0] C;
reg [2:0] D;
reg [3:0] E;

reg [7:0] input;

always@(posedge CLK)
begin
   if (input [1:0] == 2´b00) begin {E,C}    <= input[7:2]; {A, B, D} <= 0; end else
   if (input [1:0] == 2´b01) begin {A,D,C}  <= input[7:2]; {B, E}    <= 0; end else
   if (input [1:0] == 2´b10) begin {A,B,E}  <= input[7:2]; {D, C}    <= 0; end else
   if (input [1:0] == 2´b11) begin {B,C,D}  <= input[7:2]; {A, E}    <= 0; end
end

The problem with this approach is that if we have a lot of registers and lots of decoding (it is my case), the coding has still some complexity (altough much better that a if/else for each register). I would like to simplify more and wonder if there is some way to avoid the "<= 0" attribution on each if, in order to keep the code easy to mantain.

Verilog is my natural hardware language, but suggestions in VHDL are also welcome. Any suggestions?
 

Code:
always@(posedge CLK)
begin
   {A, B, C, D, E} <= 0;
   case (input[1:0]) 
      0: {E,C}    <= input[7:2];
      1: {A,D,C}  <= input[7:2];
      2: {A,B,E}  <= input[7:2];
      3: {B,C,D}  <= input[7:2];
   endcase
end
This also works. The way non-blocking assignments are done, the last reached assignment is the one that is used. This behavior should be used responsibly -- it creates a bottom-to-top priority structure which is opposite from the top-to-bottom priority that if/else and case have.

In some cases, this can have side effects. Specifically, if you have an always@(*) block that uses $report, this can lead to the $report being reached with unchanged inputs.
 
Code:
always@(posedge CLK)
begin
   {A, B, C, D, E} <= 0;
   case (input[1:0]) 
      0: {E,C}    <= input[7:2];
      1: {A,D,C}  <= input[7:2];
      2: {A,B,E}  <= input[7:2];
      3: {B,C,D}  <= input[7:2];
   endcase
end
This also works. The way non-blocking assignments are done, the last reached assignment is the one that is used. This behavior should be used responsibly -- it creates a bottom-to-top priority structure which is opposite from the top-to-bottom priority that if/else and case have.

In some cases, this can have side effects. Specifically, if you have an always@(*) block that uses $report, this can lead to the $report being reached with unchanged inputs.

Wow, thanks vGoodtimes, that´s exactly I was looking for. I always thougth that a double register assignment inside the same always is a no-no and could bring undeterminated results. Good to know that double assignement can be used is some cases, as you cited, responsably.
 

Multiple assignments to a reg is mostly a no-no. There are two possible exceptions. There is the default value assignment shown in my first post. There is also a style that places the synchronous reset at the bottom of the process. This makes it easy to have registers without reset to be in the same always block as registers with a reset. VHDL allows this with async resets as well. Verilog does not.

Code:
always@(posedge clk) begin
  controls <= logic;
  data_out <= calculation;
  // this resets the control signals but not the data signals.  some fpga vendors suggest this.
  if (rst) begin
    controls <= init;
  end
end

Two-process style code benefits from this as well. You can have "next_state = curr_state;" at the top of the always@(*) block. This makes the rest of the always block less verbose and prevents you from inferring latches. (unless you forget the default assignment)
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top