HDLBits 刷题笔记
第17题 Vectorr
使用Generate for时候必须要注意以下几点要求:
- 必须使用genvar声明一个正整数变量,用作for循环的判断变量;
- for循环内部的的语句必须写在begin-end里面;
- begin-and语句块需要一个命名。
代码:
module top_module(
input [7:0] in,
output [7:0] out
);
genvar i;
generate
for(i=0;i<=7;i=i+1)
begin: abc
assign out[7-i]=in[i];
end
endgenerate
endmodule
第18题 Vector4
如果想要将一个字符串连续串联多次,可以写成这种形式:{num{vector}}
例如:
{5{1'b1}} // 5'b11111 (or 5'd31 or 5'h1f)
{2{a,b,c}} // The same as {a,b,c,a,b,c}
{3'd5, {2{3'd6}}} // 9'b101_110_110. It's a concatenation of 101 with
// the second vector, which is two copies of 3'b110.
代码:
module top_module (
input [7:0] in,
output [31:0] out );//
assign out={{24{in[7]}},in[7:0]};
// assign out = { replicate-sign-bit , the-input };
endmodule
第19题 Vector5
代码:
module top_module (
input a, b, c, d, e,
output [24:0] out );//
// The output is XNOR of two vectors created by
// concatenating and replicating the five inputs.
// assign out = ~{ ... } ^ { ... };
assign out[4:0]=~{5{e}}^{a,b,c,d,e};
assign out[9:5]=~{5{d}}^{a,b,c,d,e};
assign out[14:10]=~{5{c}}^{a,b,c,d,e};
assign out[19:15]=~{5{b}}^{a,b,c,d,e};
assign out[24:20]=~{5{a}}^{a,b,c,d,e};
endmodule
第20题 Module
法一(By position)
代码:
module top_module ( input a, input b, output out );
mod_a inst_1(a,b,out);
endmodule
法二(By name)
代码:
module top_module ( input a, input b, output out );
mod_a inst_1(.out(out),.in1(a),.in2(b));
endmodule
第21题 Module pos
代码:
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a inst_1(out1,out2,a,b,c,d);
endmodule
第22题 Module name
代码:
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a inst_1(.out1(out1),.out2(out2),.in1(a),.in2(b),.in3(c),.in4(d));
endmodule
第23题 Module shift
代码:
module top_module ( input clk, input d, output q );
wire a,b;
my_dff inst_1(.q(a),.clk(clk),.d(d));
my_dff inst_2(.q(b),.clk(clk),.d(a));
my_dff inst_3(.q(q),.clk(clk),.d(b));
endmodule
第24题 Module shift8
代码:
module top_module (
input clk,
input [7:0] d,
input [1:0] sel,
output [7:0] q
);
wire [7:0]a,b,c;
my_dff8 inst_1(.q(a),.clk(clk),.d(d));
my_dff8 inst_2(.q(b),.clk(clk),.d(a));
my_dff8 inst_3(.q(c),.clk(clk),.d(b));
always @(*)
case(sel)
2'b00: q=d;
2'b01: q=a;
2'b10: q=b;
2'b11: q=c;
endcase
endmodule
第25题 Module_add
代码:
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [15:0] f,g,aa,bb,aaa,bbb;
wire j;
assign aa=a[15:0];
assign bb=b[15:0];
assign aaa=a[31:16];
assign bbb=b[31:16];
parameter h=0;
add16 inst_1(.sum(f),.cout(j),.cin(h),.a(aa),.b(bb));
add16 inst_2(.sum(g),.cout(),.cin(j),.a(aaa),.b(bbb));
assign sum={g,f};
endmodule
第26题 Module fadd
代码:
module top_module (
input [31:0] a,
input [31:0] b,
output [31:0] sum
);//
wire [15:0]sum1,sum2,aa,bb,aaa,bbb;
wire t;
assign aa=a[15:0];
assign bb=b[15:0];
assign aaa=a[31:16];
assign bbb=b[31:16];
parameter y=0;
add16 inst_1(.sum(sum1),.cout(t),.cin(y),.a(aa),.b(bb));
add16 inst_2(.sum(sum2),.cout(),.cin(t),.a(aaa),.b(bbb));
assign sum={sum2,sum1};
endmodule
module add1 ( input a, input b, input cin, output sum, output cout );
assign sum=a+b+cin;
always @(*)
if((cin&(a|b))|((~cin)&a&b))
cout=1'b1;
else
cout=1'b0;
endmodule
第27题 Module cseladd
代码:
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [15:0] aa,bb,aaa,bbb,aaaa,bbbb,sum1,sum2,sum3,sumsum;
wire t;
parameter q=0;
parameter w=1;
assign aa=a[15:0];
assign bb=b[15:0];
assign aaa=a[31:16];
assign bbb=b[31:16];
assign aaaa=a[31:16];
assign bbbb=b[31:16];
add16 inat_1(.sum(sum1),.cout(t),.cin(q),.a(aa),.b(bb));
add16 inat_2(.sum(sum2),.cout(),.cin(q),.a(aaa),.b(bbb));
add16 inat_3(.sum(sum3),.cout(),.cin(w),.a(aaaa),.b(bbbb));
always @(*)
case(t)
1'b0: sumsum=sum2;
1'b1: sumsum=sum3;
endcase
assign sum={sumsum,sum1};
endmodule
第28题 Module addsub
代码:
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] sum
);
wire [15:0] aa,bb,aaa,bbb,sum1,sum2;
wire t;
wire [31:0] tt;
assign tt= b^{32{sub}};
assign aa=a[15:0];
assign bb=tt[15:0];
assign aaa=a[31:16];
assign bbb=tt[31:16];
add16 inst_1(.sum(sum1),
.cout(t),
.cin(sub),
.a(aa),
.b(bb));
add16 inst_2(.sum(sum2),
.cout(),
.cin(t),
.a(aaa),
.b(bbb));
assign sum={sum2,sum1};
endmodule
第29题 Alwaysblock1
关于wire和reg的一个注释:
assign语句的左侧必须是net类型(例如wire).
而过程赋值的左侧(在always块中)必须是变量类型(例如reg)。
这些类型(wire与reg)与合成的硬件无关,只是Verilog用作硬件模拟语言时留下的语法。
代码:
// synthesis verilog_input_version verilog_2001
module top_module(
input a,
input b,
output wire out_assign,
output reg out_alwaysblock
);
assign out_assign=a&b;
always @(*)
out_alwaysblock=a&b;
endmodule
第30题 Alwaysblock2
对于硬件合成,有两种类型的always块是相关的:
Combinational: always @(*)
Clocked: always @(posedge clk)
Verilog中有三种类型的分配:
连续赋值(assign x=y;)。只能在不在过程内部时使用(“always block”)。
过程块赋值:(x=y;)。只能在过程内部使用。 在combinational always 块, 使用阻塞赋值
过程非阻塞赋值:(x<=y;)。只能在过程内部使用。在 clocked always 块, 使用非阻塞赋值
代码:
// synthesis verilog_input_version verilog_2001
module top_module(
input clk,
input a,
input b,
output wire out_assign,
output reg out_always_comb,
output reg out_always_ff );
assign out_assign=a^b;
always @(*)
out_always_comb=a^b;
always @(posedge clk)
out_always_ff=a^b;
endmodule
第31题 Always if
上图有两种表达方式:
第一种 procedural语句
//procedural statement
always @(*) begin
if (condition) begin
out = x;
end
else begin
out = y;
end
end
第二种 assign 语句
//assign statement
assign out = (condition) ? x : y;
assign out = (condition) ? x : y;
代码:
// 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 );
assign out_assign=(sel_b1&sel_b2)?b:a;
always @(*)
begin
if(sel_b1&sel_b2)
begin
out_always=b;
end
else
begin
out_always=a;
end
end
endmodule
第32题 Always if2
代码:
// synthesis verilog_input_version verilog_2001
module top_module (
input cpu_overheated,
output reg shut_off_computer,
input arrived,
input gas_tank_empty,
output reg keep_driving ); //
always @(*) begin
if (cpu_overheated)
shut_off_computer = 1;//cpu发热,电脑关闭
else
shut_off_computer = 0;
end
always @(*) begin
if (~arrived)
keep_driving = ~gas_tank_empty; // 还未到目的地,油箱空了,不跑;如果油箱没有空,就接着跑
else
keep_driving = 0; // 到达目的地,不管油箱空没空,都不能跑
end
endmodule
第33题 Always case
代码:
// 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=data0;
3'b001:out=data1;
3'b010:out=data2;
3'b011:out=data3;
3'b100:out=data4;
3'b101:out=data5;
3'b110:out=0;
3'b111:out=0;
endcase
end
endmodule
每个case项只能执行一条语句。这使得在C中使用的“break”是不必要的。但这意味着如果你需要不止一个语句,你必须使用begin。。。结束。示例:
always @(*) begin // This is a combinational circuit
case (in)
1'b1: begin
out = 1'b1; // begin-end if >1 statement
end
1'b0: out = 1'b0;
default: out = 1'bx;
endcase
end
第34题 Always case2
代码:
// synthesis verilog_input_version verilog_2001
module top_module (
input [3:0] in,
output reg [1:0] pos );
always @(*)
begin
case(in)
4'b0000:pos=0;
4'b0001:pos=2'd0;
4'b0010:pos=2'd1;
4'b0011:pos=2'd0;
4'b0100:pos=2'd2;
4'b0101:pos=2'd0;
4'b0110:pos=2'd1;
4'b0111:pos=2'd0;
4'b1000:pos=2'd3;
4'b1001:pos=2'd0;
4'b1010:pos=2'd1;
4'b1011:pos=2'd0;
4'b1100:pos=2'd2;
4'b1101:pos=2'd0;
4'b1110:pos=2'd1;
4'b1111:pos=2'd0;
endcase
end
endmodule
第35题 Always casez
数字?是z的同义词。所以2'bz0和2'b?0是一样的
代码:
// synthesis verilog_input_version verilog_2001
module top_module (
input [7:0] in,
output reg [2:0] pos );
always @(*)
begin
casez(in[7:0])
8'bzzzzzzz1:pos=0;
8'bzzzzzz1z:pos=1;
8'bzzzzz1zz:pos=2;
8'bzzzz1zzz:pos=3;
8'bzzz1zzzz:pos=4;
8'bzz1zzzzz:pos=5;
8'bz1zzzzzz:pos=6;
8'b1zzzzzzz:pos=7;
default pos=0;
endcase
end
endmodule