module top_module( output one );
// Insert your code here
assign one = 1;
endmodule
module top_module ( output zero );
assign zero = 1'b0;
endmodule
知识点:连续赋值
module top_module( input in, output out );
assign out = in;
endmodule
module top_module(
input a,b,c,
output w,x,y,z );
assign w = a;
assign x = b;
assign y = b;
assign z = c;
endmodule
知识点:
1、位运算符总结:
module top_module( input in, output out );
assign out = ~in;
endmodule
知识点:
1、要注意区分“按位与(&)”和“逻辑与(&&)”
法一:
module top_module(
input a,
input b,
output out );
assign out = a&b;
endmodule
法二:
知识点:熟悉三目运算符,但是不可取,逻辑太复杂了,要用的器件更多,浪费资源。
module top_module(
input a,
input b,
output out );
assign out = ( a == 1 && b == 1 ) ? 1 : 0;
endmodule
知识点:或非门,不就是对位运运算符进行一个简单的组合
module top_module(
input a,
input b,
output out );
assign out =~(a|b);
endmodule
知识点:同或(异或非门)
~a^b 等价于a~^b
module top_module(
input a,
input b,
output out );
assign out = a~^b;
endmodule
知识点:小个小型组合逻辑电路的实现
module top_module (
input a,
input b,
input c,
input d,
output out,
output out_n );
wire w1, w2; // Declare two wires (named w1 and w2)
assign w1 = a&b; // First AND gate
assign w2 = c&d; // Second AND gate
assign out = w1|w2; // OR gate: Feeds both 'out' and the NOT gate
assign out_n = ~out; // NOT gate
endmodule
module top_module (
input p1a, p1b, p1c, p1d, p1e, p1f,
output p1y,
input p2a, p2b, p2c, p2d,
output p2y );
wire w1, w2, w3, w4;
assign w1 = p2a & p2b;
assign w2 = p1c & p1b & p1a;
assign w3 = p2c & p2d;
assign w4 = p1f & p1e & p1d;
assign p1y = w2 | w4;
assign p2y = w1 | w3;
endmodule
知识点:
类似于这种排线:
module top_module (
input wire [2:0] vec,
output wire [2:0] outv,
output wire o2,
output wire o1,
output wire o0 ); // Module body starts after module declaration
assign o0 = vec[0];
assign o1 = vec[1];
assign o2 = vec[2];
assign outv = vec;
endmodule
知识点:
1、vector声明:
wire [7:0] w; // 8-bit wire reg [4:1] x; // 4-bit reg output reg [0:0] y; // 1-bit reg, 虽然只有一根,但是他任然是一个vector input wire [3:-2] z; // 6-bit wire input ,里面允许有负数 output [3:0] a; // 4-bit output wire,没有特殊声明的话,默认是wire类型 wire [0:7] b; // 8-bit wire ,其中b[0]是最高位
2、Implicit nets
wire [2:0] a, c; // Two vectors assign a = 3'b101; // a = 101 assign b = a; // b = 1 ,关键在这里,这里默认创建的b是1-bit的,他只会取保留最低为的值 assign c = b; // c = 001 <-- bug ,这样c就不是我们预想的样子,接下来用c运算则会出现错误。 my_module i1 (d,e); // d and e are implicitly one-bit wide if not declared. // This could be a bug if the port was intended to be a vector. 避免犯错:在开头的地方加上,`default_nettype
3、二维矩阵的定义
reg [7:0] mem [255:0]; // 256个8-bit reg mem2 [28:0]; // 29个1-bit(1-bit是默认出来的)
4、向量中的部分元素获取
w[3:0] // 获取w向量中的低四位 x[1] // 获取w向量中的第一位 x[1:1] // 同上,获取w向量中的第一位 z[-1:-2] // z向量的最低两位 b[3:0] // 若定义:wire [0:5] b,则b[3:0]表达是非法的。向量部分选择必须与声明的方向匹配 ,这里最容易出错。 assign w[3:0] = b[0:3]; // w[3]=b[0], w[2]=b[1], 以此类推
`default_nettype none // Disable implicit nets. Reduces some types of bugs.
module top_module(
input wire [15:0] in,
output wire [7:0] out_hi,
output wire [7:0] out_lo );
assign out_lo = in[7:0];
assign out_hi = in[15:8];
endmodule
知识点:拼接符({})的灵活运用
module top_module(
input [31:0] in,
output [31:0] out );//
assign out[31:0] = {in[7:0],in[15:8],in[23:16],in[31:24]};
// assign out[31:24] = ...;
endmodule
知识点:区分按位或与逻辑或
module top_module(
input [2:0] a,
input [2:0] b,
output [2:0] out_or_bitwise,
output out_or_logical,
output [5:0] out_not
);
assign out_or_bitwise = a | b;
assign out_or_logical = a || b;
assign out_not = {~b,~a};
endmodule
module top_module(
input [3:0] in,
output out_and,
output out_or,
output out_xor
);
assign out_and = in[0]&in[1]&in[2]&in[3];
assign out_or = in[0]|in[1]|in[2]|in[3];
assign out_xor = in[0]^in[1]^in[2]^in[3];
endmodule
知识点:拼接符({})
module top_module (
input [4:0] a, b, c, d, e, f,
output [7:0] w, x, y, z );//
assign w = {a[4:0],b[4:2]};
assign x = {b[1:0],c[4:0],d[4]};
assign y = {d[3:0],e[4:1]};
assign z = {e[0],f[4:0],1'b1,1'b1};
// assign { ... } = { ... };
endmodule
法一:用拼接符来做
module top_module(
input [7:0] in,
output [7:0] out
);
assign out = {in[0],in[1],in[2],in[3],in[4],in[5],in[6],in[7]};
endmodule
法二:引入循环
module top_module(
input [7:0] in,
output [7:0] out
);
integer i;
always @(*) begin
for (i=0; i<8; i = i + 1) // int is a SystemVerilog type. Use integer for pure Verilog.
out[i] = in[8-i-1];
end
endmodule
法三:通过generate-for循环来实现。
module top_module(
input [7:0] in,
output [7:0] out
);
generate
genvar i;
for (i=0; i<8; i = i+1) begin: my_block_name
assign out[i] = in[8-i-1];
end
endgenerate
endmodule
知识点:复制运算符。特点,两个花括号,不同于拼接符的一个花括号。(初学的时候容易犯错)
{num{vector}}
{5{1'b1}} // 等价于:5'b11111
{2{a,b,c}} // 等价于:{a,b,c,a,b,c}
{3'd5, {2{3'd6}}} // 等价于:9'b101_110_110(这前面是d,代表10进制)
module top_module (
input [7:0] in,
output [31:0] out );//
assign out = {{24{in[7]}},in};
// assign out = { replicate-sign-bit , the-input };
endmodule
知识点补充:a~^b等价于~a^b
module top_module (
input a, b, c, d, e,
output [24:0] out
);
wire [24:0] top, bottom;
assign top = { {5{a}}, {5{b}}, {5{c}}, {5{d}}, {5{e}} };
assign bottom = {5{a,b,c,d,e}};
assign out = ~top ^ bottom; // Bitwise XNOR
// This could be done on one line:
// assign out = ~{ {5{a}}, {5{b}}, {5{c}}, {5{d}}, {5{e}} } ^ {5{a,b,c,d,e}};
endmodule
知识点:模块的调用有两种方式:1、按位置连接。2、按名字连接。
这里介绍下按名字连接:
example : mod_a instance2 ( .out(wc), .in1(wa), .in2(wb) );
mod_a:你要调用模块的名字
instance2:实例化的名字
out、in1、in2:mod_a定义时候的输入与输出
wc、wa、wb:当前模块的输入与输出
module top_module ( input a, input b, output out );
mod_a instance1 (
.in1(a),
.in2(b),
.out(out) );
endmodule
当前一个叫top_module 的模块要取调用之前定义好的模块mod_a ,调用的时候给它取了个别名instance1 ,将信号按照与原理图接入到实例化的instance1中去。其实这个形式很像c++中的struct。
知识点:按位置连接,实例化模块的输入与输出必须与原函数完全相同
优点:按名称将信号连接到模块的端口可以使电线保持正确连接,即使端口列表发生更改。
缺点:通用性和可读性都比较差。
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a example1(out1,out2,a,b,c,d);
endmodule
知识点:按名字连接,已经在2.3.1进行了详细描述,这里不再过多叙述。
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a u0(
.out1(out1),
.out2(out2),
.in1(a),
.in2(b),
.in3(c),
.in4(d)
);
endmodule
module top_module ( input clk, input d, output q );
wire w1, w2;
my_dff u0(
.clk(clk),
.d(d),
.q(w1));
my_dff u1(
.clk(clk),
.d(w1),
.q(w2));
my_dff u2(
.clk(clk),
.d(w2),
.q(q));
endmodule
module top_module (
input clk,
input [7:0] d,
input [1:0] sel,
output [7:0] q
);
wire [7:0] w1,w2,w3;
my_dff8 u0(clk,d,w1);
my_dff8 u1(clk,w1,w2);
my_dff8 u2(clk,w2,w3);
always @(*) begin
case(sel) // if-else is ok.
2'b00: q = d;
2'b01: q = w1;
2'b10: q = w2;
2'b11: q = w3;
endcase
end
endmodule
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [15:0] sum1, sum2;
wire cout1,cout2;
add16 u0(a[15:0],b[15:0], 0, sum1,cout1);
add16 u1(a[31:16],b[31:16],cout1 ,sum2,cout2);
assign sum = {sum2,sum1};
endmodule
知识点:
两个n位的a与b相加,必须用n+1位的sum来保存他们相加的结果,因为你要考虑他们进位的情况。具体见下面add1 模块。
module top_module (
input [31:0] a,
input [31:0] b,
output [31:0] sum
);//
wire [15:0] sum1, sum2;
wire cout1,cout2;
add16 u0(a[15:0],b[15:0], 0, sum1,cout1);
add16 u1(a[31:16],b[31:16],cout1 ,sum2,cout2);
assign sum = {sum2,sum1};
endmodule
module add1 ( input a, input b, input cin, output sum, output cout );
wire [1:0] w1;
assign w1 = a + b + cin;
assign sum = w1[0];
assign cout = w1[1];
endmodule
知识点:电路图的设计思路很值得借鉴,为了防止延迟直接把两种情况提前开始做。
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [15:0] sum0,sum1,sum2,sum3;
wire cout0,cout1,cout2;
add16 u0(a[15:0],b[15:0],0,sum0,cout0);
add16 u1(a[31:16],b[31:16],0,sum1,cout1);
add16 u2(a[31:16],b[31:16],1,sum2,cout2);
always @(*) begin
case(cout0)
1'b0:sum3 = sum1;
1'b1:sum3 = sum2;
endcase
end
assign sum = {sum3,sum0};
endmodule
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] sum
);
wire [31:0] w1; //异或门的输出
wire [15:0] sum1,sum2; // 加法器的输出
wire cout1,cout2; // 进位标志
assign w1 = b^{32{sub}};
add16 u0(a[15:0],w1[15:0],sub,sum1,cout1);
add16 u1(a[31:16],w1[31:16],cout1,sum2,cout2);
assign sum = {sum2,sum1};
endmodule
知识点:always块
组合电路:always @(*),他类似于assign赋值,只是它的块内可以实现多个信号同时赋值。最重要的是,块内部的表达可以很丰富,比如包含if-else,case等。
注意:always内部赋值必须是reg型,如果是wire型会报错
always @(*) begin assign out1 = in1;
out1 = in1; 等价于 assign out2 = in2;
out2 = in2; ...
...
end
(out1、out2是reg型)
时钟电路: always @(posedge clk)
(*):只要信号有变化就执行。
posedge:clk的上升沿
negedge:clk的下降沿
// 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 @(*) begin
out_alwaysblock = a&b;
end
endmodule
知识点:阻塞赋值与非阻塞赋值
// 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 @(*) begin
out_always_comb = a^b;
end
always @(posedge clk) begin
out_always_ff <= a^b;
end
endmodule
知识点:if-else与三目运算符
// 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 == 1)&&(sel_b2 == 1)) ? b : a;
always @(*) begin
if((sel_b1 == 1)&&(sel_b2 == 1))
out_always = b;
else
out_always = a;
end
endmodule
知识点:如何避免电路生成锁存器
解决办法:组合电路必须在所有条件下为所有输出赋值,即考虑所有情况。第二种方法见2.4.7,如果不考虑所有情况该怎么办。
// 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;
else
shut_off_computer = 0;
end
always @(*) begin
if (~arrived)
keep_driving = ~gas_tank_empty;
else
keep_driving = 0;
end
endmodule
知识点:case,类似于c语言中的switch-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;
default:out = 4'b0000;
endcase
end
endmodule
知识点:case、casez、casex
法一:把每种情况考虑到,不想写,麻烦
法二:合理利用casex
// synthesis verilog_input_version verilog_2001
module top_module (
input [3:0] in,
output reg [1:0] pos );
always @(*) begin
casex(in)
4'bxxx1 : pos = 2'b00;
4'bxx10 : pos = 2'b01;
4'bx100 : pos = 2'b10;
4'b1xxx : pos = 2'b11;
default : pos = 2'b00;
endcase
end
endmodule
知识点:case,casez,casex。
// synthesis verilog_input_version verilog_2001
module top_module (
input [7:0] in,
output reg [2:0] pos );
always @(*) begin
casez(in)
8'bzzzzzzz1:pos = 4'b000;
8'bzzzzzz10:pos = 4'b001;
8'bzzzzz100:pos = 4'b010;
8'bzzzz1000:pos = 4'b011;
8'bzzz10000:pos = 4'b100;
8'bzz100000:pos = 4'b101;
8'bz1000000:pos = 4'b110;
8'b10000000:pos = 4'b111;
default:pos = 4'b000;
endcase
end
endmodule
知识点:如何避免锁存器的生成。
在进入always快的时候为所有输出赋值。
// synthesis verilog_input_version verilog_2001
module top_module (
input [15:0] scancode,
output reg left,
output reg down,
output reg right,
output reg up );
always @(*) begin
up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0;
case(scancode)
16'he06b:left=1;
16'he072:down=1;
16'he074:right=1;
16'he075:up=1;
endcase
end
endmodule
知识点:三目运算符(和c语言中的规则一模一样)
condition ? if_true : if_false;
module top_module (
input [7:0] a, b, c, d,
output [7:0] min);//
wire [7:0] w1 ,w2;
assign w1 = a <= b ? a :b;
assign w2 = c <= d ? c :d;
assign min = w1 <= w2 ? w1 : w2;
// assign intermediate_result1 = compare? true: false;
endmodule
知识点:
1、2.1.3已经介绍了位运算作用于两个对象。现在介绍它的第二种用法,对一个对象中的每个位进行位运算——缩减运算符。
example:
& a[3:0] // 等价于:a[3]&a[2]&a[1]&a[0]. | b[3:0] // 等级于: b[3]|b[2]|b[1]|b[0]. ^ c[2:0] // 等价于: c[2]^c[1]^c[0]
2、信号的奇偶校验可以运用位运算符 ^ 。
module top_module (
input [7:0] in,
output parity);
assign parity = ^in;
endmodule
module top_module(
input [99:0] in,
output out_and,
output out_or,
output out_xor
);
assign out_and = ∈
assign out_or = |in;
assign out_xor = ^in;
endmodule
知识点:$bits(out)能输出out这个vector的大小。——类似c++中,vector.size()。可以在2.5.5中应用一下。
module top_module(
input [99:0] in,
output [99:0] out
);
always@(*) begin
for(integer i = 0;i<100;i = i + 1)
out[i] = in[99 - i];
end
endmodule
易错点:你要对一个对象进行算数运算的时候必须要给他赋初值。比如下面你如果丢掉(out = 0;)就会出错。
module top_module(
input [254:0] in,
output [7:0] out );
always @(*) begin
out = 0;
for(int i = 0;i<$bits(in);i = i + 1)
out = out + in[i];
end
endmodule
知识点:
1、全加器的实现
法一:
s = a1^a2^cin
cout = a1&a2 | a1&cin | a2&cin
法二:
module top_module(
input a, b, cin,
output cout, sum );
wire [1:0] w1;
assign w1 = a + b + cin;
assign sum = w1[0];
assign cout = w1[1];
endmodule
法一优于法二,法一就不用单独设置一个wire类型的数据来保存相加结果。
2、生成块(generate-endgenerate)——摘自《数字系统设计教程(第3版)》,夏宇闻
a、应用场景:
b、生成实例的内容可以是以下的一个或多个类型:
c、3种创建生成语句的方法
题解:
法一:always块
module top_module(
input [99:0] a, b,
input cin,
output [99:0] cout,
output [99:0] sum );
//---------------initial----------------
assign sum[0] = a[0]^b[0]^cin;
assign cout[0] = a[0]&b[0] | a[0]&cin | b[0]&cin;
//---------------for loop---------------
always @(*)begin
for(integer i = 1;i<100;i++)begin
sum[i] = a[i]^b[i]^cout[i-1];
cout[i] = a[i]&b[i] | a[i]&cout[i-1] | b[i]&cout[i-1];
end
end
endmodule
法二:运用生成语句——没写出来QAQ
不知道错在哪里
module top_module(
input [99:0] a, b,
input cin,
output [99:0] cout,
output [99:0] sum );
assign cout[0] = cin;
genvar i;
generate for( i = 1 ; i < 100 ; i = i + 1) begin : r_loop
always @(*) sum[i-1] = a[i-1]^b[i-1]^cout[i-1];
always @(*) cout[i] = a[i-1]&b[i-1] | a[i-1]&cout[i-1] | b[i-1]&cout[i-1];
end
endgenerate
endmodule
知识点:生成块(generate-endgenerate),详情见题2.5.6
module top_module(
input [399:0] a, b,
input cin,
output cout,
output [399:0] sum );
reg [100:0] cin_mid;
assign cin_mid[0] = cin;
genvar i;
generate for(i = 1 ; i <= 100 ; i++) begin : r_loop
bcd_fadd tt(
a[4 * i -1 : 4 * (i - 1)],
b[4 * i -1 : 4 * (i - 1)],
cin_mid[i - 1],
cin_mid[i],
sum[4 * i -1 : 4 * (i - 1)]
);
end
endgenerate
assign cout = cin_mid[100];
endmodule
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
知识点:知道关键字(nor)的使用
法一:使用关键词nor
module top_module (
input in1,
input in2,
output out);
nor(out , in1,in2);
endmodule
法二:使用位运算符
module top_module (
input in1,
input in2,
output out);
assign out = ~(in1|in2);
endmodule
4、Another
module top_module (
input in1,
input in2,
output out);
assign out = in1&~in2;
endmodule
5、Two gates
知识点:
关键字:xnor与关键字xor
法一:用关键字
module top_module (
input in1,
input in2,
input in3,
output out);
wire w1;
xnor(w1 , in1, in2);
xor(out ,w1,in3);
endmodule
法二:位运算
module top_module (
input in1,
input in2,
input in3,
output out);
wire w1;
assign w1 = ~in1^in2;
assign out = w1^in3;
endmodule
5、More logic gates
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
);
and(out_and , a, b);
or(out_or, a, b);
xor(out_xor ,a ,b);
nand(out_nand,a,b);
nor(out_nor,a,b);
xnor(out_xnor,a,b);
assign out_anotb = a&~b;
endmodule
6、7420 chip
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
7、Truth tables
知识点:真值表
module top_module(
input x3,
input x2,
input x1, // three inputs
output f // one output
);
assign f = ~x3&x2|x1&x2|x3&x1;
endmodule
8、Two-bit equality
法一:
module top_module ( input [1:0] A, input [1:0] B, output z );
always @(*) begin
if(A == B) z = 1;
else z = 0;
end
endmodule
法二:
module top_module(
input [1:0] A,
input [1:0] B,
output z);
assign z = (A[1:0]==B[1:0]);
endmodule
9、Simple circuit A
module top_module (input x, input y, output z);
assign z = x^y&x;
endmodule
10、Simple circuit B
module top_module ( input x, input y, output z );
assign z = ~x^y;
endmodule
11、Combine circuits A and B
知识点:模块的调用
module top_module (input x, input y, output z);
wire w1,w2,w3,w4;
A_block u0(x,y,w1);
B_block u1(x,y,w2);
assign w3 = w1 | w2;
assign w4 = w1 & w2;
assign z = w3^w4;
endmodule
module A_block (input x, input y, output z);
assign z = x^y&x;
endmodule
module B_block ( input x, input y, output z );
assign z = ~x^y;
endmodule
12、Ring or bibrate
知识点:画卡诺图,然后用verilog将其实现
ring |
vibrate_mode |
vibrate_mode |
vibrate_mode |
0 | 0 | 0 | 0 |
0 | 1 | 0 | 0 |
1 | 1 | 0 | 1 |
1 | 0 | 1 | 0 |
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
13、Thermostat
module top_module (
input too_cold,
input too_hot,
input mode,
input fan_on,
output heater,
output aircon,
output fan
);
assign heater = mode&too_cold;
assign aircon = ~mode&too_hot;
assign fan = heater|aircon|fan_on;
endmodule
14、3-bit population count
法一:从卡诺图出发来写
module top_module(
input [2:0] in,
output [1:0] out );
assign out[1] = in[2]&in[1]|in[1]&in[0]|in[2]&in[0];
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];
endmodule
法二:用case把每种情况都考虑到
注意:做比较运算时候,verilog会将不同进制转换到同一进制下进行比较。
module top_module (
input [2:0] in,
output [1:0] out
);
always @(*) begin
case (in)
3'd0: out = 2'd0;
3'd1: out = 2'd1;
3'd2: out = 2'd1;
3'd3: out = 2'd2;
3'd4: out = 2'd1;
3'd5: out = 2'd2;
3'd6: out = 2'd2;
3'd7: out = 2'd3;
endcase
end
endmodule
15、Gates and vectors
知识点:错位比较
module top_module(
input [3:0] in,
output [2:0] out_both,
output [3:1] out_any,
output [3:0] out_different );
assign out_both = in[2:0]&in[3:1];
assign out_any = in[2:0]|in[3:1];
assign out_different = in^{in[0],in[3:1]};
endmodule
16、Even longer vectors
module top_module(
input [99:0] in,
output [98:0] out_both,
output [99:1] out_any,
output [99:0] out_different );
assign out_both = in[98:0]&in[99:1];
assign out_any = in[98:0]|in[99:1];
assign out_different = in^{in[0],in[99:1]};
endmodule
1、2-to-1 multiplexers
module top_module(
input a, b, sel,
output out );
assign out = sel? a : b;
endmodule
2、2-to-1 bus multiplexers
module top_module(
input [99:0] a, b,
input sel,
output [99:0] out );
assign out = sel? a : b;
endmodule
3、9-to-1 multiplexer
我的解法
module top_module(
input [15:0] a, b, c, d, e, f, g, h, i,
input [3:0] sel,
output [15:0] out );
always @(*) begin
case(sel)
4'd0:out = a;
4'd1:out = b;
4'd2:out = c;
4'd3:out = d;
4'd4:out = e;
4'd5:out = f;
4'd6:out = g;
4'd7:out = h;
4'd8:out = i;
default:out = {16{1'b1}};
endcase
end
endmodule
标准答案:
知识点:
'1是一种特殊的语法,他能将vector所有的位设为1的数字,[n:0]a = 'b。'0, 'x, 和'z 也是一样的
module top_module(
input [15:0] a, b, c, d, e, f, g, h, i,
input [3:0] sel,
output [15:0] out );
always @(*) begin
out = '1;
case (sel)
4'h0: out = a;
4'h1: out = b;
4'h2: out = c;
4'h3: out = d;
4'h4: out = e;
4'h5: out = f;
4'h6: out = g;
4'h7: out = h;
4'h8: out = i;
endcase
end
endmodule
4、256-to-1 multiplexer
module top_module(
input [255:0] in,
input [7:0] sel,
output out );
assign out = in[sel];
endmodule
知识点:
假设有一个向量A与向量a,与常量n与m:
A[a]是合法表达,此时允许a是一个变动的向量。
A[n:m]是合法表达的,此时n与m是不能为向量的,只能为常量,是一个确定的值,否则会报错。
A[4*(a+1):4*a]是非法表达,因为冒号:两边必须是常量
法一:
module top_module (
input [1023:0] in,
input [7:0] sel,
output [3:0] out
);
assign out = {in[sel*4+3], in[sel*4+2], in[sel*4+1], in[sel*4+0]};
endmodule
法二:
知识点:
assign out = in[sel*4 +: 4];
含义,选择从索引“sel*4”开始,然后选择总宽度为4位的索引号递增(+:)。
assign out = in[sel*4+3 -: 4];
含义,选择从索引“sel*4+3”开始,然后选择总宽度为4位的索引号递减(-:)。
注意:注意:宽度(本例中为4)必须是常量。
module top_module(
input [1023:0] in,
input [7:0] sel,
output [3:0] out );
assign out = in[sel*4+:4];
endmodule
1、Half adder
a | b | cout | sum |
0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 |
1 | 0 | 0 | 1 |
1 | 1 | 1 | 0 |
module top_module(
input a, b,
output cout, sum );
assign cout = a & b;
assign sum = a&~b|~a&b;
endmodule
2、Full adder
法一:
module top_module(
input a, b, cin,
output cout, sum );
assign cout = a&b|a&cin|b&cin;
assign sum = a^b^cin;
endmodule
法二:
module top_module(
input a, b, cin,
output cout, sum );
wire [1:0] w1;
assign w1 = a + b + cin;
assign sum = w1[0];
assign cout = w1[1];
endmodule
//也可以这样
module top_module(
input a, b, cin,
output cout, sum );
wire [1:0] w1;
assign {cout , sum} = a + b + cin;
endmodule
3、3-bit binary adder⭐
法一:生成循环块(generate -endgenerate )
知识点:后面cout将不会在给出,如(4-digital BCD adder这个题目)。你要自己创建一个容器来保存进位。
module top_module(
input [2:0] a, b,
input cin,
output [2:0] cout,
output [2:0] sum );
full_adder u0(a[0],b[0],cin,cout[0],sum[0]);
genvar i;
generate for(i = 1 ; i < $bits(sum) ; i++) begin:r_loop
full_adder u1(a[i],b[i],cout[i-1] ,cout[i] ,sum[i]);
end
endgenerate
endmodule
module full_adder(
input a, b, cin,
output cout, sum );
assign cout = a&b|a&cin|b&cin;
assign sum = a^b^cin;
endmodule
4、Adder
知识点:两个n位的无符号数相加必须用n+1的容器来存储他们的相加结果。
module top_module (
input [3:0] x,
input [3:0] y,
output [4:0] sum);
assign sum = x + y;
endmodule
5、Signed addition overflow⭐
知识点:二进制补码的计算
module top_module (
input [7:0] a,
input [7:0] b,
output [7:0] s,
output overflow
);
assign s=a + b;
assign overflow=a[7] & b[7] & ~s[7] | ~a[7] & ~b[7] & s[7];
endmodule
6、100-bit binary adder
module top_module(
input [99:0] a, b,
input cin,
output cout,
output [99:0] sum );
assign {cout, sum} = a + b + cin;
endmodule
7、4-digital BCD adder⭐
module top_module(
input [15:0] a, b,
input cin,
output cout,
output [15:0] sum );
wire [3:0] temp_cout;
bcd_fadd u0(a[3:0] , b[3:0] , cin, temp_cout[0], sum[3:0]);
genvar i;
generate for( i = 1 ; i < 4 ; i++) begin:r_loop
bcd_fadd u1(a[i*4+:4],b[i*4+:4],temp_cout[i-1],temp_cout[i],sum[i*4+:4]);
end
endgenerate
assign cout = temp_cout[3];
endmodule
知识点:
1、3-variable
module top_module(
input a,
input b,
input c,
output out );
assign out = a|b|c;
endmodule
2、4-variable
module top_module(
input a,
input b,
input c,
input d,
output out );
assign out = ~c&~b|~d&~a|c&d&a|c&d&b;
endmodule
3、4-variable
知识点:m代表1,d代表无关项x
module top_module(
input a,
input b,
input c,
input d,
output out );
assign out = a|c&~b;
endmodule
4、4-variable
module top_module(
input a,
input b,
input c,
input d,
output out );
assign out = a^b^c^d;
endmodule
5、Minimum SOP and POS
sop:sum of product 积之和 即化成最小项的形式,对应于卡诺图就是圈1即可 pos:product of sum 和之积 即化成最大项的形式,对应于卡诺图就是圈0后,整体取反
6、Karnuagh map
module top_module (
input [4:1] x,
output f );
assign f = x[3]&~x[1]|x[4]&x[2];
endmodule
7、Karnuagh map
module top_module (
input [4:1] x,
output f
);
assign f = x[3]&~x[1]|x[3]&x[4]&x[2]|~x[4]&x[1]&~x[2]|~x[3]&~x[4]&~x[2];
endmodule
8、K-MAP implemented witj a multiplexer ⭐、
没看懂什么意思...
module top_module (
input c,
input d,
output [3:0] mux_in
);
// After knowing how to split the truth table into four columns,
// the rest of this question involves implementing logic functions
// using only multiplexers (no other gates).
// I will use the conditional operator for each 2-to-1 mux: (s ? a : b)
assign mux_in[0] = (c ? 1 : (d ? 1 : 0)); // 2 muxes: c|d
assign mux_in[1] = 0; // No muxes: 0
assign mux_in[2] = d ? 0 : 1; // 1 mux: ~d
assign mux_in[3] = c ? (d ? 1 : 0) : 0; // 2 muxes: c&d
endmodule
1、D flip-flop
知识点:D触发器(上升沿)
module top_module (
input clk, // Clocks are used in sequential circuits
input d,
output reg q );//
always @(posedge clk) begin
q <= d;
end
// Use a clocked always block
// copy d to q at every positive edge of clk
// Clocked always blocks should use non-blocking assignments
endmodule
2、D flip-flops
module top_module (
input clk,
input [7:0] d,
output [7:0] q
);
always @(posedge clk) begin
q <= d;
end
endmodule
3、DFF with reset
知识点:同步复位,复位信只有在时钟上升沿到来时才有效。参考链接
module top_module (
input clk,
input reset, // Synchronous reset
input [7:0] d,
output [7:0] q
);
always @(posedge clk) begin
if(reset)
q <= '0;
else
q<=d;
end
endmodule
4、DFF with reset value
module top_module (
input clk,
input reset,
input [7:0] d,
output [7:0] q
);
always @(negedge clk) begin
if(reset)
q <= 8'h34;
else
q <= d;
end
endmodule
5、 DFF with asynchronous reset
知识点:异步寄存器
module top_module (
input clk,
input areset, // active high asynchronous reset
input [7:0] d,
output [7:0] q
);
always @(posedge clk , posedge areset) begin
if(areset)
q <= '0;
else
q <= d;
end
endmodule
6、DFF with byte enable
module top_module (
input clk,
input resetn,
input [1:0] byteena,
input [15:0] d,
output [15:0] q
);
always @(posedge clk) begin
if(~resetn)
q = '0;
else if(byteena == 2'b01)
q[7:0] <= d[7:0];
else if(byteena == 2'b10)
q[15:8] <= d[15:8];
else if(byteena == 2'b11)
q <= d;
end
endmodule
7、D latch
知识点:锁存器的实现(要点:考虑问题不周全就会出现锁存器,如if 没有else case没有default)
module top_module (
input d,
input ena,
output q);
always @(ena) begin
if(ena) q <= d;
end
endmodule
8、DFF
知识点:三角型代表上升沿
module top_module (
input clk,
input d,
input ar, // asynchronous reset
output q);
always @(posedge clk, posedge ar) begin
if(ar) q <= 1'b0;
else q <= d;
end
endmodule
9、DFF
module top_module (
input clk,
input d,
input r, // synchronous reset
output q);
always @(posedge clk) begin
if(r) q <= 1'b0;
else q <= d;
end
endmodule
10、DFF+gate
module top_module (
input clk,
input in,
output out);
always @(posedge clk) begin
out <= in^out;
end
endmodule
11、Mux and DFF
module top_module (
input clk,
input L,
input r_in,
input q_in,
output reg Q);
always @(posedge clk) begin
Q <= r_in&L|q_in&~L;
end
endmodule
12、Mux and DFF
module top_module (
input clk,
input w, R, E, L,
output Q
);
always @(posedge clk) begin
Q <= (w&E|Q&~E)&~L|R&L;
end
endmodule
13、DFFs and gates⭐
错误解答:z是组合逻辑,而不是时序逻辑。所以他不能放在always语句中
module top_module (
input clk,
input x,
output z
);
reg q1,q2,q3;
always @(posedge clk) begin
q1 <= x^q1;
q2 <= x&~q2;
q3 <= x|~q3;
z = ~(q1|q2|q3);
end
endmodule
正确解答
法一:
module top_module (
input clk,
input x,
output z
);
reg q1,q2,q3;
always @(posedge clk) begin
q1 <= x^q1;
q2 <= x&~q2;
q3 <= x|~q3;
end
assign z = ~(q1|q2|q3);
endmodule
法二:
module top_module (
input clk,
input x,
output z
);
reg q1,q2,q3;
D_flip_flops u0(clk,x^q1,q1);
D_flip_flops u1(clk,x&~q2,q2);
D_flip_flops u2(clk,x|~q3,q3);
assign z = ~(q1|q2|q3);
endmodule
module D_flip_flops (
input clk,
input d,
output q
);
always @(posedge clk) begin
q <= d;
end
endmodule
14、Create circuit from truth table
知识点:JK触发器
法一:利用if -else来做
module top_module (
input clk,
input j,
input k,
output Q);
always @(posedge clk) begin
if(j == 0 && k==1)
Q <= 0;
else if (j == 1 && k==0)
Q <= 1;
else if (j == 1 && k==1)
Q <= ~Q;
end
endmodule
法二:利用case-endcase
module top_module (
input clk,
input j,
input k,
output Q);
always @(posedge clk) begin
case({j,k})
2'b01:Q <= 0;
2'b10:Q <= 1;
2'b11:Q <= ~Q;
endcase
end
endmodule
15、Detect an edge⭐
知识点:边沿检测器
in = 0 | in = 1 | |
reg_in = 0 | 0 | 1 |
reg_in = 1 | 0 | 0 |
module top_module (
input clk,
input [7:0] in,
output [7:0] pedge
);
reg [7:0] reg_in;
always @(posedge clk) begin
reg_in <= in; // Remember the state of the previous cycle
pedge <= ~reg_in∈ // A positive edge occurred if input was 0 and is now 1.
end
endmodule
16、Detecg botj edges⭐
in = 0 | in = 1 | |
reg_in = 0 | 0 | 1 |
reg_in = 1 | 1 | 0 |
module top_module (
input clk,
input [7:0] in,
output [7:0] anyedge
);
reg [7:0] reg_in;
always @(posedge clk) begin
reg_in <= in;
anyedge <= ~reg_in&in|reg_in&~in;
end
endmodule
17、Edge capture register
in=0 | in=1 | |
out'=0 reg=0 | 0 | 0 |
out'=0 reg=1 | 1 | 0 |
out'=1 reg=1 | 1 | 1 |
out'=1 reg=0 | 1 | 1 |
module top_module (
input clk,
input reset,
input [31:0] in,
output [31:0] out
);
reg [31:0] reg_in;
always @(posedge clk) begin
reg_in <= in;
if(reset) out <= '0;
else out <= out|reg_in&~in;
end
endmodule
18、Dual-edge triggered flip-flop ⭐
知识点:双边触发器
非法表达一:
always @(posedge clk,negedge clk)是一种非法的表达
非法表达二:
always @(posedge clk) begin
q <= d;
end
always @(negedge clk) begin
q <= d;
end
报错:
解答:
module top_module (
input clk,
input d,
output q
);
reg q1,q2;
always @(posedge clk) begin
q1 <= d^q2;
end
always @(negedge clk) begin
q2 <= d^q1;
end
assign q = q1^q2;
endmodule
// After posedge clk, p changes to d^n. Thus q = (p^n) = (d^n^n) = d.
// After negedge clk, n changes to p^n. Thus q = (p^n) = (p^p^n) = d.
1、Four-bit binary counter⭐
知识点:verilog中的加法,4'b1111 + 1 = 4'b0000
我:
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:0] q);
always @(posedge clk) begin
if(reset) q <= '0;
else begin
if(q == 4'b1111) q <= 4'b0000;
else q <= q + 1'b1;
end
end
endmodule
参考答案:
module top_module(
input clk,
input reset,
output reg [3:0] q);
always @(posedge clk)
if (reset)
q <= 0;
else
q <= q+1; // Because q is 4 bits, it rolls over from 15 -> 0.
// If you want a counter that counts a range different from 0 to (2^n)-1,
// then you need to add another rule to reset q to 0 when roll-over should occur.
endmodule
2、Decade counter
我:
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:0] q);
always @(posedge clk) begin
if(reset) q <= '0;
else begin
if(q == 4'b1001) q <= 4'b0000;
else q <= q + 1'b1;
end
end
endmodule
参考答案:
module top_module(
input clk,
input reset,
output reg [3:0] q);
always @(posedge clk)
if (reset || q == 9) // Count to 10 requires rolling over 9->0 instead of the more natural 15->0
q <= 0;
else
q <= q+1;
endmodule
3、Decade counter again
module top_module (
input clk,
input reset,
output [3:0] q);
always @(posedge clk) begin
if(reset || q == 4'b1010)
q<=4'b0001;
else
q<=q+1;
end
endmodule
4、Slow decade counter⭐
module top_module (
input clk,
input slowena,
input reset,
output [3:0] q);
always @(posedge clk)begin
if(reset == 1)
q <= 0;
else if(slowena == 1)begin
if(q==9) q <= 0;
else q <= q + 1;
end
end
endmodule
5、Counter 1-12⭐
知识点:
module top_module (
input clk,
input reset,
input enable,
output [3:0] Q,
output c_enable,
output c_load,
output [3:0] c_d
); //
assign c_enable = enable;
assign c_load = reset| ((Q == 4'd12) && enable == 1'b1);
assign c_d = c_load ? 4'd1 : 4'd0;
count4 the_counter (clk, c_enable, c_load, c_d,Q/*, ... */ );
endmodule
6、Counter 1000⭐
知识点:q0 == 4'd9 在比较的时候会将4'd9转换为一个四位的二进制数。
module top_module (
input clk,
input reset,
output OneHertz,
output [2:0] c_enable
); //
reg [3:0] q0,q1,q2;
assign c_enable = {q0 == 4'd9 && q1 == 4'd9,q0 == 4'd9,1'b1};
assign OneHertz = (q0 == 4'd9 && q1 == 4'd9 && q2 == 4'd9);
bcdcount counter0 (clk, reset, c_enable[0],q0/*, ... */);
bcdcount counter1 (clk, reset, c_enable[1],q1/*, ... */);
bcdcount counter3 (clk, reset, c_enable[2],q2/*, ... */);
endmodule
7、4-digit decimal counter⭐
知识点:由单个bcd计数器构成更大的(1000)计数器
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:1] ena,
output [15:0] q);
assign ena = {q[11:8]==4'd9&&q[7:4]==4'd9&&q[3:0]==4'd9,q[7:4]==4'd9&&q[3:0]==4'd9,q[3:0]==4'd9};
bcd u0(clk,reset,1'b1,q[3:0]);
bcd u1(clk,reset,ena[1],q[7:4]);
bcd u2(clk,reset,ena[2],q[11:8]);
bcd u3(clk,reset,ena[3],q[15:12]);
endmodule
module bcd(
input clk,
input reset,
input enable,
output reg [3:0] q
);
always @(posedge clk) begin
if(reset) q<='0;
else if(enable) begin
if(q == 4'd9) q<='0;
else q <= q+1;
end
end
endmodule
8、12-hour clock
(不会写)
1、4-bit shift register
知识点:
module top_module(
input clk,
input areset, // async active-high reset to zero
input load,
input ena,
input [3:0] data,
output reg [3:0] q);
always @(posedge clk,posedge areset) begin
if(areset) q <= '0;
else
begin
if(load)
q<=data;
else
begin
if(ena) q <= (q>>1);
else q<=q;
end
end
end
endmodule
参考答案:
module top_module(
input clk,
input areset,
input load,
input ena,
input [3:0] data,
output reg [3:0] q);
// Asynchronous reset: Notice the sensitivity list.
// The shift register has four modes:
// reset
// load
// enable shift
// idle -- preserve q (i.e., DFFs)
always @(posedge clk, posedge areset) begin
if (areset) // reset
q <= 0;
else if (load) // load
q <= data;
else if (ena) // shift is enabled
q <= q[3:1]; // Use vector part select to express a shift.
end
endmodule
2、Left/right rotator
我:
module top_module(
input clk,
input load,
input [1:0] ena,
input [99:0] data,
output reg [99:0] q);
always @(posedge clk) begin
if(load) q<=data;
else
begin
case(ena)
2'b01:q = {q[0],q[99:1]};
2'b10:q = {q[98:0],q[99]};
endcase
end
end
endmodule
参考答案:
module top_module(
input clk,
input load,
input [1:0] ena,
input [99:0] data,
output reg [99:0] q);
// This rotator has 4 modes:
// load
// rotate left
// rotate right
// do nothing
// I used vector part-select and concatenation to express a rotation.
// Edge-sensitive always block: Use non-blocking assignments.
always @(posedge clk) begin
if (load) // Load
q <= data;
else if (ena == 2'h1) // Rotate right
q <= {q[0], q[99:1]};
else if (ena == 2'h2) // Rotate left
q <= {q[98:0], q[99]};
end
endmodule
3、Left/right arithmetic shift by 1 or 8
知识点:算数左移动与算数右移
module top_module(
input clk,
input load,
input ena,
input [1:0] amount,
input [63:0] data,
output reg [63:0] q);
always @(posedge clk) begin
if(load) q<=data;
else begin
if(ena) begin
case(amount)
2'b00:q<={q[62:0],1'd0};
2'b01:q<={q[55:0],8'd0};
2'b10:q<={q[63],q[63:1]};
2'b11:q<={{8{q[63]}},q[63:8]};
endcase
end
end
end
endmodule
4、5-bits LFSR
法一:
module top_module(
input clk,
input reset, // Active-high synchronous reset to 5'h1
output [4:0] q
);
always @(posedge clk) begin
if(reset) q<=5'h1;
else begin
q[4] <= q[0]^0;
q[3] <= q[4];
q[2] <= q[3]^q[0];
q[1] <= q[2];
q[0] <= q[1];
end
end
endmodule
法二:
module top_module(
input clk,
input reset, // Active-high synchronous reset to 5'h1
output [4:0] q
);
wire w1,w2,w3,w4,w5;
always @(posedge clk)
begin
if (reset)
q[0] = 1'b1;
else
q[0] = q[1];
end
D_flip ins2(q[2], q[1], clk, reset);
D_flip ins3(q[0]^q[3], q[2], clk,reset);
D_flip ins4(q[4], q[3], clk, reset);
D_flip ins5(0^q[0], q[4], clk, reset);
endmodule
module D_flip(input D, output Q, input clk, input reset);
always @(posedge clk)
begin
if(reset)
Q <= 1'b0;
else
Q <= D;
end
endmodule
5、3-bit LFSR⭐
在这里犯了错误,位运算符也是有优先级的。
解答:
module top_module (
input [2:0] SW, // R
input [1:0] KEY, // L and clk
output [2:0] LEDR); // Q
always @(posedge KEY[0]) begin
LEDR[0] <= KEY[1]&SW[0]|~KEY[1]&LEDR[2];
LEDR[1] <= KEY[1]&SW[1]|~KEY[1]&LEDR[0];
LEDR[2] <= KEY[1]&SW[2]|~KEY[1]&(LEDR[1]^LEDR[2]); //如果把这个括号去掉则会报错,大家可以试一试
end
endmodule
6、32-bit LFSR
module top_module(
input clk,
input reset, // Active-high synchronous reset to 32'h1
output [31:0] q
);
always @(posedge clk) begin
if(reset) q<=32'h1;
else begin
q[31]<=q[0];
q[30:22] <= q[31:23];
q[21]<=q[0]^q[22];
q[20:2]<=q[21:3];
q[1]<=q[0]^q[2];
q[0]<=q[0]^q[1];
end
end
endmodule
7、Shift register
法一:
知识点:自定义的模块名字不要与quartus ii自定义的元件名冲突,比如,你将下面代码中的d_f_f改成dff就会报错,我在这里卡了好久。。。
module top_module (
input clk,
input resetn, // synchronous reset
input in,
output out);
reg [3:1] q;
d_f_f u3(.clk(clk),.resetn(resetn),.d(in),.q(q[3]));
d_f_f u2(.clk(clk),.resetn(resetn),.d(q[3]),.q(q[2]));
d_f_f u1(.clk(clk),.resetn(resetn),.d(q[2]),.q(q[1]));
d_f_f u0(.clk(clk),.resetn(resetn),.d(q[1]),.q(out));
endmodule
module d_f_f(
input clk,
input resetn,
input d,
output q
);
always @(posedge clk) begin
if(~resetn) q <= 1'b0;
else q <= d;
end
endmodule
法二:
module top_module (
input clk,
input resetn, // synchronous reset
input in,
output reg out);
reg [2:0] Q;
always @(posedge clk)begin
if(~resetn)begin
{Q,out} <= 4'b0;
end
else begin
Q[2] <= in;
Q[1] <= Q[2];
Q[0] <= Q[1];
out <= Q[0];
end
end
endmodule
8、Shift register
知识点:如果输入和输出是一样的就没必要在定义一个另外的输入了,比如,module MUXDFF 中Q既是输入也是输出。
module top_module (
input [3:0] SW,
input [3:0] KEY,
output [3:0] LEDR
); //
MUXDFF u3(
.clk(KEY[0]),
.w(KEY[3]),
.R(SW[3]),
.E(KEY[1]),
.L(KEY[2]),
.Q(LEDR[3])
);
MUXDFF u2(
.clk(KEY[0]),
.w(LEDR[3]),
.R(SW[2]),
.E(KEY[1]),
.L(KEY[2]),
.Q(LEDR[2])
);
MUXDFF u1(
.clk(KEY[0]),
.w(LEDR[2]),
.R(SW[1]),
.E(KEY[1]),
.L(KEY[2]),
.Q(LEDR[1])
);
MUXDFF u0(
.clk(KEY[0]),
.w(LEDR[1]),
.R(SW[0]),
.E(KEY[1]),
.L(KEY[2]),
.Q(LEDR[0])
);
endmodule
module MUXDFF (
input clk,
input w, R, E, L,
output Q
);
always @(posedge clk) begin
Q <= (w&E|Q&~E)&~L|R&L;
end
endmodule
9、3-input LUT
module top_module (
input clk,
input enable,
input S,
input A, B, C,
output Z );
reg[7:0] Q;
always@(posedge clk) begin
if(enable)
Q <= {Q[6:0],S};
else
Q<=Q;
end
assign Z = Q[{A,B,C}];
endmodule
1、Rule 90
核心:邻居之间异或
module top_module(
input clk,
input load,
input [511:0] data,
output [511:0] q );
always @ (posedge clk)
begin
if (load)
q <= data;
else
begin
q <= q[511:1] ^ {q[510:0], 1'b0} ;
end
end
endmodule
2、Rule 110
module top_module(
input clk,
input load,
input [511:0] data,
output [511:0] q
);
always @(posedge clk) begin
if(load) q<=data;
else q <= (q[511:0]^{q[510:0],1'b0})|{~q[511:1] &{q[510:0],1'b0}};
end
endmodule
3、Conway's Game of Life 16×16
四部曲:
1、Simple FSM 1(asynchronous reset)
module top_module(
input clk,
input areset, // Asynchronous reset to state B
input in,
output out);//
parameter A=0, B=1;
reg state, next_state;
always @(*) begin // This is a combinational always block
// State transition logic
case (state)
A: next_state = in? A:B;
B: next_state = in? B:A;
endcase
end
always @(posedge clk, posedge areset) begin // This is a sequential always block
// State flip-flops with asynchronous reset
if (areset)
state <= B;
else
state <= next_state;
end
// Output logic
// assign out = (state == ...);
assign out = (state == B);
endmodule
2、Simple FSM 1(synchronous reset)
// Note the Verilog-1995 module declaration syntax here:
module top_module(clk, reset, in, out);
input clk;
input reset; // Synchronous reset to state B
input in;
output out;//
reg out;
parameter A=0,B=1;
reg present_state, next_state;
//present_state跟新
always @(posedge clk) begin
if(reset)
present_state <= B;
else
present_state <= next_state;
end
//next_state跟新
always @(*) begin
case(present_state)
A:next_state = (in ? A : B);
B:next_state = (in ? B : A);
endcase
end
// out跟新
assign out = (present_state == B);
endmodule
3、Simple FSM 2(asynchronous reset)
module top_module(
input clk,
input areset, // Asynchronous reset to OFF
input j,
input k,
output out); //
parameter OFF=0, ON=1;
reg state, next_state;
//next_state跟新(与激励有关)
always @(*) begin
case(state)
OFF:next_state = (j?ON:OFF);
ON:next_state = (k?OFF:ON);
endcase
end
//state跟新
always @(posedge clk, posedge areset) begin
if(areset) state<=OFF;
else state <= next_state;
end
//out跟新
assign out = (state == ON);
endmodule
4、Simple FSM 2(synchronous reset)
module top_module(
input clk,
input reset, // Synchronous reset to OFF
input j,
input k,
output out); //
parameter OFF=0, ON=1;
reg state, next_state;
always @(*) begin
case(state)
OFF:next_state <= (j?ON:OFF);
ON:next_state <= (k?OFF:ON);
endcase
end
always @(posedge clk) begin
if(reset) state <= OFF;
else state <= next_state;
end
assign out = (state == ON);
endmodule
5、Simple state transition 3
module top_module(
input in,
input [1:0] state,
output [1:0] next_state,
output out); //
parameter A=0, B=1, C=2, D=3;
always @(*) begin
case(state)
A:next_state <= (in?B:A);
B:next_state <= (in?B:C);
C:next_state <= (in?D:A);
D:next_state <= (in?B:C);
endcase
end
assign out = (state==D);
endmodule
6、Simple one-hot state transitions 3⭐
知识点:观察规律很重要
module top_module(
input in,
input [3:0] state,
output [3:0] next_state,
output out); //
parameter A=0, B=1, C=2, D=3;
// State transition logic: Derive an equation for each state flip-flop.
assign next_state[A] = state[A]&(~in) | state[C]&(~in);
assign next_state[B] = state[A]&(in) | state[B]&in | state[D]∈
assign next_state[C] = state[B]&(~in) | state[D]&(~in);
assign next_state[D] = state[C]∈
// Output logic:
assign out = (state[D] == 1);
endmodule
7、Simple FSM 3(asynchronous reset)
module top_module(
input clk,
input in,
input areset,
output out); //
parameter A=0, B=1, C=2, D=3;
reg [1:0] state , next_state;//只有四种状态2^2=4
// State transition logic
always @(*) begin
case(state)
A:next_state <= (in?B:A);
B:next_state <= (in?B:C);
C:next_state <= (in?D:A);
D:next_state <= (in?B:C);
endcase
end
// State flip-flops with asynchronous reset
always @(posedge clk,posedge areset) begin
if(areset) state <= A;
else state <= next_state;
end
// Output logic
assign out = (state == D);
endmodule
8、Simple FSM 3(synchronous reset)
module top_module(
input clk,
input in,
input reset,
output out); //
parameter A=0, B=1, C=2, D=3;
reg [1:0] state , next_state;
always @(*) begin
case(state)
A:next_state <= (in?B:A);
B:next_state <= (in?B:C);
C:next_state <= (in?D:A);
D:next_state <= (in?B:C);
endcase
end
always @(posedge clk) begin
if(reset) state <= A;
else state <= next_state;
end
assign out = (state == D);
endmodule
9、Design a Moore FSM
module top_module (
input clk,
input reset,
input [3:1] s,
output fr3,
output fr2,
output fr1,
output dfr
);
parameter A = 0,B1= 1, B2= 2 ,C1 = 3,C2 =4 ,D = 5;
reg [2:0] state , nstate;
always @(*) begin
case(state)
A:begin
case(s)
3'b111:nstate=A;
3'b011:nstate=B1;
3'b001:nstate=C1;
3'b000:nstate=D;
endcase
end
B1:begin
case(s)
3'b111:nstate=A;
3'b011:nstate=B1;
3'b001:nstate=C1;
3'b000:nstate=D;
endcase
end
B2:begin
case(s)
3'b111:nstate=A;
3'b011:nstate=B2;
3'b001:nstate=C1;
3'b000:nstate=D;
endcase
end
C1:begin
case(s)
3'b111:nstate=A;
3'b011:nstate=B2;
3'b001:nstate=C1;
3'b000:nstate=D;
endcase
end
C2:begin
case(s)
3'b111:nstate=A;
3'b011:nstate=B2;
3'b001:nstate=C2;
3'b000:nstate=D;
endcase
end
D:begin
case(s)
3'b111:nstate=A;
3'b011:nstate=B2;
3'b001:nstate=C2;
3'b000:nstate=D;
endcase
end
endcase
end
always @(posedge clk) begin
if(reset) state <= D;
else state <= nstate;
end
always@(*)begin
case(state)
D: {fr3,fr2,fr1,dfr} = 4'b1111;
C1: {fr3,fr2,fr1,dfr} = 4'b0111;
C2: {fr3,fr2,fr1,dfr} = 4'b0110;
B1: {fr3,fr2,fr1,dfr} = 4'b0011;
B2: {fr3,fr2,fr1,dfr} = 4'b0010;
A: {fr3,fr2,fr1,dfr} = 4'b0000;
default: {fr3, fr2, fr1, dfr} = 'x;
endcase
end
endmodule
10、Lemmings1
知识点:next_state跟新的时候一定要把所以情况考虑到,不然会出现意外错误,如下:看似逻辑没问题,但是运行通不过
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
output walk_left,
output walk_right); //
parameter LEFT=0, RIGHT=1;//2^1 = 2
reg state, next_state;
always @(*) begin
if(state == LEFT&&bump_left)
next_state <= RIGHT;
else if(state==RIGHT && bump_right)
next_state <= LEFT;
end
always @(posedge clk, posedge areset) begin
if(areset) state = LEFT;
else state <= next_state;
end
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
endmodule
答案:
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
output walk_left,
output walk_right); //
parameter LEFT=0, RIGHT=1;//2^1 = 2
reg state, next_state;
always @(*) begin
case(state)
LEFT: begin
if(bump_left) next_state = RIGHT;
else next_state = LEFT;
end
RIGHT: begin
if(bump_right) next_state = LEFT;
else next_state = RIGHT;
end
default: begin
next_state = LEFT;
end
endcase
end
always @(posedge clk, posedge areset) begin
if(areset) state = LEFT;
else state <= next_state;
end
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
endmodule
11、Lemmings2⭐
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
output walk_left,
output walk_right,
output aaah );
parameter LEFT = 0, RIGHT = 1 , F_L = 2 , F_R = 3;
reg [1:0] state , next_state;
//next_state更新
always @(*) begin
case(state)
LEFT:next_state <= ground?(bump_left?RIGHT:LEFT):F_L;
RIGHT:next_state<= ground?(bump_right?LEFT:RIGHT):F_R;
F_L:next_state<=ground?LEFT:F_L;
F_R:next_state<=ground?RIGHT:F_R;
endcase
end
//state更新
always @(posedge clk,posedge areset) begin
if(areset) state <= LEFT;
else state<=next_state;
end
//out更新
assign walk_left = (state==LEFT);
assign walk_right = (state==RIGHT);
assign aaah = (state == F_L ||state ==F_R);
endmodule
12、Lemmings 3
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
input dig,
output walk_left,
output walk_right,
output aaah,
output digging );
parameter R = 3'b000, L = 3'b001, F_R = 3'b010, F_L = 3'b011, D_R = 3'b100 , D_L = 3'b101;
reg [2:0] state , next_state;
always @(*) begin
case(state)
R:next_state <= ground?(dig?D_R:(bump_right?L:R)):F_R;
L:next_state <= ground?(dig?D_L:(bump_left?R:L)):F_L;
F_R:next_state <= ground?(R):F_R;
F_L:next_state <= ground?(L):F_L;
D_R:next_state <= ground?D_R:F_R;
D_L:next_state <= ground?D_L:F_L;
endcase
end
always @(posedge clk , posedge areset) begin
if(areset) state <= L;
else state <= next_state;
end
// 输出更新
assign walk_left = (state == L);
assign walk_right = (state == R);
assign aaah = (state == F_R || state == F_L);
assign digging = (state == D_R || state == D_L);
endmodule
13、Lemmings4⭐
知识点:寄存器的计数一定是对next_state的统计。
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
input dig,
output walk_left,
output walk_right,
output aaah,
output digging );
// states definition
parameter L=0,R=1,L_G=2,R_G=3,L_D=4,R_D=5,S=6;
reg [2:0] current_state, next_state;
// states transmission
always@(posedge clk or posedge areset) begin
if(areset) begin
current_state <= L;
end
else begin
current_state <= next_state;
end
end
// counting for splatter state
reg [6:0] cout;
always@(posedge clk or posedge areset) begin
if(areset) begin
cout <= 5'd0;
end
else if( (next_state == L_G) || (next_state == R_G) ) begin
cout <= cout + 1'b1;
end
else begin
cout <= 5'd0;
end
end
// next_state judgement
always@(*) begin
case(current_state)
L: next_state = ~ground ? L_G : ( dig ? L_D : (bump_left ? R : L) );
R: next_state = ~ground ? R_G : ( dig ? R_D : (bump_right ? L : R) );
L_G: next_state = ground ? ( cout > 5'd20 ? S : L ) : L_G;
R_G: next_state = ground ? ( cout > 5'd20 ? S : R ) : R_G;
L_D: next_state = ~ground ? L_G : L_D;
R_D: next_state = ~ground ? R_G : R_D;
S: next_state = S;
endcase
end
// output logic
assign walk_left = (current_state == L);
assign walk_right = (current_state == R);
assign aaah = ((current_state == L_G) || (current_state == R_G));
assign digging = ((current_state == L_D) || (current_state == R_D));
endmodule
13、PS/2 packet parser
one-hot编码:利用其只有一位是1来简化操作。
module top_module(
input in,
input [9:0] state,
output [9:0] next_state,
output out1,
output out2);
assign next_state[0] = state[0]&~in|state[1]&~in|state[2]&~in|state[3]&~in|state[4]&~in|state[7]&~in|state[8]&~in|state[9]&~in;
assign next_state[1] = state[0]&in|state[8]&in|state[9]∈
assign next_state[2] = state[1]∈
assign next_state[3] = state[2]∈
assign next_state[4] = state[3]∈
assign next_state[5] = state[4]∈
assign next_state[6] = state[5]∈
assign next_state[7] = state[6]&in|state[7]∈
assign next_state[8] = state[5]&~in;
assign next_state[9] = state[6]&~in;
assign out1 = state[8]|state[9];
assign out2 = state[7]|state[9];
endmodule
14、PS/2 packet parser⭐
不太懂题目意思,照着hint中的状态图写的
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output done); //
parameter A = 0 , B = 1, C = 2, D = 3;
reg [1:0] state , next_state;
// State transition logic (combinational)
always @(*) begin
case(state)
A:next_state<=in[3]?B:A;
B:next_state<=C;
C:next_state<=D;
D:next_state <= in[3]?B:A;
endcase
end
// State flip-flops (sequential)
always @(posedge clk) begin
if(reset) state <= A;
else state <= next_state;
end
// Output logic
assign done = (state == D);
endmodule
15、PS/2 packet parser and datapath⭐
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output [23:0] out_bytes,
output done); //
// FSM from fsm_ps2
parameter A = 0 , B = 1, C = 2, D = 3;
reg [1:0] state , next_state;
// State transition logic (combinational)
always @(*) begin
case(state)
A:next_state<=in[3]?B:A;
B:next_state<=C;
C:next_state<=D;
D:next_state <= in[3]?B:A;
endcase
end
// State flip-flops (sequential)
always @(posedge clk) begin
if(reset) state <= A;
else state <= next_state;
end
// Output logic
assign done = (state == D);
// New: Datapath to store incoming bytes.
reg [23:0] out_reg;
always @(posedge clk) begin
if(reset) out_reg <= 24'b0;
else begin
case(next_state)
B:out_reg[23:16] <= in[7:0];
C:out_reg[15:8] <= in[7:0];
D:out_reg[7:0] <= in[7:0];
endcase
end
end
assign out_bytes = done ? out_reg : 24'b0;
endmodule
16、Serial receiver]
参考链接
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output done
);
parameter [3:0] IDLE = 4'd0;
parameter [3:0] START = 4'd1;
parameter [3:0] BIT1 = 4'd2;
parameter [3:0] BIT2 = 4'd3;
parameter [3:0] BIT3 = 4'd4;
parameter [3:0] BIT4 = 4'd5;
parameter [3:0] BIT5 = 4'd6;
parameter [3:0] BIT6 = 4'd7;
parameter [3:0] BIT7 = 4'd8;
parameter [3:0] BIT8 = 4'd9;
parameter [3:0] STOP = 4'd10;
parameter [3:0] ERROR = 4'd11;
reg [3:0] state,nstate;
always @(posedge clk)begin
if(reset)begin
state <= IDLE;
end
else begin
state <= nstate;
end
end
always @(*)begin
nstate = IDLE;
case(state)
IDLE: nstate = in? IDLE:START;
START:nstate = BIT1;
BIT1: nstate = BIT2;
BIT2: nstate = BIT3;
BIT3: nstate = BIT4;
BIT4: nstate = BIT5;
BIT5: nstate = BIT6;
BIT6: nstate = BIT7;
BIT7: nstate = BIT8;
BIT8: nstate = in? STOP:ERROR;
STOP: nstate = in? IDLE:START;
ERROR: nstate = in? IDLE:ERROR;
default: nstate = IDLE;
endcase
end
assign done = (state == STOP);
endmodule
17、Serial receiver and datapath⭐
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
); //
// Use FSM from Fsm_serial
parameter [3:0] IDLE = 4'd0;
parameter [3:0] START = 4'd1;
parameter [3:0] BIT1 = 4'd2;
parameter [3:0] BIT2 = 4'd3;
parameter [3:0] BIT3 = 4'd4;
parameter [3:0] BIT4 = 4'd5;
parameter [3:0] BIT5 = 4'd6;
parameter [3:0] BIT6 = 4'd7;
parameter [3:0] BIT7 = 4'd8;
parameter [3:0] BIT8 = 4'd9;
parameter [3:0] STOP = 4'd10;
parameter [3:0] ERROR = 4'd11;
reg [3:0] state,nstate;
always @(posedge clk)begin
if(reset)begin
state <= IDLE;
end
else begin
state <= nstate;
end
end
always @(*)begin
nstate = IDLE;
case(state)
IDLE: nstate = in? IDLE:START;
START:nstate = BIT1;
BIT1: nstate = BIT2;
BIT2: nstate = BIT3;
BIT3: nstate = BIT4;
BIT4: nstate = BIT5;
BIT5: nstate = BIT6;
BIT6: nstate = BIT7;
BIT7: nstate = BIT8;
BIT8: nstate = in? STOP:ERROR;
STOP: nstate = in? IDLE:START;
ERROR: nstate = in? IDLE:ERROR;
default: nstate = IDLE;
endcase
end
assign done = (state == STOP);
// New: Datapath to latch input bits.
reg [7:0] data_r;
always @(posedge clk)begin
case(nstate)
BIT1: data_r <= {in,data_r[7:1]};
BIT2: data_r <= {in,data_r[7:1]};
BIT3: data_r <= {in,data_r[7:1]};
BIT4: data_r <= {in,data_r[7:1]};
BIT5: data_r <= {in,data_r[7:1]};
BIT6: data_r <= {in,data_r[7:1]};
BIT7: data_r <= {in,data_r[7:1]};
BIT8: data_r <= {in,data_r[7:1]};
endcase
end
assign out_byte = (state == STOP)? data_r:0;
endmodule
18、Serial receiver with parity checking
19、Sequence recognition
20、Q8:Design a Mealy FSM
知识点:
题解参考链接
法一:利用了四种状态没有满足题目要求
module top_module (
input clk,
input aresetn, // Asynchronous active-low reset
input x,
output z );
parameter IDLE = 0, BIT1 = 1,BIT2 = 2,BIT3 = 3;
reg [1:0] state , next_state;
always @(*) begin
case(state)
IDLE:next_state<=x?BIT1:IDLE;
BIT1:next_state<=x?BIT1:BIT2;
BIT2:next_state<=x?BIT3:IDLE;
BIT3:next_state<=x?BIT1:BIT2;
endcase
end
always @(posedge clk, negedge aresetn) begin
if(~aresetn) state <= 0;
else state <= next_state;
end
assign z = ((state == BIT2) && (x == 1))? 1'b1:1'b0;
endmodule
法二:只用三种状态
module top_module (
input clk,
input aresetn, // Asynchronous active-low reset
input x,
output z );
parameter IDLE = 0, BIT1 = 1,BIT2 = 2;
reg [1:0] state , next_state;
always @(*) begin
case(state)
IDLE:next_state = x?BIT1:IDLE;
BIT1:next_state = x?BIT1:BIT2;
BIT2:next_state = x?BIT1:IDLE;
endcase
end
always @(posedge clk, negedge aresetn) begin
if(~aresetn) state <= 0;
else state <= next_state;
end
assign z = ((state == BIT2) && (x == 1))? 1'b1:1'b0;
endmodule
21、Q5a:Serial two's complementer (Moore FSM)
22、Q5a:Serial two's complementer (Mealy FSM)
23、Q3a:FSM⭐⭐(很有代表性)
知识点:如果不用计数器,那么要用16种状态才能将所有状态描述完。用计数器来代替重复的工作。
module top_module (
input clk,
input reset, // Synchronous reset
input s,
input w,
output z
);
parameter A = 0, B = 1;
reg state,nstate;
always @(posedge clk) begin
if(reset) state <= A;
else state <= nstate;
end
always @(*) begin
case(state)
A:nstate = s?B:A;
B:nstate = B;
endcase
end
reg [1:0] clk_cnt , w_cnt;
// 时钟计数
always @(posedge clk) begin
if(reset) clk_cnt <= 0;
else if(state == B) begin
if (clk_cnt==2'd2)
clk_cnt <= 0;
else
clk_cnt <= clk_cnt+1'b1;
end
else clk_cnt<=0;
end
//w计数
always @(posedge clk) begin
if (reset) w_cnt = 0;
else if(nstate == B) begin
if(clk_cnt == 2'd0) w_cnt <= w;
else if(w) w_cnt <= w_cnt + 1;
end
end
assign z=(state==B&&clk_cnt==2'd0&&w_cnt==2'd2);
endmodule
24、Q3b:FSM
module top_module (
input clk,
input reset, // Synchronous reset
input x,
output z
);
parameter s0 = 3'b000,s1 = 3'b001,s2 = 3'b010,s3 = 3'b011,s4 = 3'b100;
reg [2:0] state , nstate;
always @(posedge clk) begin
if(reset) state <= s0;
else state <= nstate;
end
always @(*) begin
case(state)
s0:nstate = x?s1:s0;
s1:nstate = x?s4:s1;
s2:nstate = x?s1:s2;
s3:nstate = x?s2:s1;
s4:nstate = x?s4:s3;
endcase
end
assign z = (state == s3|| state == s4);
endmodule
25、Q3c:FSM logic
module top_module (
input clk,
input [2:0] y,
input x,
output Y0,
output z
);
parameter s0 = 3'b000,s1 = 3'b001,s2 = 3'b010,s3 = 3'b011,s4 = 3'b100;
reg [2:0] nstate;
// nstate由x与y决定
always @(*) begin
case(y)
s0:nstate = x?s1:s0;
s1:nstate = x?s4:s1;
s2:nstate = x?s1:s2;
s3:nstate = x?s2:s1;
s4:nstate = x?s4:s3;
endcase
end
assign Y0 = nstate[0];
assign z = (y == s3|| y == s4);
endmodule
26、Q6b:FSM next-state logic
module top_module (
input [3:1] y,
input w,
output Y2);
parameter s0 = 3'b000 , s1 = 3'b001 , s2 = 3'b010 , s3 = 3'b011 , s4 = 3'b100 , s5 = 3'b101;
reg [3:1] nstate;
always @(*) begin
case(y)
s0:nstate = w?s0:s1;
s1:nstate = w?s3:s2;
s2:nstate = w?s3:s4;
s3:nstate = w?s0:s5;
s4:nstate = w?s3:s4;
s5:nstate = w?s3:s2;
endcase
end
assign Y2 = nstate[2];
endmodule
27、Q6c:FSM one-hot next-state logic
one-hot可以简化为组合逻辑
module top_module (
input [6:1] y,
input w,
output Y2,
output Y4);
reg [6:1] nstate = '0;
assign nstate[1] = (y[1]|y[4])&w;
assign nstate[2] = y[1]&~w;
assign nstate[3] = y[2]&~w|(y[6]&~w);
assign nstate[4] = w&(y[2]|y[3]|y[5]|y[6]);
assign nstate[5] = ~w&y[5]|(y[3]&~w);
assign nstate[6] = y[4]&~w;
assign Y2 = nstate[2];
assign Y4 = nstate[4];
endmodule
28、Q6:FSM
module top_module (
input clk,
input reset, // synchronous reset
input w,
output z);
parameter A = 0 ,B = 1,C = 2,D = 3,E = 4,F = 5;
reg [2:0] state ,nstate;
always @(posedge clk) begin
if(reset) state <= A;
else state <= nstate;
end
always @(*) begin
case(state)
A:nstate<=w?A:B;
B:nstate<=w?D:C;
C:nstate<=w?D:E;
D:nstate<=w?A:F;
E:nstate<=w?D:E;
F:nstate<=w?D:C;
endcase
end
assign z = (state==E||state == F);
endmodule
29、Q2a:FSM
module top_module (
input clk,
input reset, // synchronous reset
input w,
output z);
parameter A = 0 ,B = 1,C = 2,D = 3,E = 4,F = 5;
reg [2:0] state ,nstate;
always @(posedge clk) begin
if(reset) state <= A;
else state <= nstate;
end
always @(*) begin
case(state)
A:nstate<=w?B:A;
B:nstate<=w?C:D;
C:nstate<=w?E:D;
D:nstate<=w?F:A;
E:nstate<=w?E:D;
F:nstate<=w?C:D;
endcase
end
assign z = (state==E||state == F);
endmodule
30、Q2b:One-hot FSM equations
module top_module (
input [5:0] y,
input w,
output Y1,
output Y3
);
reg [5:0] nstate = '0;
assign nstate[0] = y[3]&~w|y[0]&~w;
assign nstate[1] = y[0]&w;
assign nstate[2] = y[1]&w|y[5]&w;
assign nstate[3] = y[1]&~w|y[2]&~w|y[4]&~w|y[5]&~w;
assign nstate[4] = y[4]&w|y[2]&w;
assign nstate[5] = y[3]&w;
assign Y1 = nstate[1];
assign Y3 = nstate[3];
endmodule
31、Q2a:FSM⭐
在这里犯了个错误:
parameter A = 1, B= 2, C= 3, D = 4;
reg [1:0] state ,nstate;
此时寄存器只有两位,无法保存‘4’这个大数字,最终会报错。
module top_module (
input clk,
input resetn, // active-low synchronous reset
input [3:1] r, // request
output [3:1] g // grant
);
parameter A = 0, B= 1, C= 2, D = 3;
reg [1:0] state ,nstate;
always @(posedge clk) begin
if(~resetn) state<=A;
else state<=nstate;
end
always @(*) begin
case(state)
A:begin
if(~r[1]&~r[2]&~r[3]) nstate = A;
else if(r[1]) nstate = B;
else if(~r[1]&r[2]) nstate = C;
else if(~r[1]&~r[2]&r[3]) nstate = D;
end
B:begin
if(r[1]) nstate = B;
else if(~r[1]) nstate = A;
end
C:begin
if(r[2]) nstate = C;
else if(~r[2]) nstate = A;
end
D:begin
if(r[3]) nstate = D;
else if (~r[3]) nstate = A;
end
default:nstate = A;
endcase
end
assign g[3] = (state == D);
assign g[2] = (state == C);
assign g[1] = (state == B);
endmodule
32、Q2b:Another FSM