重温一下大道至简的至简设计法,正式开发两年多回顾当时的设计方法,又有了更多的体会和感触,希望将模块化运用起来会更有条例。
1 FPGA设计代码模板
c
信号命名规范:
1 clk 表示时钟信号小写
2 rstn 表示高电平复位信号 小写
3 rst_n 表示低电平复位信号 小写
4 模块的命名:将模块英文名称的各个单词首字母组合起来,形成3到5个单词,首字母大写
5 参数、宏定义,必须大写
1.1 计数器模板
cpp
always@(posedge clk or negedge rst_n) begin
if(rst_n == 1'b0) cnt <= 'd0;
else if(add_cnt) begin
if(end_cnt) cnt <= 'd0;
else cnt <= cnt + 1'b1;
end
end
这一段计数器模板可以完全套用,需要改变的是add_cnt 和 end_cnt 的值
c
assign add_cnt = a == 2;
assign end_cnt = add_cnt && cnt == 10-1;
1.2 状态机模板
我们采用四段式状态机
第一段:同步时序的always模块,格式化描述次状态迁移到现状态寄存器
c
always@(posedge clk or negedge rst_n) begin
if(!rst_n) state_c <= IDLE;
else state_c <= state_n;
end
第二段,组合逻辑always块,描述状态转移条件判断
c
always@(*) begin
case(state_c)
IDLE:begin
if(idle2s1_start) state_n = S1;
else state_n = state_c;
end
S1: begin
if(s12s2_start) state_n = S2;
else state_n = state_c;
end
S2: begin
if(s22idle_start) state_n = IDLE;
else state_n = state_c;
end
default: state_n = IDLE;
end case;
end
第三段:前两段可以模板拿来即用,这一段需要自己根据项目需要来设定;
c
assign idle2s1_start = (state_c == IDLE) && (XX);
assign s12s2_start = (state_c == S1) && (XX);
assign s22idle_start = (state_c == S2) && (XX);
第四段:也是根据实际项目需要来设定
c
always@(posedge clk or negedge rst_n) begin
if(!rst_n) out1 <= 1'b0;
else if(state_c == S1) out1 <= 1'b1;
else out1 <= 1'b0;
end