测试平台: 产生待测模块的全部输入信号 从输出信号接收结果 测试平台只能用于仿真,不能变成真正的硬件电路。 测试文件不属于芯片工程,不要添加进芯片工程!
测试文件——仿真时间定义 定义格式:
`timescale BAS_TIME_UNIT/TIME_ACUR
`timescale :时间尺度预编译指令
BAS_TIME_UNIT :仿真基本时间单位 1、10、100(s、ms、us、ns、ps)
TIME_ACUR
BAS_TIME_UNIT >= TIME_ACUR
e.g. `timescale 1ns/100ps
测试文件———代码主体结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 `timescale BAS_TIME_UNIT/TIME_ACUR module TEST_NAME; reg IN_TES_SIG_1; reg IN_TES_SIG_2; ...... wire OUT_TEST_SIG_1; wire OUT_TEST_SIG_2; ..... MDU_NAME INST_NAME ( .IN_MDU_SIG_1 (IN_TEST_SIG_1); .IN_MDU_SIG_2 (IN_TEST_SIG_2); .OUT_TEST_SIG_1 (OUT_TEST_SIG_1); .OUT_TEST_SIG_2 (OUT_TEST_SIG_2); )endmodule
产生输入信号——时钟 显式赋值/隐式赋值
产生输入信号——复位 必备信号
产生输入信号——数据 每个时钟周期,产生一位数据
可综合设计原则和方法 1.信号赋值 阻塞赋值 = 串行赋值 非阻塞赋值 <= 并行赋值
组合逻辑电路赋值
1 2 3 4 5 6 7 8 9 assign SIG_1 = SIG_2 + SIG_3always @(SIG_1 or SIG_2 or SIG_3)begin SIG_4 = SIG_1 & SIG_2 & SIG_3;end
时序逻辑电路赋值 只能用always非阻塞赋值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 always @( posedge clk or posedge rst )always @( posedge clk) always @( negedge clk)always @( posedge clk or negedge rst_n)always @( negedge clk or posedge rst ) always @( negedge clk or negedge rst_n)always @( posedge clk or negedge rst_n) begin if ( !rst_n) REG_1 <= 1'b0 ; else REG_1 <= SIG_1 & SIG_2 & SIG_3; end always @(posedge clk) begin if ( !rst_n) REG_1 <= 1'b0 ; else REG_1 <= SIG_1 & SIG_2 & SIG_3;end
2.信号初始化
以下的寄存器初始化方法不属于可综合设计:
1 2 3 4 5 6 7 initial begin SIG_1 = 1'b0 ;end always @( posedge clk) beginSIG_3 <= SIG_1 & SIG_2;end
以上代码的本意是在时钟信号上升沿的控制下,将SIG_1信号和SIG2信号连续逻辑相 与,再连接到SIG_3信号。代码中没有设计复位功能,却使用initial结构对SIG_1信号进行初始化,不符合可综合设计原则。由于initial结构属于仿真语法,在编译过程中会被绝大多数综合工具忽略,事实上无法达到对SIG1信号可靠初始化的目的,最终导致SIG_3信号也可能一直处于不定态,无法获得正确的值。若要完成SIG_1信号的可靠初始化,必须在代码中设计复位信号,在电路复位期间初始化SIG_1信号。实现上述效果的正确代码如下:
1 2 3 4 5 6 7 always @( posedge clk or negedge rst _n)begin if (!rst_n) SIG1<=1'b0 ; else SIG_3<= SIG_1 & SIG _2;end
3.信号延时
以下的延时设计方法不属于可综合设计:
1 2 3 4 5 6 7 8 9 'timescale 1 ns/1 nsalways @(posedge clk or negedge rst_n)begin if ( !rst_n ) SIG_11'b0; else SIG_1 <=#20 SIG_2;end
以上代码的本意是将信号SIG_2延迟2个时钟周期(测试平台中设定1个时钟周期为10 纳秒)后,连接到信号SIG_1,但是经过综合工具编译后,“#20”会被忽略,实际上无 法实现延时的效果。时序逻辑的可综合延时设计,通常是使需要延时的信号通过移位寄存器,获得的延时由移位寄存器的级数(深度)决定。移位寄存器有几级深度,就能使信号延迟几个时钟周期,这种以时钟周期为单位的延时方法在时序逻辑设计中最为常见。按照可综合设计原则,实现上述延时效果的正确代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 always @( posedge clk or negedge rst_n)begin if (!rst_n) begin REG[0 ]<=1'b0 ; REG[1 ]<=1'b0 ; end else begin REG[1 ]<=SIG_2; REG[0 ]<=REG[1 ]; end end assignSIG_1=REG[0 ];
4.组合逻辑条件判断 可综合设计原则 只使用”if..elseif…else”和”case”两种语法结构实现组合逻辑的条件分支判断,且不允许独立的”if”条件(缺失”else”)或独立的”case”条件(缺失”default”)存在。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 always @(*)begin if (en=2'b00 .) SIG_1=SIG_2; else if (en==2'b01 ) SIG_1= SIG_3; else if (en== 2'b10 ) SIG_1= SIG_4; else SIG_1=1'b0 ;end always @(*)begin case (en) 2'b00 :SIG_1=SIG_2; 2'b01 :SIG_1= SIG_3; 2'b10 :SIG_1=SIG_4; efault:SIG_1=1'b0 ; endcase end
5.循环结构时序展开
在综合过程中,会被开发工具按照循环最大次数,复制为同样数目完全重复的单次执行电路结构,造成电路规模庞大,导致不必要的芯片资源消耗。这并不符合可综合设计旨在设计可靠高效芯片电路的目的,因此也被设计业界认为不符合可综合设计原则。 例如:以下循环结构不属于可综合设计。
1 2 3 4 for (i=5'b0_0000 ;i<=5'b1_1111 ;i++)begin i=i+5'b0_0001 ;end
以上循环结构控制信号i(定义为5位宽二进制)的值递增,共循环32次。在综合过 程中,开发工具会从这一结构中提取出”i=i+5’b0_0001”综合为一个单次执行电路结 构,然后将这一结构复制32次并进行级联串接。当循环次数过大时,这种循环结构会占用大量芯片资源。为解决上述问题,常用的方法是将循环结构展开,用时序逻辑控制:
1 2 3 4 5 6 7 always @( posedge clk or negedge rst _n)begin if ( !rst_n) i<=5'b0_0000 ; else if (i<=5'b11111 ) i<=i+5 b0_001:end