【问题标题】:verilog code for priority encoder优先级编码器的verilog代码
【发布时间】:2016-09-11 12:21:29
【问题描述】:

我为优先级编码器编写了verilog代码,这个代码可以用于模拟目的吗?什么可以是用于综合目的的代码?请放弃您的意见和想法。

module pri_encoder(y,i,enable);
output reg [3:0]y;
input [15:0]i;
input enable;

always@(i or enable)
if(enable)
if(!i)
y=4'bx;
else if(i==1)
y=4'b0;
else if(i==2)
  y=1;
else if(i==3)
  y=2;
  else if(i>=4 && i<=7)
  y=3;
  else if(i>=8 && i<=16)
  y=4;
  else if(i>=16 && i<=32)
  y=5;
  else if(i>=32 && i<=64)
  y=6;
  else if(i>=64 && i<=128)
  y=7;
  else if(i>=128 && i<=256)
  y=8;
  else if(i>=256 && i<=512)
  y=9;
  else if(i>=512 && i<=1024)
  y=10;
  else if(i>=1024 && i<=2048)
  y=11;
endmodule

【问题讨论】:

  • 您在组合块中的if(enable) 将暗示闩锁。

标签: verilog digital-logic


【解决方案1】:

您的设计可能是可合成的,但根据上面的评论,您会得到一个闩锁。如果您摆脱了闩锁,casex 语句可能更具可读性。

这是我使用的一个小型编码器。我已将其修改为启用。让“启用 + 选择”输入的宽度与 {1'b1,6'bxxxxxx} 中向量的宽度相匹配至关重要。在这种情况下,1 + 6 = 7。您可以根据需要放大。

function [2:0] prienc6;
 input       enable;
 input [5:0] select;
 reg   [2:0] out;
 begin
   casex({enable,select})
     {1'b1,6'b000001}: out = 3'b101;
     {1'b1,6'b00001x}: out = 3'b100;
     {1'b1,6'b0001xx}: out = 3'b011; 
     {1'b1,6'b001xxx}: out = 3'b010; 
     {1'b1,6'b01xxxx}: out = 3'b001; 
     {1'b1,6'b1xxxxx}: out = 3'b000;
     {1'b0,6'bxxxxxx}: out = 3'b000;  // if you assign out = out, then you get latches.
   endcase

   prienc6 = out ;
 end
endfunction

您可以将其扩展为包含一个 prev_out 和一个时钟以避免闩锁,因此

reg [2:0] encode_out;

function [2:0] prienc6;
 input       enable;
 input [5:0] select;
 input [2:0] prev_out;
 reg   [2:0] out;
 begin
   casex({enable,select})
     {1'b1,6'b000001}: out = 3'b101;
     {1'b1,6'b00001x}: out = 3'b100;
     {1'b1,6'b0001xx}: out = 3'b011; 
     {1'b1,6'b001xxx}: out = 3'b010; 
     {1'b1,6'b01xxxx}: out = 3'b001; 
     {1'b1,6'b1xxxxx}: out = 3'b000;
     {1'b0,6'bxxxxxx}: out = prev_out;
   endcase

   prienc6 = out ;
 end
endfunction

always @ (posedge clk or posedge reset)
begin 
   if (reset) encode_out <= 3'b000;
   else encode_out <= prienc6(some_enable,some_select,encode_out); //latch avoided.

end

我不知道这是否合适,但这是我的首选解决方案。我在函数外部启用了。

reg [2:0] encode_out;

function [2:0] prienc6;
     input [5:0] select;
     reg   [2:0] out;
     begin
       casex(select)
         6'b000001: out = 3'b101;
         6'b00001x: out = 3'b100;
         6'b0001xx: out = 3'b011; 
         6'b001xxx: out = 3'b010; 
         6'b01xxxx: out = 3'b001; 
         6'b1xxxxx: out = 3'b000;
         default  : out = 3'b000;
       endcase

       prienc6 = out ;
     end
    endfunction

always @ (posedge clk or posedge reset)
begin 
   if (reset) encode_out <= 3'b000;
   else       encode_out <= enable ? prienc6(some_input) : encode_out;
end

【讨论】:

  • 您的 (enable,select) 是 case 语句的无效语法,请将其更改为串联形式:({enable,select})。虽然合法,但强烈建议不要使用casex,而是使用casez(并将案例条件中的xs 更改为?s)。在搜索 verilog casex vs casez 时,casez 超过 casex 的原因在 herehere 以及其他在线资源中进行了解释
  • 更正了向量合并。
【解决方案2】:

以下代码为 3bit 优先编码器。同样可以为您实现 代码也。我以最简单的方式编写了代码。

您的代码不包含使电路合成为锁存器的 else 条件。

module priority(input [7:0] a,
input enable,
output reg [2:0] b    );

always @(*)
begin
if(enable)
begin
if (a[7:0]==1)
b=0;
else if(a[7:1]==1)
b=1;
else if(a[7:2]==1)
b=2;
else if(a[7:3]==1)
b=3;
else if(a[7:4]==1)
b=4;
else if(a[7:5]==1)
b=5;
else if(a[7:6]==1)
b=6;
else if(a[7]==1)
b=7;
end
else
b=4'bxxxx;
end
endmodule

【讨论】:

  • 请告诉我哪种情况会导致闩锁?
  • 假设在上面的程序中没有'else'命令。如果 enable =1 则 if 块将被执行,如果 enable != 1 则程序必须等到 enable 变为 1 并且必须存储先前的输出值。值的存储可以通过使用锁存器来完成。 @NavkantTyagi
猜你喜欢
  • 2015-06-14
  • 2023-03-31
  • 2012-12-16
  • 2014-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多