# Verilog 复习

# 基础语法部分

# 关于 beginend

不要 C/Python 写多了,就忘了 Verilog 是用 beginend 标记语句块

还有 case 语句没有 begin ,只有 endcasemodule 定义没有 begin ,只有 endmodule

# 关于 assignalways @(*)

没啥区别

# 关于赋值

如果是如下定义的寄存器型变量

reg [6:4] a;
reg [0:2] b;

那么这样的赋值是合法的

assign a[6:4] = b[0:2];

但是这样赋值就会错

assign a[6:4] = b[2:0];

总之就是赋值只能按照定义时的大小端去用

# 关于数字

下面的数字常量是合法的

'b1000, 8'o100, 8'b_0100_1000, -3'd10

下面的是不合法的

3'101, 32'd-100, 2b10

变量如果不加以特殊说明,默认按照无符号数处理,有符号与无符号相遇,默认将有符号转为无符号,因此

reg[31:0] a, b;
initial a = 1;
initial b = -1;
a < b			//True,这里的 - 1 被理解成了 15
a < $signed(b)	//True,b 为 signed,a 为 unsigned,则 b 转换成 unsigned
$signed(a) < $signed(b)		//False,这才对

# 关于一些有用的调试和系统指令

$display("%d %d ...", wire1, reg2, ...);		// 可以打印 wire 或者 reg 的值到控制台
#15;											// 延时 15ns
always #1 clk = ~clk;							// 每 1ns 改变一次时钟信号,这个语句优先级高于其他的,因此你在第一秒后 $display (clk) 就已经不是原来的值了

# 具体题目类型

# 关于 Moore 型状态机

基本框架如下:

module moore_fsm(
	input x,
    input clk,
    input reset,
    output x
	)
    
    parameter START = 0, ...		// 在这里定义每一个状态对应的标签
    reg[7:0] state, next_state;		// 这里是当前状态和下一个状态,记得大小要开足够
    
    always @(*) begin				// 组合逻辑,根据当前状态 state 计算 next_state
        case(state)
            START: begin
                ...
            end
            ...
            default: 				// 建议写上 default
                ...
        endcase
    end
    
    always @(posedge clk) begin		// 赋值下一个状态
        if(reset) state <= START;
        else state <= next_state;
    end
    
    assign x = ...					// 输出逻辑
        
endmodule

此外还有别的变种,例如使用 One-Hot 编码状态,这样的状态转移会好写一点(详见 Hdlbit 上的题目)

还有一种类型就是字符串识别,遇到重复的字符串需要考虑设置计数器统计出现的次数