从黑金FPGA的文档资料里面摘抄出了会用使用到的东西,便于查阅。
1 数据类型
1.1 常量
整数:二进制(b或B)、八进制(o或O)、十进制(d或D)、十六进制(h或H)。
8’b00001111 //八位二进制
X和Z:X代表不定值、Z代表高阻值。
下划线:在位数过长时,可用来分割,提高程序可读性。
参数 parameter:可用来定义常量。
parameter width = 8; //定义了一个常量为8
localparam:只能用于本模块内使用,不能用于参数传递。
1.2 变量
wire:网络类型变量,必须用assign进行赋值,用来表示实体之间的连接。
Reg:寄存器变量,可用来存储值,必须在always语句中使用。
1.3 Memory类型
定义RAM、ROM等存储器。
reg [7:0] ram [255:0] //定义了256个8位寄存器,256为存储器的深度,8为数据的宽度。
2 运算符
2.1 算术运算符
+ //加
- //减
* //乘
/ //整除
% //取模
2.2 赋值运算符
= //阻塞(Blocking)赋值,执行完一条赋值语句后立即执行
<= //非阻塞(Nonblocking)赋值,并行执行,不考虑顺序,在always块语句执行完成后,才进行赋值
一般情况下,在时序逻辑电路中使用非阻塞赋值,可避免仿真时出现竞争冒险现象;在组合逻辑中使用阻塞赋值,执行赋值语句后立即改变;在 assign 语句中必须用阻塞赋值。
2.3 关系运算符
用于表示两个操作数之间的关系,如 a>b
2.4 逻辑运算符
&& //两个操作数逻辑与
|| //两个操作数逻辑或
! //单个操作数逻辑非
2.5 条件运算符
?: 用法类似于三目运算符。
assign a = (i>8)?1’b1:1’b0
2.6 位运算符
~ //按位取反
| //按位或,
^ //按位异或,
& //按位与,
^ //按位同或,
2.7 移位运算符
<< //左移位运算符
>> //右移位运算符
2.8 拼接运算符
{a[3:0], b[1:0]} //将a的低4位,b的低2位拼接成6位数据,类似MATLAB
2.9 优先级别
3 组合逻辑
3.1 与门
module top(a, b, c) ;
input a ;
input b ;
output c ;
assign c = a & b ;
endmodule
3.2 或门
module top(a, b, c) ;
input a ;
input b ;
output c ;
assign c = a | b ;
endmodule
3.3 非门
module top(a, b) ;
input a ;
output b ;
assign b = ~a ;
endmodule
3.4 异或
module top(a, b, c) ;
input a ;
input b ;
output c ;
assign c = a ^ b ;
endmodule
3.5 比较器
module top(a, b, c) ;
input a ;
input b ;
output c ;
assign c = a > b ;
endmodule
3.6 半加器&全加器
module top(a, b, sum, count) ;
input a ;
input b ;
output sum ;
output count ;
assign sum = a ^ b ;
assign count = a & b ;
endmodule
module top(cin, a, b, sum, count) ;
input cin ;
input a ;
input b ;
output sum ;
output count ;
assign {count,sum} = a + b + cin ;
endmodule
3.7 乘法器
module top(a, b, c) ;
input [1:0] a ;
input [1:0] b ;
output [3:0] c ;
assign c = a * b ;
endmodule
3.8 数据选择器
module top(a, b, c, d, sel, Mux) ;
input a ;
input b ;
input c ;
input d ;
input [1:0] sel ;
output reg Mux ;
always @(sel or a or b or c or d)
begin
case(sel)
2'b00 : Mux = a ;
2'b01 : Mux = b ;
2'b10 : Mux = c ;
2'b11 : Mux = d ;
endcase
end
endmodule
3.9 3-8译码器
module top(addr, decoder) ;
input [2:0] addr ;
output reg [7:0] decoder ;
always @(addr)
begin
case(addr)
3'b000 : decoder = 8'b1111_1110 ;
3'b001 : decoder = 8'b1111_1101 ;
3'b010 : decoder = 8'b1111_1011 ;
3'b011 : decoder = 8'b1111_0111 ;
3'b100 : decoder = 8'b1110_1111 ;
3'b101 : decoder = 8'b1101_1111 ;
3'b110 : decoder = 8'b1011_1111 ;
3'b111 : decoder = 8'b0111_1111 ;
endcase
end
endmodule
3.10 三态门
module top(en, din, dout, bio) ;
input din ;
input en ;
output dout ;
inout bio ;
assign bio = en? din : 1'bz ;
assign dout = bio ;
endmodule
4 时序逻辑
4.1 D触发器
module top(d, clk, q) ;
input d ;
input clk ;
output reg q ;
always @(posedge clk)
begin
q <= d ;
end
endmodule
4.2 两级D触发器
module top(d, clk, q, q1) ;
input d ;
input clk ;
output reg q ;
output reg q1 ;
always @(posedge clk)
begin
q <= d ;
end
always @(posedge clk)
begin
q1 <= q ;
end
endmodule
4.3 带异步复位的D触发器
module top(d, rst, clk, q) ;
input d ;
input rst ;
input clk ;
output reg q ;
always @(posedge clk or negedge rst)
begin
if (rst == 1'b0)
q <= 0 ;
else
q <= d ;
end
endmodule
4.4 带异步复位同步清零的 D 触发器
module top(d, rst, clr, clk, q) ;
input d ;
input rst ;
input clr ;
input clk ;
output reg q ;
always @(posedge clk or negedge rst)
begin
if (rst == 1'b0)
q <= 0 ;
else if (clr == 1'b1)
q <= 0 ;
else
q <= d ;
end
endmodule
4.5 移位寄存器
module top(d, rst, clk, q) ;
input d ;
input rst ;
input clk ;
output reg [7:0] q ;
always @(posedge clk or negedge rst)
begin
if (rst == 1'b0)
q <= 0 ;
else
q <= {q[6:0], d} ; //向左移位
//q <= {d, q[7:1]} ; //向右移位
end
endmodule
4.6 单口RAM
写地址与读地址公用一个地址,延迟一周将数据送出。
module top
(
input [7:0] data,
input [5:0] addr,
input wr,
input clk,
output [7:0] q
);
reg [7:0] ram[63:0]; //declare ram
reg [5:0] addr_reg; //addr register
always @ (posedge clk)
begin
if (wr) //write
ram[addr] <= data;
addr_reg <= addr;
end
assign q = ram[addr_reg]; //read data
endmodule
4.7 伪双口RAM
读写地址独立,可以随机选择写或读地址,同时进行读写操作。
module top
(
input [7:0] data,
input [5:0] write_addr,
input [5:0] read_addr,
input wr,
input rd,
input clk,
output reg [7:0] q
);
reg [7:0] ram[63:0]; //declare ram
reg [5:0] addr_reg; //addr register
always @ (posedge clk)
begin
if (wr) //write
ram[write_addr] <= data;
if (rd) //read
q <= ram[read_addr];
end
endmodule
4.8 真双口RAM
具有两套控制线,允许两个系统对其进行读写操作。
module top
(
input [7:0] data_a, data_b,
input [5:0] addr_a, addr_b,
input wr_a, wr_b,
input rd_a, rd_b,
input clk,
output reg [7:0] q_a, q_b
);
reg [7:0] ram[63:0]; //declare ram
//Port A
always @ (posedge clk)
begin
if (wr_a) //write
begin
ram[addr_a] <= data_a;
q_a <= data_a ;
end
if (rd_a)
//read
q_a <= ram[addr_a];
end
//Port B
always @ (posedge clk)
begin
if (wr_b) //write
begin
ram[addr_b] <= data_b;
q_b <= data_b ;
end
if (rd_b)
//read
q_b <= ram[addr_b];
end
endmodule
4.9 单口ROM
ROM用来存储数据,可以使用下面的代码进行对ROM的初始化,推荐使用FPGA现成的IP核实现。
module top
(
input [3:0] addr,
input clk,
output reg [7:0] q
);
reg [7:0] rom [15:0] ; //declare rom
always @(addr)
begin
case(addr)
4'd0 : rom[addr] = 8'd15 ;
4'd1 : rom[addr] = 8'd24 ;
4'd2 : rom[addr] = 8'd100 ;
4'd3 : rom[addr] = 8'd78 ;
4'd4 : rom[addr] = 8'd98 ;
4'd5 : rom[addr] = 8'd105 ;
4'd6 : rom[addr] = 8'd86 ;
4'd7 : rom[addr] = 8'd254 ;
4'd8 : rom[addr] = 8'd76 ;
4'd9 : rom[addr] = 8'd35 ;
4'd10 : rom[addr] = 8'd120 ;
4'd11 : rom[addr] = 8'd85 ;
4'd12 : rom[addr] = 8'd37 ;
4'd13 : rom[addr] = 8'd19 ;
4'd14 : rom[addr] = 8'd22 ;
4'd15 : rom[addr] = 8'd67 ;
endcase
end
always @(posedge clk)
begin
q <= rom[addr] ;
end
endmodule
4.10 有限状态机
4.10.1 Mealy型有限状态机
输出和当前状态和以及输入信号有关。
module top
(
input shift_start,
input shift_stop,
input rst,
input clk,
input d,
output reg [7:0] q
);
parameter Idle = 2'd0 ; //Idle state
parameter Start = 2'd1 ; //Start state
parameter Run = 2'd2 ; //Run state
parameter Stop = 2'd3 ; //Stop state
reg [1:0] state ; //statement
reg [4:0] delay_cnt ; //delay counter
always @(posedge clk or negedge rst)
begin
if (!rst)
begin
state <= Idle ;
delay_cnt <= 0 ;
q <= 0 ;
end
else
case(state)
Idle : begin
if (shift_start)
state <= Start ;
end
Start : begin
if (delay_cnt == 5'd99)
begin
delay_cnt <= 0 ;
state <= Run ;
end
else
delay_cnt <= delay_cnt + 1'b1 ;
end
Run : begin
if (shift_stop)
state <= Stop ;
else
q <= {q[6:0], d} ;
end
Stop : begin
q <= 0 ;
state <= Idle ;
end
default: state <= Idle ;
endcase
end
endmodule
4.10.2 Moore型有限状态机
Moore 有限状态机,输出只与当前状态有关,与输入信号无关,输入信号只影响状态的改变, 不影响输出。
module top
(
input shift_start,
input shift_stop,
input rst,
input clk,
input d,
output reg [7:0] q
);
parameter Idle = 2'd0 ; //Idle state
parameter Start = 2'd1 ; //Start state
parameter Run = 2'd2 ; //Run state
parameter Stop = 2'd3 ; //Stop state
reg [1:0] current_state ; //statement
reg [1:0] next_state ;
reg [4:0] delay_cnt ; //delay counter
//First part: statement transition
always @(posedge clk or negedge rst)
begin
if (!rst)
current_state <= Idle ;
else
current_state <= next_state ;
end
//Second part: combination logic, judge statement transition condition
always @(*)
begin
case(current_state)
Idle : begin
if (shift_start)
next_state <= Start ;
else
next_state <= Idle ;
end
Start : begin
if (delay_cnt == 5'd99)
next_state <= Run ;
else
next_state <= Start ;
end
Run : begin
if (shift_stop)
next_state <= Stop ;
else
next_state <= Run ;
end
Stop : next_state <= Idle ;
default: next_state <= Idle ;
endcase
end
//Last part: output data
always @(posedge clk or negedge rst)
begin
if (!rst)
delay_cnt <= 0 ;
else if (current_state == Start)
delay_cnt <= delay_cnt + 1'b1 ;
else
delay_cnt <= 0 ;
end
always @(posedge clk or negedge rst)
begin
if (!rst)
q <= 0 ;
else if (current_state == Run)
q <= {q[6:0], d} ;
else
q <= 0 ;
end
endmodule
Comments NOTHING