任务需求:用组合逻辑一拍求出最小值
req_flag:标志系统正在执行的任务数,
time_win:标志每一个任务所用时间值
time_flag:标志各个任务中使用时间最短的任务
设计思想:
①求最小值,从二进制数的高位到低位依次比较;
②标志位起到屏蔽作用;
例如比较8个四位二进制数:
1000;
1010;
0101;
1100;
0100;
0001;
0000;
1000;
假设有效位标志数req_flag=11110000,即前四个数位有效数据(正在运行的,参与最小值比较),后四位数据无效(不参与最小值比较);
首先,需要用标志位req_flag来屏蔽掉,后四个数;
然后,选出time1(11010000)前四个数最高位中为0的数;
~(~req_flag | time1)=00100000
由于前四个数只判断最高位就可以选出最小值,因此不需要再算。
其次,正常情况下需要从最高位到最低位依次判断选出最终最小值。
最后,如果有两个数相等都是最小值,那么选后面的位最小值。
代码:
`timescale 1ns/1ps
module min(
input clk,
input rst_n,
input [7:0] req_flag,
input [7:0] time_win1,
input [7:0] time_win2,
input [7:0] time_win3,
input [7:0] time_win4,
input [7:0] time_win5,
input [7:0] time_win6,
input [7:0] time_win7,
input [7:0] time_win8,
output [7:0] time_flag
);
wire [7:0] value_flag1;
wire [7:0] value_flag2;
wire [7:0] value_flag3;
wire [7:0] value_flag4;
wire [7:0] value_flag5;
wire [7:0] value_flag6;
wire [7:0] value_flag7;
wire [7:0] value_flag8;
wire [7:0] win1;
wire [7:0] win2;
wire [7:0] win3;
wire [7:0] win4;
wire [7:0] win5;
wire [7:0] win6;
wire [7:0] win7;
wire [7:0] win8;
assign win1 = {time_win1[7],time_win2[7],time_win3[7],time_win4[7],time_win5[7],time_win6[7],time_win7[7],time_win8[7]};
assign win2 = {time_win1[6],time_win2[6],time_win3[6],time_win4[6],time_win5[6],time_win6[6],time_win7[6],time_win8[6]};
assign win3 = {time_win1[5],time_win2[5],time_win3[5],time_win4[5],time_win5[5],time_win6[5],time_win7[5],time_win8[5]};
assign win4 = {time_win1[4],time_win2[4],time_win3[4],time_win4[4],time_win5[4],time_win6[4],time_win7[4],time_win8[4]};
assign win5 = {time_win1[3],time_win2[3],time_win3[3],time_win4[3],time_win5[3],time_win6[3],time_win7[3],time_win8[3]};
assign win6 = {time_win1[2],time_win2[2],time_win3[2],time_win4[2],time_win5[2],time_win6[2],time_win7[2],time_win8[2]};
assign win7 = {time_win1[1],time_win2[1],time_win3[1],time_win4[1],time_win5[1],time_win6[1],time_win7[1],time_win8[1]};
assign win8 = {time_win1[0],time_win2[0],time_win3[0],time_win4[0],time_win5[0],time_win6[0],time_win7[0],time_win8[0]};
assign value_flag1 = (((~req_flag )|win1) == 8'b1111_1111)? seq_flag : ~((~seq_flag )|win1);
assign value_flag2 = (((~value_flag1)|win2) == 8'b1111_1111)? value_flag1 : ~((~value_flag1)|win2);
assign value_flag3 = (((~value_flag2)|win3) == 8'b1111_1111)? value_flag2 : ~((~value_flag2)|win3);
assign value_flag4 = (((~value_flag3)|win4) == 8'b1111_1111)? value_flag3 : ~((~value_flag3)|win4);
assign value_flag5 = (((~value_flag4)|win5) == 8'b1111_1111)? value_flag4 : ~((~value_flag4)|win5);
assign value_flag6 = (((~value_flag5)|win6) == 8'b1111_1111)? value_flag5 : ~((~value_flag5)|win6);
assign value_flag7 = (((~value_flag6)|win7) == 8'b1111_1111)? value_flag6 : ~((~value_flag6)|win7);
assign value_flag8 = (((~value_flag7)|win8) == 8'b1111_1111)? value_flag7 : ~((~value_flag7)|win8);
generate
genvar i;
for(i=1;i<8;i=i+1)
begin:min_
assign time_flag[i] = value_flag8[i]&(~(|value_flag8[i-1:0]));
end
endgenerate
assign time_flag[0] = value_flag8[0];
endmodule
改进后的代码,进行了参数化和generate + for循环
`timescale 1ns/1ps
module min_v2#(
parameter DATA_NUM = 8,
parameter DATA_WIDTH = 4
)(
input clk,
input rst_n,
input [DATA_NUM-1:0] req_flag,
input [DATA_NUM*DATA_WIDTH-1:0] time_win,
output [DATA_NUM-1:0] time_flag
);
wire [DATA_WIDTH-1:0] time_wini [DATA_NUM-1 :0];
wire [DATA_NUM-1 :0] digit [DATA_WIDTH-1:0];
wire [DATA_NUM-1 :0] value_flag[DATA_WIDTH-1:0];
//将输入时间数值写入数组
generate
genvar i;
for(i=0;i<DATA_NUM;i=i+1)
begin:time_
assign time_wini[i] = time_win[DATA_WIDTH*(i+1)-1:DATA_WIDTH*i];
end
endgenerate
//将DATA_NUM个数,按位提取
generate
genvar di,ti;
for(di=0;di<DATA_WIDTH;di=di+1)
begin:data_i
for(ti=0;ti<DATA_NUM;ti=ti+1)
begin:time_i
assign digit[di][ti] = time_wini[ti][di];
end
end
endgenerate
//比较有效位
assign value_flag[DATA_WIDTH-1] = (((~req_flag )|digit[DATA_WIDTH-1]) == {DATA_NUM{1'b1}})? req_flag:~((~req_flag)|digit[DATA_WIDTH-1]);
generate
genvar fi;
for(fi=0;fi<DATA_WIDTH-1;fi=fi+1)
begin:flag_i
assign value_flag[fi] = (((~value_flag[fi+1])|digit[fi])=={DATA_NUM{1'b1}})?value_flag[fi+1]:~((~value_flag[fi+1])|digit[fi]);
end
endgenerate
//如果由两个数都是最小值,那么选后面的
generate
genvar j;
for(j=1;j<DATA_NUM;j=j+1)
begin:min_j
assign time_flag[j] = value_flag[0][j]&(~(|value_flag[0][j-1:0]));
end
endgenerate
assign time_flag[0] = value_flag[0][0];
endmodule
分享出来希望对各位同学有帮助,整理不易,点个赞再走呗。