智能芯片与嵌入式系统笔记

文章发布时间:

最后更新时间:

页面浏览: 加载中...

测试平台:

产生待测模块的全部输入信号
从输出信号接收结果
测试平台只能用于仿真,不能变成真正的硬件电路。
测试文件不属于芯片工程,不要添加进芯片工程!

测试文件——仿真时间定义

定义格式:

`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 赋值 用加法器实现,只能用阻塞赋值
assign SIG_1 = SIG_2 + SIG_3

//always 赋值 必须使用阻塞赋值
always @(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赋值示例
always @( posedge clk or negedge rst_n) //时序逻辑异步复位赋值法
begin
if( !rst_n)//复位时
REG_1 <= 1'b0; //寄存器REG_1置初值
else //复位结束,电路开始工作
REG_1 <= SIG_1 & SIG_2 & SIG_3; //电路执行逻辑功能
end

always @(posedge clk) //时序逻辑同步复位赋值法
begin
if( !rst_n)//复位时
REG_1 <= 1'b0;//寄存器REG_1置初值
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 1ns/1ns
always @(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为2级深度的移位寄存器,此处进行初始化
REG[1]<=1'b0;
end
else
begin
REG[1]<=SIG_2;//延迟第1个时钟周期
REG[0]<=REG[1];//延迟第2个时钟周期
end
end
assignSIG_1=REG[0];//延迟2个时钟周期后的SIG_2信号连接到SIG_1信号

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.)//信号en的值(2位宽二进制)为00时
SIG_1=SIG_2;//信号SIG_1与SIG_2连接
else if(en==2'b01)//信号en的值为01时
SIG_1= SIG_3;//信号SIG_1与SIG_3连接
else if(en== 2'b10)//信号en的值为10时
SIG_1= SIG_4;//信号SIG1与SIG_4连接
else//信号en的值为11、高阻态、不定态时
SIG_1=1'b0;//信号SIG_1明确赋值(此例为低电平)
end
always @(*)
begin
case(en)//判断信号en的值(2位宽二进制)
2'b00:SIG_1=SIG_2;//值为00时,信号SIG_1与SIG_2连接
2'b01:SIG_1= SIG_3;//值为01时,信号SIG1与SIG3连接
2'b10:SIG_1=SIG_4;//值为10时,信号SIG_1与SIG_4连接
efault:SIG_1=1'b0;//值为11、高阻态、不定态时,信号SIG_1明确赋值
endcase
end

5.循环结构时序展开

在综合过程中,会被开发工具按照循环最大次数,复制为同样数目完全重复的单次执行电路结构,造成电路规模庞大,导致不必要的芯片资源消耗。这并不符合可综合设计旨在设计可靠高效芯片电路的目的,因此也被设计业界认为不符合可综合设计原则。
例如:以下循环结构不属于可综合设计。

1
2
3
4
for(i=5'b0_0000;i<=5'b1_1111;i++)//此处的“<="是小于等于人不是赋值
begin
i=i+5'b0_0001;//信号i的值递增,增量为1
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;//信号i的初值在复位期间获取
else if(i<=5'b11111)//信号i的变化上限(相当于循环最大次数)
i<=i+5b0_001://信号i的值递增,每个时钟周期增量为1
end