您的设计可能是可合成的,但根据上面的评论,您会得到一个闩锁。如果您摆脱了闩锁,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