user4611785
user4611785

Reputation: 31

Convert binary input into residue number system

I have written a code which converts our number which is in binary into residue using a look up table.

First, I have made a memory having both read and write enables and stored values. During 'we' , 'a' is my input which is of 8 bit... for every bit of a it checks whether it is 1 or 0, for a[bit position]==1, it sends dout(output) at that mem[addr]. and after checking all 8 bits its send data into sum3, sum5, sum7.

But, I am unable to get the output. I am getting undefined output.

module mem(clk,we,re,a,sum7,sum5,sum3);
   
parameter ADD_WIDTH=3;
parameter DATA_WIDTH=9;
input [7:0] a;
//integer i;
input clk;
input we;
input re;
reg[ADD_WIDTH-1:0] addr;
reg [DATA_WIDTH-1:0] dout0,dout1,dout2,dout3,dout4,dout5,dout6,dout7;
reg [2:0] mod70,mod71,mod72,mod73,mod74,mod75,mod76,mod77,mod50,mod51,mod52,mod53,mod54,mod55,mod56,mod57,mod30,mod31,mod32,mod33,mod34,mod35,mod36,mod37;

output reg [3:0] sum3,sum5,sum7;
reg [DATA_WIDTH - 1 : 0] mem [2**ADD_WIDTH -1 : 0] ;
reg [3:0] count,count1;

always@(posedge clk)
begin 
 if (we)
  begin 
    case(addr)
     4'b000: mem[addr]=9'b001001001;
     4'b001: mem[addr]=9'b010010010;
     4'b010: mem[addr]=9'b100100001;
     4'b011: mem[addr]=9'b001011010;
     4'b100: mem[addr]=9'b010001001;
     4'b101: mem[addr]=9'b100010010;
     4'b110: mem[addr]=9'b001100001;
     4'b111: mem[addr]=9'b010011010;         
     endcase
    end
end

always@(posedge clk)
begin
dout0=9'd0;
dout1=9'd0;
dout2=9'd0;
dout3=9'd0;
dout4=9'd0;
dout5=9'd0;
dout6=9'd0;
dout7=9'd0;
mod30=3'd0;
mod31=3'd0;
mod32=3'd0;
mod33=3'd0;
mod34=3'd0;
mod35=3'd0;
mod36=3'd0;
mod37=3'd0;
mod51=3'd0;
mod52=3'd0;
mod53=3'd0;
mod54=3'd0;
mod55=3'd0;
mod56=3'd0;
mod57=3'd0;
mod71=3'd0;
mod72=3'd0;
mod73=3'd0;
mod74=3'd0;
mod75=3'd0;
mod76=3'd0;
mod77=3'd0;

//if (count1==1)
//begin
if (re && !we  )
begin
 case(addr)
  3'b000:
   begin
    dout0= mem[addr];
    mod30= dout0[2:0];
    mod50= dout0[5:3];
   mod70= dout0[8:6];
  end
  
  3'b001:
   begin
    dout1= mem[addr];
    mod31= dout1[2:0];
    mod51= dout1[5:3];
   mod71= dout1[8:6];
  end
  
  3'b010:
   begin
    dout2= mem[addr];
    mod32= dout2[2:0];
    mod52= dout2[5:3];
   mod72= dout2[8:6];
  end
  
   3'b011:
   begin
    dout3= mem[addr];
    mod33= dout3[2:0];
    mod53= dout3[5:3];
   mod73= dout3[8:6];
  end
  
   3'b100:
   begin
    dout4= mem[addr];
    mod34= dout4[2:0];
    mod54= dout4[5:3];
   mod74= dout4[8:6];
  end
  
  3'b101:
   begin
    dout5= mem[addr];
    mod35= dout5[2:0];
    mod55= dout5[5:3];
   mod75= dout5[8:6];
  end
  
  3'b110:
   begin
    dout6= mem[addr];
    mod36= dout6[2:0];
    mod56= dout6[5:3];
   mod76= dout6[8:6];
  end
  
  3'b111:
   begin
    dout7= mem[addr];
    mod37= dout7[2:0];
    mod57= dout7[5:3];
   mod77= dout7[8:6];
  end
  endcase
 
 if (count1==4'b1000)
 begin
  sum7=mod70+mod71+mod72+mod73+mod74+mod75+mod76+mod77;
  sum5=mod50+mod51+mod52+mod53+mod54+mod55+mod56+mod57;
  sum3=mod30+mod31+mod32+mod33+mod34+mod35+mod36+mod37;
  end

 end
 end


always@(posedge clk)
begin
 if (count==4'b1001)
  count1<=0;
 else count1<=count+1;
 end

always@(posedge clk)
begin
case (1'b1)
  a[0]: addr=3'd0;
  a[1]: addr=3'd1;
  a[2]: addr=3'd2;
  a[3]: addr=3'd3;
  a[4]: addr=3'd4;
  a[5]: addr=3'd5;
  a[6]: addr=3'd6;
  a[7]: addr=3'd7;
  default: addr=3'd0; // to avoid inferring a latch when W==8'd0
endcase
end
endmodule

Upvotes: 1

Views: 725

Answers (1)

Morgan
Morgan

Reputation: 20514

In always@(posedge clk), use non-blocking assignments (<=).

The way you have defined initial values is not typical.

Either use an initial block or a reset.

initial begin
  dout0=9'd0;
  dout1=9'd0;
  dout2=9'd0;
  dout3=9'd0;
  dout4=9'd0;
  dout5=9'd0;
  dout6=9'd0;
  dout7=9'd0;
  mod30=3'd0;
  mod31=3'd0;
  mod32=3'd0;
  mod33=3'd0;
  mod34=3'd0;
  mod35=3'd0;
  mod36=3'd0;
  mod37=3'd0;
  ...
end

Or

always@(posedge clk, negedge rst_n) begin
  if(~rst_n) begin
    dout0<=9'd0;
    //...
  end 
  else begin
    if (re && !we  ) begin
      case(addr)
        3'b000: begin
          dout0 <= mem[addr];
          {mod70, mod50, mod30} <= dout0; //1 cycle latency for this
        end
      endcase
  end
end

dout to your mod will have a 1 clock cycle latency, should dout not be a combinatorial look up?

always @* begin
   dout0 = mem[addr];
end

Upvotes: 2

Related Questions