(自用)高集第三章作业
第一题:
设计一个组合逻辑电路,检测输入32位0/1向量中从高到低第一个1出现的位置,如果向量为全0则输出32。例如:
输入00011000 10000000 00000000 00000000,输出3;
输入00000000 11111111 00000000 00000000,输出8;
输入00000000 00000000 00000000 00001010,输出28.
模块输入输出功能定义:
名称 | 方向 | 位宽 | 描述 |
---|---|---|---|
data_in | I | 32 | 输入0/1向量 |
pos_out | O | 6 | 前导1出现位置,取值范围0 ~ 32量 |
设计要求:
Verilog实现代码可综合,逻辑延迟越小越好,给出仿真结果。
第一题思路:
判断第一个1的输出可由32位的每个2的权位决定,比如输入256,其二进制表示为0000_0000_0000_0000_0000_0001_0000_0000,权位是第九个,我们只要大于第九个的权位都可以得到一个结论:其输出一定>=23,类似我们就能通过比较2的权位知道第一个1的位置
代码:
module Vector_leading_1_detector
(
input clk, //时钟输入,该模块无需时钟
input rst_n, //复位信号
input [31:0] data_in, //32位的输入数据
output reg [5:0] pos_out //输出第一个1的位置
);
/****************组合逻辑实现过程*********************/
always @ (*) //当输入data_in >= 2^(31)时,pos_out输出位0,;data_in >= 2^(30),pos_out输出为1,以此类推...
begin
if(!rst_n)
pos_out <= 6'd0;
else if(data_in == 32'd0)
pos_out <= 6'd32;
else if(data_in >= 32'd2147483648)
pos_out <= 6'd0;
else if(data_in >= 32'd1073741824)
pos_out <= 6'd1;
else if(data_in >= 32'd536870912)
pos_out <= 6'd2;
else if(data_in >= 32'd268435456)
pos_out <= 6'd3;
else if(data_in >= 32'd134217728)
pos_out <= 6'd4;
else if(data_in >= 32'd67108864)
pos_out <= 6'd5;
else if(data_in >= 32'd33554432)
pos_out <= 6'd6;
else if(data_in >= 32'd16777216)
pos_out <= 6'd7;
else if(data_in >= 32'd8388608)
pos_out <= 6'd8;
else if(data_in >= 32'd4194304)
pos_out <= 6'd9;
else if(data_in >= 32'd2097152)
pos_out <= 6'd10;
else if(data_in >= 32'd1048576)
pos_out <= 6'd11;
else if(data_in >= 32'd524288)
pos_out <= 6'd12;
else if(data_in >= 32'd262144)
pos_out <= 6'd13;
else if(data_in >= 32'd131072)
pos_out <= 6'd14;
else if(data_in >= 32'd65536)
pos_out <= 6'd15;
else if(data_in >= 32'd32768)
pos_out <= 6'd16;
else if(data_in >= 32'd16384)
pos_out <= 6'd17;
else if(data_in >= 32'd8192)
pos_out <= 6'd18;
else if(data_in >= 32'd4096)
pos_out <= 6'd19;
else if(data_in >= 32'd2048)
pos_out <= 6'd20;
else if(data_in >= 32'd1024)
pos_out <= 6'd21;
else if(data_in >= 32'd512)
pos_out <= 6'd22;
else if(data_in >= 32'd128)
pos_out <= 6'd23;
else if(data_in >= 32'd64)
pos_out <= 6'd24;
else if(data_in >= 32'd32)
pos_out <= 6'd25;
else if(data_in >= 32'd16)
pos_out <= 6'd26;
else if(data_in >= 32'd8)
pos_out <= 6'd27;
else if(data_in >= 32'd4)
pos_out <= 6'd28;
else if(data_in >= 32'd2)
pos_out <= 6'd29;
else if(data_in >= 32'd1)
pos_out <= 6'd30;
end
endmodule
仿真结果:
第二题:
设计一个序列检测同步时序逻辑电路,要实现的功能如下:当已有输入码流出现序列111000或101110时输出检测信号为1,否则输出为0。在时序上检测到完整序列的下一个时钟周期输出检测结果。输入信号有效为1时表示当前输入有效,否则表示无效。之前输入依旧计入序列中并不清零,即允许序列重叠检测。例如:输入码流(设输入数据均有效)和输出检测为
input : 0 0 1 1 1 0 0 0 1 1 0 1 1 1 0 0 0 0
out : 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1
模块输入输出功能定义:
名称 | 方向 | 位宽 | 描述 |
---|---|---|---|
clk | I | 1 | 系统时钟 |
rst_n | I | 1 | 异步复位,低电平有效 |
din_vid | I | 1 | 输入数据有效指示 |
din | I | 1 | 输入数据 |
result | O | 1 | 输出检测结果 |
第二题思路:
使用三段式状态机,判断每一个input信号来,跳转到下一个状态,继续判断input信号,之后有时间在补充画状态图。。要考试了没时间整理。。
代码:
module detect_111000_101110
(
input clk, //输入时钟
input rst_n, //全局复位
input data_in, //输入数据流
input din_vld, //数据流有效使能
output reg result //输出检测序列结果的标记信号
);
/**********三段式状态机***************/
reg [3:0] current_state,next_state;
parameter S0 = 4'd0, //定义状态
S1 = 4'd1,
S2 = 4'd2,
S3 = 4'd3,
S4 = 4'd4,
S5 = 4'd5,
S6 = 4'd6,
S7 = 4'd7,
S8 = 4'd8,
S9 = 4'd9,
S10 = 4'd10,
S11 = 4'd11;
/*************第一段,下个状态给当前状态**************/
always @ (posedge clk,negedge rst_n) begin
if(!rst_n)
current_state <= S0;
else
current_state <= next_state;
end
/*************第二段:判断状态的跳转条件**************/
always @ (*)
begin
next_state = 4'dx;
case(current_state)
S0 : if(data_in == 1) //data_in == 1跳出S0
next_state = S1;
else
next_state = S0;
S1 : if(data_in == 0)
next_state = S2;
else
next_state = S7;
S2 : if(data_in == 1)
next_state = S3;
else
next_state = S0;
S3 : if(data_in == 1)
next_state = S4;
else
next_state = S2;
S4 : if(data_in == 1)
next_state = S5;
else
next_state = S2;
S5 : if(data_in == 0)
next_state = S6;
else
next_state = S8;
S6 : if(data_in == 0)
next_state = S0;
else
next_state = S1;
S7 : if(data_in == 1)
next_state = S8;
else
next_state = S2;
S8 : if(data_in == 0)
next_state = S9;
else
next_state = S8;
S9 : if(data_in == 0)
next_state = S10;
else
next_state = S1;
S10 : if(data_in == 0)
next_state = S11;
else
next_state = S1;
S11 : if(data_in == 0)
next_state = S0;
else
next_state = S1;
default : next_state = S0;
endcase
end
/*************第三段:输出信号**************/
always @ ( posedge clk,negedge rst_n)
begin
if(!rst_n)
begin
result <= 1'b0;
end
else
case(next_state)
S0 : begin
result <= 1'b0;
end
S1 : begin
result <= 1'b0;
end
S2 : begin
result <= 1'b0;
end
S3 : begin
result <= 1'b0;
end
S4 : begin
result <= 1'b0;
end
S5 : begin
result <= 1'b0;
end
S6 : begin
result <= 1'b1;
end
S7 : begin
result <= 1'b0;
end
S8 : begin
result <= 1'b0;
end
S9 : begin
result <= 1'b0;
end
S10 : begin
result <= 1'b0;
end
S11 : begin
result <= 1'b1;
end
default : result <= 1'b0;
endcase
end
endmodule