Hdlbits

HDLBits 入门必刷50题(Verilog 带注释+功能说明)

以下题目按"组合逻辑→时序逻辑→状态机→工程模块"梯度排序,每道题含核心考点、完整代码及关键注释,可直接复制到 HDLBits 提交验证,也能本地仿真复用。

一、组合逻辑基础(10题)

1. 与门(Gates-AND2)

考点:基本逻辑门实现

module top_module(

input a,

input b,

output out );

assign out = a & b; // 与运算,两输入均为1时输出1

endmodule

2. 或非门(Gates-NOR2)

考点:逻辑运算符优先级

module top_module(

input a,

input b,

output out );

assign out = ~(a | b); // 先或后非,两输入均为0时输出1

endmodule

3. 异或门(Gates-XOR)

考点:异或运算(奇偶校验常用)

module top_module(

input a,

input b,

output out );

assign out = a ^ b; // 输入不同时输出1,相同输出0

endmodule

4. 多路选择器2选1(Mux2to1)

考点:条件运算符(组合逻辑核心)

module top_module(

input a,

input b,

input sel,

output out );

assign out = sel ? b : a; // sel=1选b,sel=0选a

endmodule

5. 多路选择器4选1(Mux4to1)

考点:嵌套条件运算符

module top_module(

input 1:0 sel,

input 3:0 data,

output out );

// sel=00选data0,01选data1,10选data2,11选data3

assign out = sel1 ? (sel0 ? data3 : data2) : (sel0 ? data1 : data0);

endmodule

6. 位宽扩展(Gates-Extension)

考点:位运算与符号扩展

module top_module(

input 7:0 a,

input 7:0 b,

output 7:0 out_or_bitwise,

output out_or_logical,

output 7:0 out_xor );

assign out_or_bitwise = a | b; // 按位或

assign out_or_logical = |(a | b); // 逻辑或(整体判0)

assign out_xor = a ^ b; // 按位异或

endmodule

7. 加法器(Adder-1bit)

考点:算术运算基础

module top_module(

input a,

input b,

input cin,

output cout,

output sum );

assign sum = a ^ b ^ cin; // 全加器和逻辑

assign cout = (a & b) | (a & cin) | (b & cin); // 全加器进位逻辑

endmodule

8. 比较器(Comparator-2bit)

考点:组合逻辑条件判断

module top_module(

input 1:0 a,

input 1:0 b,

output eq );

assign eq = (a == b) ? 1'b1 : 1'b0; // 2位数据相等判断

endmodule

9. 译码器(Decoder-3to8)

考点:case语句应用

module top_module(

input 2:0 in,

output 7:0 out );

always @(*) begin

out = 8'b0; // 初始化为0,避免 latch

case(in)

3'd0: out = 8'b00000001;

3'd1: out = 8'b00000010;

3'd2: out = 8'b00000100;

3'd3: out = 8'b00001000;

3'd4: out = 8'b00010000;

3'd5: out = 8'b00100000;

3'd6: out = 8'b01000000;

3'd7: out = 8'b10000000;

endcase

end

endmodule

10. 优先级编码器(Priority-Encoder)

考点:casez语句(无关位处理)

module top_module(

input 3:0 in,

output 1:0 pos );

always @(*) begin

casez(in)

4'b1???: pos = 2'd3; // 最高位优先

4'b01??: pos = 2'd2;

4'b001?: pos = 2'd1;

4'b0001: pos = 2'd0;

default: pos = 2'd0;

endcase

end

endmodule

二、时序逻辑基础(10题)

11. D触发器(DFF)

考点:时序逻辑建模(时钟触发)

module top_module(

input clk,

input d,

output reg q );

always @(posedge clk) begin // 时钟上升沿触发

q <= d; // 非阻塞赋值(时序逻辑专用)

end

endmodule

12. D触发器带复位(DFF-Reset)

考点:同步复位

module top_module(

input clk,

input reset,

input d,

output reg q );

always @(posedge clk) begin

if(reset) begin

q <= 1'b0; // 复位时置0

end else begin

q <= d;

end

end

endmodule

13. D触发器带异步复位(DFF-Async-Reset)

考点:异步复位(复位独立于时钟)

module top_module(

input clk,

input areset, // 异步复位(高有效)

input d,

output reg q );

always @(posedge clk or posedge areset) begin // 复位沿触发

if(areset) begin

q <= 1'b0;

end else begin

q <= d;

end

end

endmodule

14. 计数器(Counter-4bit)

考点:时序逻辑循环计数

module top_module(

input clk,

input reset,

output reg 3:0 q );

always @(posedge clk) begin

if(reset) begin

q <= 4'd0; // 复位清零

end else begin

q <= q + 4'd1; // 每次时钟加1

end

end

endmodule

15. 减计数器(Counter-Down-4bit)

考点:递减计数与边界处理

module top_module(

input clk,

input reset,

output reg 3:0 q );

always @(posedge clk) begin

if(reset) begin

q <= 4'd15; // 复位置最大值

end else begin

q <= q - 4'd1; // 每次时钟减1

end

end

endmodule

16. 模10计数器(Counter-Mod10)

考点:模值计数(工程常用)

module top_module(

input clk,

input reset,

output reg 3:0 q );

always @(posedge clk) begin

if(reset || q == 4'd9) begin // 计数到9复位

q <= 4'd0;

end else begin

q <= q + 4'd1;

end

end

endmodule

17. 移位寄存器(Shift-Register-4bit)

考点:数据移位操作

module top_module(

input clk,

input reset,

input data,

output reg 3:0 q );

always @(posedge clk) begin

if(reset) begin

q <= 4'd0;

end else begin

q <= {q2:0, data}; // 左移1位,新数据从最低位输入

end

end

endmodule

18. 双边沿D触发器(DFF-Dual-Edge)

考点:时钟双边沿触发

module top_module(

input clk,

input d,

output reg q );

always @(posedge clk or negedge clk) begin // 上升沿和下降沿都触发

q <= d;

end

endmodule

19. 同步使能计数器(Counter-Enable)

考点:使能信号控制计数

module top_module(

input clk,

input reset,

input en,

output reg 3:0 q );

always @(posedge clk) begin

if(reset) begin

q <= 4'd0;

end else if(en) begin // 使能有效时计数

q <= q + 4'd1;

end

// 使能无效时保持原值

end

endmodule

20. 寄存器堆(Register-File-2x2)

考点:多寄存器读写控制

module top_module(

input clk,

input 1:0 addr,

input we, // 写使能

input 3:0 din,

output reg 3:0 dout );

reg 3:0 reg0, reg1, reg2, reg3; // 4个4位寄存器

always @(posedge clk) begin

if(we) begin // 写操作

case(addr)

2'd0: reg0 <= din;

2'd1: reg1 <= din;

2'd2: reg2 <= din;

2'd3: reg3 <= din;

endcase

end

// 读操作(组合逻辑,即时输出)

case(addr)

2'd0: dout = reg0;

2'd1: dout = reg1;

2'd2: dout = reg2;

2'd3: dout = reg3;

endcase

end

endmodule

三、状态机(10题)

21. 摩尔状态机(Moore-FSM-1)

考点:摩尔状态机(输出仅依赖当前状态)

module top_module(

input clk,

input reset,

input in,

output out);

// 定义状态

typedef enum {S0, S1, S2, S3} state_t;

state_t current_state, next_state;

// 状态寄存器(时序逻辑)

always @(posedge clk or posedge reset) begin

if(reset) begin

current_state <= S0;

end else begin

current_state <= next_state;

end

end

// 下一状态逻辑(组合逻辑)

always @(*) begin

case(current_state)

S0: next_state = in ? S1 : S0;

S1: next_state = in ? S2 : S0;

S2: next_state = in ? S3 : S0;

S3: next_state = in ? S3 : S0;

default: next_state = S0;

endcase

end

// 输出逻辑(仅依赖当前状态)

assign out = (current_state == S3) ? 1'b1 : 1'b0;

endmodule

22. 米利状态机(Mealy-FSM-1)

考点:米利状态机(输出依赖当前状态+输入)

module top_module(

input clk,

input reset,

input in,

output out);

typedef enum {S0, S1} state_t;

state_t current_state, next_state;

// 状态寄存器

always @(posedge clk or posedge reset) begin

if(reset) current_state <= S0;

else current_state <= next_state;

end

// 下一状态逻辑

always @(*) begin

case(current_state)

S0: next_state = in ? S1 : S0;

S1: next_state = in ? S0 : S1;

default: next_state = S0;

endcase

end

// 输出逻辑(依赖状态+输入)

assign out = (current_state == S1 && in == 1'b1) ? 1'b1 : 1'b0;

endmodule

23. 序列检测器(Sequence-110)

考点:状态机检测特定序列

module top_module(

input clk,

input reset,

input in,

output reg out);

typedef enum {S0, S1, S2} state_t;

state_t current_state, next_state;

// 状态寄存器

always @(posedge clk or posedge reset) begin

if(reset) current_state <= S0;

else current_state <= next_state;

end

// 下一状态逻辑(检测序列110)

always @(*) begin

case(current_state)

S0: next_state = in ? S1 : S0; // 收到第一个1

S1: next_state = in ? S2 : S0; // 收到第二个1

S2: next_state = in ? S1 : S0; // 收到0,完成序列

default: next_state = S0;

endcase

end

// 检测到110时输出1

always @(posedge clk or posedge reset) begin

if(reset) out <= 1'b0;

else out <= (current_state == S2 && in == 1'b0) ? 1'b1 : 1'b0;

end

endmodule

24. 状态机带复位(FSM-Reset-Sync)

考点:同步复位状态机

module top_module(

input clk,

input reset,

input 1:0 op,

output reg 1:0 out);

typedef enum {S0, S1, S2} state_t;

state_t current_state, next_state;

// 同步复位状态寄存器

always @(posedge clk) begin

if(reset) current_state <= S0;

else current_state <= next_state;

end

// 下一状态逻辑

always @(*) begin

next_state = current_state; // 默认保持当前状态

case(op)

2'd0: next_state = S0;

2'd1: next_state = S1;

2'd2: next_state = S2;

endcase

end

// 输出逻辑

assign out = (current_state == S0) ? 2'd0 :

(current_state == S1) ? 2'd1 : 2'd2;

endmodule

25. 双序列检测器(FSM-Dual-Sequence)

考点:状态机同时检测两个序列

module top_module(

input clk,

input reset,

input in,

output out1,

output out2);

// 检测序列110(out1)和101(out2)

typedef enum {S0, S1, S2, S3, S4} state_t;

state_t current_state, next_state;

always @(posedge clk or posedge reset) begin

if(reset) current_state <= S0;

else current_state <= next_state;

end

always @(*) begin

next_state = S0;

case(current_state)

S0: next_state = in ? S1 : S0;

S1: next_state = in ? S2 : S3; // 1→1(S2),1→0(S3)

S2: next_state = in ? S2 : S0; // 11→0→S0(输出out1)

S3: next_state = in ? S4 : S0; // 10→1→S4(输出out2)

S4: next_state = in ? S2 : S3;

endcase

end

assign out1 = (current_state == S2 && in == 1'b0); // 检测到110

assign out2 = (current_state == S3 && in == 1'b1); // 检测到101

endmodule

26. 状态机带使能(FSM-Enable)

考点:使能信号控制状态机运行

module top_module(

input clk,

input reset,

input en,

input 1:0 op,

output reg 1:0 out);

typedef enum {S0, S1, S2} state_t;

state_t current_state, next_state;

always @(posedge clk or posedge reset) begin

if(reset) current_state <= S0;

else if(en) current_state <= next_state; // 使能有效时切换状态

end

always @(*) begin

next_state = current_state;

case(op)

2'd0: next_state = S0;

2'd1: next_state = S1;

2'd2: next_state = S2;

endcase

end

assign out = (current_state == S0) ? 2'd0 :

(current_state == S1) ? 2'd1 : 2'd2;

endmodule

27. 一位全加器状态机(FSM-Full-Adder)

考点:状态机实现算术运算

module top_module(

input clk,

input reset,

input a,

input b,

input cin,

output reg cout,

output reg sum);

// 状态表示进位cin(0或1)

typedef enum {C0, C1} state_t;

state_t current_state, next_state;

always @(posedge clk or posedge reset) begin

if(reset) current_state <= C0;

else current_state <= next_state;

end

always @(*) begin

// 计算sum和next_state(进位)

sum = a ^ b ^ (current_state == C1 ? 1'b1 : 1'b0);

cout = (a & b) | (a & (current_state == C1)) | (b & (current_state == C1));

next_state = cout ? C1 : C0;

end

endmodule

28. 按键消抖状态机(FSM-Deounce)

考点:状态机解决实际工程问题

module top_module(

input clk,

input reset,

input btn,

output reg btn_clean);

// 消抖状态:等待稳定、确认按下、确认释放

typedef enum {IDLE, WAIT_PRESS, PRESSED, WAIT_RELEASE} state_t;

state_t current_state, next_state;

reg 19:0 cnt; // 20ms计数器(50MHz时钟)

// 计数器

always @(posedge clk or posedge reset) begin

if(reset) cnt <= 20'd0;

else if(current_state != next_state) cnt <= 20'd0; // 状态切换时清零

else cnt <= cnt + 20'd1;

end

// 状态寄存器

always @(posedge clk or posedge reset) begin

if(reset) current_state <= IDLE;

else current_state <= next_state;

end

// 下一状态逻辑

always @(*) begin

next_state = current_state;

case(current_state)

IDLE: if(btn == 1'b0) next_state = WAIT_PRESS; // 检测到按键按下

WAIT_PRESS: if(cnt == 20'd1_000_000) next_state = PRESSED; // 稳定20ms

PRESSED: if(btn == 1'b1) next_state = WAIT_RELEASE; // 检测到按键释放

WAIT_RELEASE: if(cnt == 20'd1_000_000) next_state = IDLE; // 稳定20ms

endcase

end

// 输出消抖后的按键信号

assign btn_clean = (current_state == PRESSED) ? 1'b1 : 1'b0;

endmodule

29. 状态机编码(FSM-Encoding)

考点:二进制编码vs独热码

module top_module(

input clk,

input reset,

input in,

output out);

// 独热码编码(减少组合逻辑延迟)

typedef enum {S0=4'b0001, S1=4'b0010, S2=4'b0100, S3=4'b1000} state_t;

state_t current_state, next_state;

always @(posedge clk or posedge reset) begin

if(reset) current_state <= S0;

else current_state <= next_state;

end

always @(*) begin

next_state = S0;

case(current_state)

S0: next_state = in ? S1 : S0;

S1: next_state = in ? S2 : S0;

S2: next_state = in ? S3 : S0;

S3: next_state = in ? S3 : S0;

endcase

end

assign out = (current_state == S3) ? 1'b1 : 1'b0;

endmodule

30. 多输出状态机(FSM-Multi-Output)

考点:状态机控制多个输出

module top_module(

input clk,

input reset,

input 1:0 in,

output reg 1:0 out1,

output reg 1:0 out2);

typedef enum {S0, S1, S2} state_t;

state_t current_state, next_state;

always @(posedge clk or posedge reset) begin

if(reset) current_state <= S0;

else current_state <= next_state;

end

always @(*) begin

next_state = current_state;

case(in)

2'd0: next_state = S0;

2'd1: next_state = S1;

2'd2: next_state = S2;

endcase

end

// 多输出逻辑

always @(*) begin

case(current_state)

S0: begin out1 = 2'd0; out2 = 2'd3; end

S1: begin out1 = 2'd1; out2 = 2'd2; end

S2: begin out1 = 2'd2; out2 = 2'd1; end

default: begin out1 = 2'd0; out2 = 2'd0; end

endcase

end

endmodule

四、工程常用模块(10题)

31. 二分频器(Clock-Divider-2)

考点:时钟分频基础

module top_module(

input clk,

input reset,

output reg clk_div2);

always @(posedge clk or posedge reset) begin

if(reset) begin

clk_div2 <= 1'b0;

end else begin

clk_div2 <= ~clk_div2; // 每两个时钟周期翻转一次

end

end

endmodule

32. 四分频器(Clock-Divider-4)

考点:奇数分频vs偶数分频

module top_module(

input clk,

input reset,

output reg clk_div4);

reg 1:0 cnt; // 2位计数器实现4分频

always @(posedge clk or posedge reset) begin

if(reset) begin

cnt <= 2'd0;

clk_div4 <= 1'b0;

end else begin

if(cnt == 2'd1) begin // 计数到1时翻转(占空比50%)

cnt <= cnt + 2'd1;

clk_div4 <= ~clk_div4;

end else if(cnt == 2'd3) begin

cnt <= 2'd0;

clk_div4 <= ~clk_div4;

end else begin

cnt <= cnt + 2'd1;

end

end

end

endmodule

33. 格雷码计数器(Gray-Counter-4bit)

考点:格雷码编码(减少翻转次数)

module top_module(

input clk,

input reset,

output reg 3:0 gray);

reg 3:0 q; // 二进制计数器

// 二进制计数器

always @(posedge clk or posedge reset) begin

if(reset) q <= 4'd0;

else q <= q + 4'd1;

end

// 格雷码 = 二进制 ^ 二进制右移1位

assign gray = q ^ (q >> 1);

endmodule

34. FIFO基础(FIFO-Basic)

考点:同步FIFO实现

module top_module(

input clk,

input reset,

input wr_en,

input rd_en,

input 7:0 din,

output reg 7:0 dout,

output full,

output empty);

reg 7:0 fifo 0:3; // 4深度FIFO

reg 1:0 wr_ptr, rd_ptr; // 写指针、读指针

reg 2:0 cnt; // 计数(判断满/空)

// 满/空判断

assign full = (cnt == 3'd4);

assign empty = (cnt == 3'd0);

// 写操作

always @(posedge clk or posedge reset) begin

if(reset) begin

wr_ptr <= 2'd0;

end else if(wr_en && !full) begin

fifowr_ptr <= din;

wr_ptr <= wr_ptr + 2'd1;

end

end

// 读操作

always @(posedge clk or posedge reset) begin

if(reset) begin

rd_ptr <= 2'd0;

dout <= 8'd0;

end else if(rd_en && !empty) begin

dout <= fiford_ptr;

rd_ptr <= rd_ptr + 2'd1;

end

end

// 计数更新

always @(posedge clk or posedge reset) begin

if(reset) begin

cnt <= 3'd0;

end else begin

case({wr_en, rd_en})

2'b00: cnt <= cnt;

2'b01: cnt <= cnt - 3'd1; // 只读

2'b10: cnt <= cnt + 3'd1; // 只写

2'b11: cnt <= cnt; // 同时读写

endcase

end

end

endmodule

35. ROM初始化(ROM-Init)

考点:FPGA内部ROM使用

module top_module(

input clk,

input 3:0 addr,

output reg 7:0 dout);

// 初始化ROM数据(0-15对应0x00-0x0F)

reg 7:0 rom 0:15;

initial begin

rom0 = 8'h00;

rom1 = 8'h01;

rom2 = 8'h02;

rom3 = 8'h03;

rom4 = 8'h04;

rom5 = 8'h05;

rom6 = 8'h06;

rom7 = 8'h07;

rom8 = 8'h08;

rom9 = 8'h09;

rom10 = 8'h0a;

rom11 = 8'h0b;

rom12 = 8'h0c;

rom13 = 8'h0d;

rom14 = 8'h0e;

rom15 = 8'h0f;

end

// 同步读ROM

always @(posedge clk) begin

dout <= romaddr;

end

endmodule

  1. RAM读写(RAM-RW)

考点:FPGA内部RAM使用

module top_module(

input clk,

input we,

input 3:0 addr,

input 7:0 din,

output reg 7:0 dout);

reg 7:0 ram 0:15; // 16x8 RAM

// 同步读写

always @(posedge clk) begin

if(we) begin // 写使能有效

ramaddr <= din;

end

dout <= ramaddr; // 读操作(无论是否写)

end

endmodule

37. 跨时钟域同步(CDC-Sync-1bit)

考点:单bit跨时钟域处理

module top_module(

input clk_a,

input clk_b,

input rst_a,

input rst_b,

input data_in,

output data_out);

// 两级寄存器同步(避免亚稳态)

reg sync1, sync2;

always @(posedge clk_b or posedge rst_b) begin

if(rst_b) begin

sync1 <= 1'b0;

sync2 <= 1'b0;

end else begin

sync1 <= data_in; // 第一级同步

sync2 <= sync1; // 第二级同步

end

end

assign data_out = sync2;

endmodule

38. 流水线加法器(Pipeline-Adder)

考点:流水线提升时序性能

module top_module(

input clk,

input 7:0 a,

input 7:0 b,

output reg 8:0 sum);

reg 7:0 a_reg, b_reg;

reg 8:0 sum_reg;

// 流水线第一级:寄存器输入

always @(posedge clk) begin

a_reg <= a;

b_reg <= b;

end

// 流水线第二级:计算和

always @(posedge clk) begin

sum_reg <= a_reg + b_reg;

end

// 流水线第三级:输出寄存器

always @(posedge clk) begin

sum <= sum_reg;

end

endmodule

39. I2C起始条件检测(I2C-Start)

考点:硬件接口时序检测

module top_module(

input clk,

input scl,

input sda,

output reg start);

reg sda_prev; // 寄存前一个时钟的SDA信号

// 寄存SDA

always @(posedge clk) begin

sda_prev <= sda;

end

// I2C起始条件:SCL高电平时,SDA从高变低

assign start = (scl == 1'b1) && (sda_prev == 1'b1) && (sda == 1'b0);

endmodule

40. SPI时钟生成(SPI-Clk-Gen)

考点:SPI接口时钟控制

module top_module(

input clk,

input reset,

input en,

output reg sclk);

reg 3:0 cnt; // 16分频(50MHz→3.125MHz)

always @(posedge clk or posedge reset) begin

if(reset) begin

cnt <= 4'd0;

sclk <= 1'b0;

end else if(en) begin

if(cnt == 4'd7) begin // 计数到7翻转时钟

cnt <= 4'd0;

sclk <= ~sclk;

end else begin

cnt <= cnt + 4'd1;

end

end else begin

sclk <= 1'b0; // 使能无效时时钟为0

end

end

endmodule

五、综合实战(10题)

41. 4位加法器(Adder-4bit)

考点:模块化设计

// 1位全加器模块

module full_adder(

input a,

input b,

input cin,

output cout,

output sum);

assign sum = a ^ b ^ cin;

assign cout = (a & b) | (a & cin) | (b & cin);

endmodule

// 4位加法器(级联1位全加器)

module top_module(

input 3:0 a,

input 3:0 b,

input cin,

output 3:0 sum,

output cout);

wire 2:0 carry; // 进位链

full_adder fa0(a0, b0, cin, carry0, sum0);

full_adder fa1(a1, b1, carry0, carry1, sum1);

full_adder fa2(a2, b2, carry1, carry2, sum2);

full_adder fa3(a3, b3, carry2, cout, sum3);

endmodule

42. BCD加法器(BCD-Adder)

考点:BCD码算术运算

module top_module(

input 3:0 a,

input 3:0 b,

input cin,

output reg 3:0 sum,

output reg cout);

wire 4:0 temp;

assign temp = a + b + cin;

// BCD码需校正:和≥10或有进位时加6校正

always @(*) begin

if(temp > 4'd9 || temp4) begin

sum = temp3:0 + 4'd6;

cout = 1'b1;

end else begin

sum = temp3:0;

cout = 1'b0;

end

end

endmodule

43. 移位寄存器串并转换(Shift-Parallel)

考点:串并转换(通信接口常用)

module top_module(

input clk,

input reset,

input ser_in,

input load,

input 7:0 par_in,

output reg 7:0 par_out,

output ser_out);

always @(posedge clk or posedge reset) begin

if(reset) begin

par_out <= 8'd0;

end else if(load) begin

par_out <= par_in; // 并行加载

end else begin

par_out <= {par_out6:0, ser_in}; // 左移,串行输入

end

end

assign ser_out = par_out7; // 串行输出(最高位)

endmodule

44. 计数器带加载(Counter-Load)

考点:可编程计数器

module top_module(

input clk,

input reset,

input load,

input 3:0 data,

output reg 3:0 q);

always @(posedge clk or posedge reset) begin

if(reset) begin

q <= 4'd0;

end else if(load) begin

q <= data; // 加载初始值

end else begin

q <= q + 4'd1; // 计数

end

end

endmodule

45. 脉冲宽度调制(PWM)

考点:PWM波形生成(电机控制常用)

module top_module(

input clk,

input reset,

input 7:0 duty,

output reg pwm_out);

reg 7:0 cnt; // 8位计数器(0-255)

always @(posedge clk or posedge reset) begin

if(reset) begin

cnt <= 8'd0;

end else begin

cnt <= cnt + 8'd1;

end

end

// 占空比 = duty/256

always @(posedge clk or posedge reset) begin

if(reset) begin

pwm_out <= 1'b0;

end else begin

pwm_out <= (cnt < duty) ? 1'b1 : 1'b0;

end

end

endmodule

46. 数字锁(Digital-Lock)

考点:状态机+计数器综合应用

module top_module(

input clk,

input reset,

input 3:0 key,

output reg unlock);

// 密码:1234

typedef enum {S0, S1, S2, S3, UNLOCKED} state_t;

state_t current_state, next_state;

reg 19:0 cnt; // 10秒超时计数器(50MHz时钟)

// 超时计数器

always @(posedge clk or posedge reset) begin

if(reset) cnt <= 20'd0;

else if(current_state != S0) cnt <= cnt + 20'd1;

else cnt <= 20'd0;

end

// 状态寄存器

always @(posedge clk or posedge reset) begin

if(reset) current_state <= S0;

else if(cnt == 20'd5_000_000) current_state <= S0; // 超时复位

else current_state <= next_state;

end

// 下一状态逻辑

always @(*) begin

next_state = current_state;

case(current_state)

S0: if(key == 4'd1) next_state = S1;

S1: if(key == 4'd2) next_state = S2;

S2: if(key == 4'd3) next_state = S3;

S3: if(key == 4'd4) next_state = UNLOCKED;

UNLOCKED: next_state = UNLOCKED; // 解锁后保持

endcase

end

assign unlock = (current_state == UNLOCKED) ? 1'b1 : 1'b0;

endmodule

47. 灰度码到二进制转换(Gray-to-Binary)

考点:编码转换

module top_module(

input 3:0 gray,

output reg 3:0 binary);

// 二进制最高位=灰度码最高位,其余位=前一位二进制^当前灰度码

always @(*) begin

binary3 = gray3;

binary2 = binary3 ^ gray2;

binary1 = binary2 ^ gray1;

binary0 = binary1 ^ gray0;

end

endmodule

48. 二进制到灰度码转换(Binary-to-Gray)

考点:编码转换

module top_module(

input 3:0 binary,

output reg 3:0 gray);

// 灰度码 = 二进制 ^ 二进制右移1位

always @(*) begin

gray = binary ^ (binary >> 1);

end

endmodule

49. 同步FIFO带空满标志(FIFO-Full-Empty)

考点:FIFO优化设计

module top_module(

input clk,

input reset,

input wr_en,

input rd_en,

input 7:0 din,

output reg 7:0 dout,

output reg full,

output reg empty);

reg 7:0 fifo 0:7; // 8深度FIFO

reg 2:0 wr_ptr, rd_ptr;

reg 3:0 cnt; // 0-8计数

// 满/空判断

always @(posedge clk or posedge reset) begin

if(reset) begin

full <= 1'b0;

empty <= 1'b1;

end else begin

full <= (cnt == 4'd8);

empty <= (cnt == 4'd0);

end

end

// 写操作

always @(posedge clk or posedge reset) begin

if(reset) begin

wr_ptr <= 3'd0;

end else if(wr_en && !full) begin

fifowr_ptr <= din;

wr_ptr <= wr_ptr + 3'd1;

end

end

// 读操作

always @(posedge clk or posedge reset) begin

if(reset) begin

rd_ptr <= 3'd0;

dout <= 8'd0;

end else if(rd_en && !empty) begin

dout <= fiford_ptr;

rd_ptr <= rd_ptr + 3'd1;

end

end

// 计数更新

always @(posedge clk or posedge reset) begin

if(reset) begin

cnt <= 4'd0;

end else begin

case({wr_en, rd_en})

2'b00: cnt <= cnt;

2'b01: cnt <= cnt - 4'd1;

2'b10: cnt <= cnt + 4'd1;

2'b11: cnt <= cnt;

endcase

end

end

endmodule

50. 简易UART发送器(UART-Tx)

考点:串行通信接口实现

module top_module(

input clk,

input reset,

input 7:0 data,

input send,

output reg tx,

output reg done);

// UART参数:1位起始位,8位数据位,1位停止位,无校验

typedef enum {IDLE, START, DATA, STOP} state_t;

state_t current_state, next_state;

reg 3:0 bit_cnt; // 数据位计数(0-7)

reg 15:0 baud_cnt; // 波特率计数器(9600bps@50MHz:50e6/9600≈5208)

// 波特率计数器

always @(posedge clk or posedge reset) begin

if(reset) baud_cnt <= 16'd0;

else if(current_state != IDLE) baud_cnt <= baud_cnt + 16'd1;

else baud_cnt <= 16'd0;

end

// 状态寄存器

always @(posedge clk or posedge reset) begin

if(reset) current_state <= IDLE;

else current_state <= next_state;

end

// 下一状态逻辑

always @(*) begin

next_state = current_state;

case(current_state)

IDLE: if(send) next_state = START;

START: if(baud_cnt == 16'd5207) next_state = DATA; // 起始位结束

DATA: if(baud_cnt == 16'd5207 && bit_cnt == 3'd7) next_state = STOP; // 8位数据发送完成

STOP: if(baud_cnt == 16'd5207) next_state = IDLE; // 停止位结束

endcase

end

// 数据位计数

always @(posedge clk or posedge reset) begin

if(reset) bit_cnt <= 3'd0;

else if(current_state == DATA && baud_cnt == 16'd5207) bit_cnt <= bit_cnt + 3'd1;

else if(current_state != DATA) bit_cnt <= 3'd0;

end

// TX输出

always @(posedge clk or posedge reset) begin

if(reset) begin

tx <= 1'b1; // IDLE状态为高电平

end else begin

case(current_state)

IDLE: tx <= 1'b1;

START: tx <= 1'b0; // 起始位低电平

DATA: tx <= databit_cnt; // 逐位发送数据

STOP: tx <= 1'b1; // 停止位高电平

endcase

end

end

// 发送完成标志

always @(posedge clk or posedge reset) begin

if(reset) done <= 1'b0;

else done <= (current_state == STOP && baud_cnt == 16'd5207);

end

endmodule

需要我帮你生成这些题目的 Testbench 仿真代码 吗?每个模块对应独立的Testbench,包含激励信号生成和功能验证逻辑,可直接在 Vivado/Quartus 中运行仿真。

相关推荐
仲南音2 天前
Xilinx FPGA——时钟IP核MMCM、PLL
fpga开发
I'm a winner3 天前
基于Xilinx FPGA的LVDS高速串行通信系统(三)--数据训练及握手机制【文末源码】
fpga开发
upper20203 天前
coremark移植坑之-nostartfiles -nostdlib参数
学习·fpga开发·coremark移植·riscv设计
Eloudy3 天前
Vivado 纯命令行构建 FPGA 项目教程
fpga开发
Rambo.xia3 天前
AXI跨时钟域与数据一致性——CDC FIFO深度不够、写后读冒险、多Master仲裁、乱序返回,出了Bug根本查不出来
fpga开发·bug
upper20203 天前
FPGA部署卷积神经网络识别MINST图片
fpga开发·卷积神经网络·minst·minst识别·部署神经网络·神经网络识别图片
你是我的解忧王子3 天前
嵌入式 ADC采样 原始数据分析上层(平均值 波动率 正态分布 线性补偿 系统误差)
fpga开发·数据挖掘·数据分析
9527华安4 天前
FPGA纯verilog代码ISP图像处理培训教程,基于IMX214,提供工程源码+视频教程+FPGA开发板
图像处理·fpga开发·isp·imx214·mipi
千寻xun5 天前
二、实战篇-NVME SSD控制之ZYNQ实现(六)-读写NVME SSD硬盘数据
fpga开发·nvme·nvme ssd
千寻xun5 天前
二、实战篇-NVME SSD控制之ZYNQ实现(三)
fpga开发·nvme ssd·nvme协议