感想:发现在一个舒适区学习,所以直接跳到Circuit,在失败中找进步,等碰到问题后面再补前面的。
疑问:为什么会用到这些门?这些门的实际应用是怎么样的?
1.Wire
module top_module (
input in,
output out);
assign out = in;
endmodule
2.GND
module top_module (
output out);
assign out = 1'b0;
endmodule
3.NOR
module top_module (
input in1,
input in2,
output out);
assign out = !(in1||in2);
endmodule
Debug:忘记在第5行加“;”所以报错
4.Another gate
module top_module (
input in1,
input in2,
output out);
assign out = in1&&!in2;
endmodule
5.Two gates
module top_module (
input in1,
input in2,
input in3,
output out);
wire in;
assign in = !(in1^in2);
assign out = in^in3;
endmodule
6.各种门
module top_module(
input a, b,
output out_and,
output out_or,
output out_xor,
output out_nand,
output out_nor,
output out_xnor,
output out_anotb
);
assign out_and = a&&b;
assign out_or = a||b;
assign out_xor = a^b;
assign out_nand = !(a&&b);
assign out_nor = !(a||b);
assign out_xnor = !(a^b);
assign out_anotb = a&&(!b);
endmodule
有很多参数看不懂什么意思,所以直接AI了。 这种简单的门要知道他的作用,比如
&&:只能判断多个参数是否全为1。
^ :判断是否存在1,更可以判断多个参数是否相同,感觉与“&&”补充做兄弟。
|| :则是判断全为0,且仅限能判断有1,有没有可以直接判断有几个1的?有!比如a&&(!b)如果为1可以直接针对1,0来作出判断。那是否还能进一步拓展到多个参数?a&&(!b)&&c为1则是1,0,1,a&&(!b)&&(!c)为1则是1,0,0。
7.7420芯片
module top_module (
input p1a, p1b, p1c, p1d,
output p1y,
input p2a, p2b, p2c, p2d,
output p2y );
assign p1y = !(p1a&p1b&p1c&p1d);
assign p2y = !(p2a&p2b&p2c&p2d);
endmodule
疑问:前面1-7是简单的逻辑门,门具体有什么实际意义,就像第一题 assign out = 1'b0表示接地,那这些门能真正表示什么东西?我们的硬件、芯片和这些有什么关系?|
8.真值表
这题设计选择性语言,因此要学习if语法,因此2.4.3题的结果如下:
// synthesis verilog_input_version verilog_2001
module top_module(
input a,
input b,
input sel_b1,
input sel_b2,
output wire out_assign,
output reg out_always );
always @(*) begin
if (sel_b1&sel_b2 == 1) begin
out_always = b;
end
else begin
out_always = a;
end
end
assign out_assign = (sel_b1&sel_b2 == 1) ? b : a;
endmodule
然后我的思路是在输出结果为1时,找出对应输入参数的规律,以此来作出一个筛选:
module top_module(
input x3,
input x2,
input x1, // three inputs
output f // one output
);
always @(*) begin
if (x2 == 1) begin //以 x 1 x为前提筛选
if (x3^x1 == 1) begin
if (x3 == 1) begin // 排除1 1 0
f = 0;
end
else begin
f = 1;
end
end
else begin
f = 1;
end
end
else begin
if (x1&x3 == 1) begin // 选择 1 0 1
f = 1;
end
else begin
f = 0;
end
end
end
endmodule
我这个筛选方法比较机械,规律不具有普遍性,因此参考价值不大。进一步修改的话可能是先找更简单的规律,然后用优化代码。
附上官方solution:
module top_module (
input x3,
input x2,
input x1,
output f
);
// This truth table has four minterms.
assign f = ( ~x3 & x2 & ~x1 ) |
( ~x3 & x2 & x1 ) |
( x3 & ~x2 & x1 ) |
( x3 & x2 & x1 ) ;
// It can be simplified, by boolean algebra or Karnaugh maps.
// assign f = (~x3 & x2) | (x3 & x1);
// You may then notice that this is actually a 2-to-1 mux, selected by x3:
// assign f = x3 ? x1 : x2;
endmodule
感觉官方使用基本门更灵活,和第六题的反思相呼应。
9. 2-bits equality
module top_module(
input [1:0] A,
input [1:0] B,
output z);
assign z = (A == B);
endmodule
10.Simple circuit A
module top_module (input x, input y, output z);
assign z = (x^y) & x;
endmodule
11.Simple circuit B
module top_module ( input x, input y, output z );
assign z = (x^y == 0)? 1:0;
endmodule
12. Circuit A combined with circuit B
module top_module (input x, input y, output z);
wire z1,z2,z3,z4;//设置中间参数
assign z1 = (x^y)&x;
assign z2 = !(x^y);
assign z3 = (x^y)&x;
assign z4 = !(x^y);
assign z = (z1|z2)^(z3&z4);
endmodule
官方solution中用到了内嵌模块,通过在主模块下方添加module,可以直接引用函数,适合函数很长很复杂时使用,这和普通的编程语言很像。官方solution如下:
module top_module(
input x,
input y,
output z);
wire o1, o2, o3, o4;
A ia1 (x, y, o1);
B ib1 (x, y, o2);
A ia2 (x, y, o3);
B ib2 (x, y, o4);
assign z = (o1 | o2) ^ (o3 & o4);
// Or you could simplify the circuit including the sub-modules:
// assign z = x|~y;
endmodule
module A (
input x,
input y,
output z);
assign z = (x^y) & x;
endmodule
module B (
input x,
input y,
output z);
assign z = ~(x^y);
endmodule
13. Ring or vibrate
module top_module (
input ring,
input vibrate_mode,
output ringer, // Make sound
output motor // Vibrate
);
assign ringer = ring&!vibrate_mode;
assign motor = ring&vibrate_mode;
endmodule
14.空调遥控器
难点在于理解题意,我的难点在于难理解fan这个的input条件
module top_module (
input too_cold,
input too_hot,
input mode,
input fan_on,
output heater,
output aircon,
output fan
);
assign heater = too_cold&mode;
assign aircon = too_hot&!mode;
assign fan = fan_on|too_cold&mode|too_hot&!mode;
endmodule
15. Population count
这题设计选择性语言,因此要学习Case语法,因此2.4.5题的结果如下:
// synthesis verilog_input_version verilog_2001
module top_module (
input [2:0] sel,
input [3:0] data0,
input [3:0] data1,
input [3:0] data2,
input [3:0] data3,
input [3:0] data4,
input [3:0] data5,
output reg [3:0] out );//
always@(*) begin // This is a combinational circuit
case(sel)
3'b000: out[3:0] = data0[3:0];
3'b001: out[3:0] = data1[3:0];
3'b010: out[3:0] = data2[3:0];
3'b011: out[3:0] = data3[3:0];
3'b100: out[3:0] = data4[3:0];
3'b101: out[3:0] = data5[3:0];
default: out = 0;
endcase
end
endmodule
如果用a&b&!c的判断语句可以判断1在哪个位置,和第8题的解法相似,官方的solution如下:
module top_module (
input [2:0] in,
output [1:0] out
);
assign out[0] = (~in[2] & ~in[1] & in[0]) | (~in[2] & in[1] & ~in[0]) | (in[2] & ~in[1] & ~in[0]) | (in[2] & in[1] & in[0]);
assign out[1] = (in[1] & in[0]) | (in[2] & in[0]) | (in[2] & in[1]);
endmodule
我是用case语句写的:
module top_module(
input [2:0] in,
output [1:0] out );
always @(*) begin
case(in)
3'b000:out = 0;
3'b001:out = 1;
3'b010:out = 1;
3'b100:out = 1;
3'b111:out = 3;
default:out =2;
endcase
end
endmodule
16.Gates and vectors
第一种解法是用case语句列出所有结果,最多有16个case,所以这个太机械先排除。
第二种解法是列出真值表找规律,真值表也有16行,暂不考虑。
第三种我觉得是先分类再开始做,也是找规律,由于第17题是16题的拓展,所以如果可以找出第三种解法会简单许多