是的3.31
区分casex,case以及caseZ语句的特点:
其中casez语句用来处理不考虑高阻值z的比较过程,casex语句则将高阻值z和不定值都视为不必关心的情况。所谓不必关心的情况,即在表达式进行比较时,不将该位的状态考虑在内。这样在case语句表达式进行比较时,就可以灵活地设置以对信号的某些位进行比较。
注意!!!!case语句只能放在always块里面,对reg型变量进行处理,所以如果想用case语句替代if-else来处理wire变量时,得先设个reg再赋值
今日题目1:用两个83编码器实现164编码器:
、
其实自己一直在想算法,后来根据真值表发现每个83编码器有一个输出有效信号EO,当编码器8个输入位全是0的时候EO就是1,那么我们可以根据把16位拆成高8位和低8位,分别高8位和低八位进行编码;然后分析算法,可以发现高位编码器的EO特别重要,如果EO是1说明高位全是0,那么只用管低位的编码将三位结果高位补0变成二进制数就可以了;如果EO是0说明高位至少有一个数是1,那么低位的结果就不用管(因为底层模块是优先编码器),所以在高位编码器的输出结果直接高位补1就可以了(等价为4'b1000+3'b结果)。
`timescale 1ns/1ns
module encoder_83(
input [7:0] I ,
input EI ,
output wire [2:0] Y ,
output wire GS ,
output wire EO
);
assign Y[2] = EI & (I[7] | I[6] | I[5] | I[4]);
assign Y[1] = EI & (I[7] | I[6] | ~I[5]&~I[4]&I[3] | ~I[5]&~I[4]&I[2]);
assign Y[0] = EI & (I[7] | ~I[6]&I[5] | ~I[6]&~I[4]&I[3] | ~I[6]&~I[4]&~I[2]&I[1]);
assign EO = EI&~I[7]&~I[6]&~I[5]&~I[4]&~I[3]&~I[2]&~I[1]&~I[0];
assign GS = EI&(I[7] | I[6] | I[5] | I[4] | I[3] | I[2] | I[1] | I[0]);
//assign GS = EI&(| I);
endmodule
module encoder_164(
input [15:0] A ,
input EI ,
output wire [3:0] L ,
output wire GS ,
output wire EO
);
wire EO1, EO2, GS1, GS2;
wire [2:0] highout;
wire [2:0] lowout;
encoder_83 high (.I(A[15:8]), .EI(EI), .Y(highout), .GS(GS1), .EO(EO1));
encoder_83 low (.I(A[7:0]), .EI(EI), .Y(lowout), .GS(GS2), .EO(EO2));
assign GS = GS1&GS2||GS1&~GS2||~GS1&GS2;
assign EO = EO1&&EO2;
/*
if (EO1)
assign L = {0, lowout};
else
assign L = 4'b1000+ highout;
*/
assign L = GS1 ? {1'b1,highout}:{1'b0,lowout};
endmodule
以上就是代码,但是在做的时候又犯了基础语法错误,把if语句放在了always块外面了……回顾了知识才想起条件判断语句都必须要放在always块里面……如果在外面可以用问号语句写个MUX。
4.6
今天刷题做到了一个边沿检测的题,借助这个题目来回顾一下边沿检测的经典算法:
主要讲两个问题:
1. 打两拍防止亚稳态;先用reg1储存当前值,再用reg2储存reg1原本的值,也就是说两个寄存器分别代表当前周期和上一个周期时钟上升沿来临的时候的值;
2. ===消除不定态;当用逻辑判断表达式的时候,只用==的形式会忽略不定态,导致输出也变成不定态;用全等号可以消除不定态的情况,只有0和1两种输出,不会有不定态的输出(不定态输出为0)