特点:位宽参数化
实现代码如下:
`timescale 1ns / 1ps
//
// Company: nssc
// Engineer: liumeng
// Create Date: 2021/12/18 19:07:53
// Module Name: one_hot_to_bin
// Revision 0.01 - File Created
//
module one_hot_to_bin #(
parameter ONE_HOT_WIDTH = 8
)(
input[ONE_HOT_WIDTH-1 : 0] one_hot_code,
output[$clog2(ONE_HOT_WIDTH)-1 : 0] bin_code,
output valid
);
localparam TRUE_BIN_WIDTH = log_two(ONE_HOT_WIDTH);
localparam TRUE_ONE_HOT_WIDTH = 2**(TRUE_BIN_WIDTH);
wire[TRUE_BIN_WIDTH-1:0] bin_code_temp;
function integer log_two;
input integer number; begin
log_two=(number <=1) ? 1: 0;
while(2**log_two<number) begin
log_two=log_two+1;
end
end
endfunction
wire[TRUE_ONE_HOT_WIDTH-1 : 0] true_one_hot_code;
assign true_one_hot_code = {TRUE_ONE_HOT_WIDTH{1'b0}} | one_hot_code;
localparam or_elements_number = TRUE_ONE_HOT_WIDTH>>1;
wire[TRUE_ONE_HOT_WIDTH-1 : 0] or_bit[TRUE_BIN_WIDTH-1 : 0][or_elements_number-1 : 0];
genvar i,j,k;
for(i=0;i<TRUE_BIN_WIDTH;i=i+1) begin : loop_1
for (j=0; j<or_elements_number; j=j+1) begin : loop_2
for(k=0;k<TRUE_ONE_HOT_WIDTH;k=k+1) begin :loop_3
if(k%(2**(i+1))<(2**(i))) begin
assign or_bit[i][j][k] = true_one_hot_code[k];
end else begin
assign or_bit[i][j][k] = 1'b0;
end
end
assign bin_code_temp[i] = ~|(or_bit[i][j]);
end
end
assign valid = |one_hot_code ? 1'b1 : 1'b0;
assign bin_code = bin_code_temp;
endmodule
仿真代码如下:
`timescale 1ns / 1ps
//
// Company: nssc
// Engineer: liumeng
// Create Date: 2021/12/18 19:17:53
// Module Name: sim_one_hot_to_bin
// Revision 0.01 - File Created
//
module sim_one_hot_to_bin;
localparam ONE_HOT_WIDTH = 11;
localparam BIN_WIDTH = log_two(ONE_HOT_WIDTH);
function integer log_two;
input integer number; begin
log_two=(number <=1) ? 1: 0;
while(2**log_two<number) begin
log_two=log_two+1;
end
end
endfunction
reg[ONE_HOT_WIDTH : 0] one_hot_code_temp;
wire[ONE_HOT_WIDTH-1 : 0] one_hot_code;
wire[BIN_WIDTH-1 : 0] bin_code;
wire valid;
initial begin
one_hot_code_temp = 1;
#100;
repeat(200) begin
one_hot_code_temp ={one_hot_code_temp[ONE_HOT_WIDTH-1 : 0],one_hot_code_temp[ONE_HOT_WIDTH]};
#100;
end
#200;
one_hot_code_temp = {ONE_HOT_WIDTH{1'b0}};
end
assign one_hot_code = one_hot_code_temp[ONE_HOT_WIDTH-1:0];
one_hot_to_bin#(
.ONE_HOT_WIDTH ( ONE_HOT_WIDTH )
)u_one_hot_to_bin(
.one_hot_code ( one_hot_code ),
.bin_code ( bin_code ),
.valid ( valid )
);
endmodule
仿真波形图如下: