Hexo


  • Home

  • Archives

  • Tags

  • Search

8.16

Posted on 2018-08-16 | In 技术
Words count in article: 593 | Reading time ≈ 2

Verilog 的概念注意点

一.case语句

以前接触过case语句,知道case语句分为case,casex,以及casez三类,但是觉得一般用不到,就没怎么注意,可是因为这个导致程序出错就不得不注意了,在写一个外围测试元件的时候,写了以下语句:

1
2
3
4
5
casex(state)
13'b1_xxxx_xxxx_xxxx: {rom_sel,ram_sel}=2'b10;
13'b0_xxxx_xxxx_xxx1: {rom_sel,ram_sel}=2'b01;
default: {rom_sel,ram_sel}=2'b00;
endcase

这里,如果换成case,输出结果则与预期不符,casez用来处理不用考虑高阻值z的比较过程,casex用来处理既不用考虑高阻值z也不用考虑不定态x的情况,改成case,输出结果一般都是default的输出结果。

二.取反

Verilog有~和!两个符号,之前认为可以共用。的确,有的情况可以通用,但是有的情况不可以通用,比如,你定义一个一位变量,以及一个7位变量,将七位变量分别以上述两种符号取反并将所得结果赋值给上述定义的一位变量,对比结果可知(one代表!的输出结果,zero代表~的运算结果):

上述结果告诉我们:!除非你的值为00,否则该运算符的结果都为0; ~就看七位变量的最低位,将最低位取反为该运算符的结果;

三.常用的系统函数

为了更好的测试我们的代码,Verilog中有一些常用的系统函数,如$display 、$monitor、$strobe等等,其中:

1.$monitor表示连续监测变量,每当参数列表中的变量或者表达式的值发生变化时,整个参数列表中变量或者表达式的值都将输出显示;
2.$display,$strobe都表示打印输出结果,但区别是$strobe只在当前时刻结束才输出打印结果,而$display只要仿真器观测到变量就会打印输出结果;

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
26
27
28
`timescale 1ns/1ps

module test;

reg a,b;
initial

begin
#1 a=0;
b=1;
a<=b;
b<=a;

$write("$display");
$display("%b %b %b", $time, a, b);
$write("$strobe");
$strobe("%b %b %b", $time, a, b);
$write("$monitor");
$monitor("%b %b %b", $time, a, b);

#2 a=0;
b=1;
#3 a=1;
b=1;

end

endmodule

测试代码的结果:

点击下载

8.05

Posted on 2018-08-05 | In 行想(CQ)
Words count in article: 288 | Reading time ≈ 1

上海的一日半行

一.上海外滩

来这儿几日了,也没好好看看,今日有人陪着一起看看,还是挺惬意的,不过这惬意很快就被打破了,因为上海的夏天真的不是一般的热,而且它还巨晒,估计又会增上几缕黝黑的妆容了。下午6点多来到外滩,比之前来的时候,体验感差极了,因为人比之前多了许多,走路基本就是走一步,停一百步,东方明珠的整个四周全部围满了人,完全不留任何空袭,想拍照不可能的,总有很多人入境,下面是我的杰作。

———-



———-



———-



———-

不过说实话,景色还是挺奢华的!
### 一.上海学校
中午在上海的一所学校看了看,校园很大,依然很晒,不过有了交通工具-共享电车,还是有种雪中送碳的感觉,参观的学校,感觉校门都很严肃,而且风格迥异,总感觉哪里怪怪的,不过同行人倒逛的津津有味,拍的照片也被我顺手拿下。

———-


———-


———-


———-


8.03

Posted on 2018-08-03 | In 技术
Words count in article: 1,855 | Reading time ≈ 10

基于Modelsim的I2C CMOS串行的EEPROM读写操作
一.Modelsim软件
这个软件最大的好处就是速度快,与传统的EDA设计工具相比,最显著的特点就是速度快,为什么这么快呢,因为它只能作为仿真工具,无法综合,对于初级阶段的人来说,先来仿真也未尝不可;当然这个软件可以与许多大型的EDA设计工具配合使用,比较常用的就是Quartus设计软件。Modelsim软件的版本很多,如10.1C,10.2以及10.4等等,版本之间大同小异,具体的差异可以去了解一下,这个软件需要破解,破解过程并不复杂,但是我遇到一个非常坑的问题就是破解完成后,我编译文件并仿真文件,出现一个奇怪的问题:Verilog中的$display以及$monitor语句无法正常显示在Transcript窗口,我怀疑是不是破解不完全,于是重新装,重新破解,结果还是不行;我又怀疑是不是软件版本的问题,网上也有人说是版本导致的,于是我换了以上三个版本,结果仍然一样。后来我怀疑是不是电脑系统版本的问题,于是借用别人的Win7电脑,安装完一次,重新测试,所有问题都没有,顺便补充一下我的电脑系统是Win10版本的。


二.I2C协议
这个协议很简单,是个串口执行的,因此比较慢,需要两个线,一个时钟线SDL,一个数据线SDA,有启动,停止,数据有效段以及应答阶段,具体定义参考夏宇闻的第三版Verilog教程的P227页。明白了原理之后就可以写代码了,这里说明一点:控制字节以及EEPROM的存储地址发送成功之后都需要应答的,一定注意写和读两个示意图。


三.Verilog代码

当然我的代码也参考了别人的成果,这里感谢网上那些大神的开源,毕竟我比较菜。

源代码

    
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305

module I2C
(input clk,rst,RW_sig, //RW_sig =1 stands for reading
input [7:0]Addr_data,Write_data,
output SCL,
inout SDA,
input SDA_data,
output [7:0]Read_data,
output Isover // Isover=1 Stands for over
);

parameter clk_div=249;
reg [7:0]count;
reg [7:0]rRead_data;
reg [4:0]state1;
reg [4:0]state2;
reg rSDA;
reg rIsover;
reg rIOselect;
reg rSCL;
reg IsACK;// IsASK=0 Return=0 state

assign SDA=(rIOselect==1)? rSDA:1'bz;
assign Read_data=rRead_data;
assign SCL=rSCL;
assign Isover=rIsover;
//assign IOselect<=rIOselcet;
always @ (posedge clk or negedge rst)
if(!rst)
begin
count<=8'b0;
state1<=5'b0;
state2<=5'b0;
rRead_data<=8'b0;
rSCL<=1'b1;
rSDA<=1'b1;
rIsover<=1'b0;
rIOselect<=1'b1;
end
else if(!RW_sig)
begin
case(state1)
0: //Write start
begin
rIOselect<=1'b1;
if(count==0)
begin
rSCL<=1'b1;
rSDA<=1'b1;
end
if(count==100) rSDA<=0;
if(count==200) rSCL<=0;
if(count==clk_div)
begin
count<=8'b0;
state1<=state1+1'b1;
end
else
count<=count+1'b1;
end
1: // Device Address
begin
rRead_data<={4'b1010, 3'b000, 1'b0};
state1<=5'b00111;
state2<=state1+1'b1;
end
2: // EEPROM Address
begin
rRead_data<=Addr_data;
state1<=5'b00111;
state2<=state1+1'b1;
end
3: // Data
begin
rRead_data<=Write_data;
state1<=5'b00111;
state2<=state1+1'b1;
end
4: // Stop Start
begin
rIOselect<=1;
if(count==0)
begin
rSCL<=1'b1;
rSDA<=1'b0;
end
if(count==50)
begin
rSCL<=1'b1; //which can be ignored
rSDA<=1'b1;
end

if(count==clk_div)
begin
count<=8'b0000_0000;
state1<=state1+1'b1;
end
else
count<=count+1'b1;
end
5: //Stop
begin
rIsover<=1'b1;
state1<=state1+1'b1;
end
6:
begin
rIsover<=1'b0;
state1<=5'b00000;
end
7,8,9,10,11,12,13,14:
begin
if(count==0)
rSDA<=rRead_data[14-state1];
if(count==50)
rSCL<=1'b1;
if(count==150)
rSCL<=1'b0;
if(count==clk_div)
begin
count<=8'b0;
state1<=state1+1'b1;
end
else
count<=count+1'b1;
end

15:
begin
rIOselect<=0;
if(count==0)
begin
IsACK<=SDA_data;
state1<=state1+1'b1;
end
end
16:
begin
rIOselect<=1'b1;
if(!IsACK)
state1<=5'b00000;
else
state1<=state2;
end
endcase
end
else if(RW_sig) //READ DATA
begin
case(state1) //READ Start Firstly
0:
begin
rIOselect<=1'b1;
if(count==0)
begin
rSCL<=1;
rSDA<=1;
end
if(count==100) rSDA<=0;
if(count==200) rSCL<=0;
if(count==clk_div)
begin
count<=8'b0;
state1<=state1+1'b1;
end
else
count<=count+1'b1;
end
1: //Address write data
begin
rRead_data<={4'b1010, 3'b000, 1'b0};
state1<=5'b01000;
state2<=state1+1'b1;
end
2:
begin
rRead_data<=Addr_data;
state1<=5'b01000;
state2<=state1+1'b1;
end
3:
// READ Start Secondly
begin

rIOselect<=1'b1;
if(count==0)
begin
rSCL<=1;
rSDA<=1;
end
if(count==100) rSDA<=0;
if(count==200) rSCL<=0;
if(count==clk_div)
begin
count<=8'b0;
state1<=state1+1'b1;
state2<=state1+1'b1;
end
else
count<=count+1'b1;
end
4:
begin
rRead_data<={4'b1010, 3'b000, 1'b1};
state1<=5'b01000;
state2<=state1+1'b1;
end
5:
begin
rRead_data<=8'b0;
state1<=5'b10100;
state2<=state1+1'b1;
end
6: //Stop
begin
rIsover<=1'b1;
state1<=state1+1'b1;
end
7:
begin
rIsover<=1'b0;
state1<=5'b00000;
end

8,9,10,11,12,13,14,15:

begin
rIOselect<=1'b1;
if(count==0)
rSDA<=rRead_data[15-state1];
if(count==50)
rSCL<=1'b1;
if(count==150)
rSCL<=1'b0;
if(count==clk_div)
begin
count<=8'b0;
state1<=state1+1'b1;
end
else
count<=count+1'b1;
end


16:
begin
rIOselect<=0;
if(count==0)

IsACK<=rSDA;
end
17:
begin
if(!IsACK)
state1<=5'b00000;
else
state1<=state2;
end
20,21,22,23,24,25,26,27:
begin
rIOselect<=1'b0;
if(count==0)
rRead_data[27-state1] <= SDA;
if(count==50)
rSCL<=1'b1;
if(count==150)
rSCL<=1'b0;
if(count==clk_div)
begin
count<=8'b0;
state1<=state1+1'b1;
end
else
count<=count+1'b1;
end
28:
begin
rIOselect<=1'b1;
if(count==0)
begin
rSCL<=1;
rSDA<=1;
end
if(count==100) rSDA<=0;
if(count==200) rSCL<=0;

if(count==clk_div)
begin
count<=8'b0;
state1<=state2;
end

else
count<=count+1;

end
endcase
end
endmodule

//PS:注释写的太差了

```


### 测试代码
`timescale 1ns / 1ps module tbI2C; reg clk; reg rst; reg RW_sig; reg SDA_data; reg [7:0]Addr_data; reg [7:0]Write_data; wire SCL; wire SDA; wire Isover; wire [7:0]Read_data; I2C DT ( .clk(clk), .rst(rst), .RW_sig(RW_sig), .Addr_data(Addr_data), .Write_data(Write_data), .SCL(SCL), .SDA(SDA), .SDA_data(SDA_data), .Read_data(Read_data), .Isover(Isover) ); initial begin rst=1; clk=0; RW_sig=1'b0; Addr_data=8'b10101010; Write_data=8'b0000111; #2.5 rst=0; #5 rst=1; #4550 SDA_data=1'b1; end always #1 clk=~clk; endmodule ```
关于在testbench的阻塞与非阻塞语句的差别,具体看一下以下链接的文章
https://www.cnblogs.com/fkl523/p/4029467.html

下图就是EEPROM的写代码的测试结果



这个代码看似很长,其实读写重复部分很多,可以优化一下,还要说一下,仿真检验的testbench部分,我只验证了写的部分(RW_sig==0)的代码,读的代码没验证,我觉得出错的可能性非常大,有兴趣的可以继续完成验证。在验证写的过程中,因为定义的SDA为inout类型,双向端口,在testbench中只能声明为wire类型,可是在应答中,需要将SDA传输给IsACK,于是我增加了一个SDA_data作为传输向量,只是为了看完整的仿真结果。

7.22

Posted on 2018-07-22 | In 行想(CQ)
Words count in article: 140 | Reading time ≈ 1

杭州之行

紧赶慢赶坐上杭州的列车,途中发生太多的插曲,比如做公交做错站,到了站买不到票,不过万幸在本人的坚持下,还是顺利坐上开往杭州的G2715列车,虽然只待了一会儿,也感受到了杭州该感受到的东西,东坡肉,还有那个什么鱼,都还可以,也感受了类似中山大学的学校环境,挺好的,回来的时候,人太多,站在回来的火车上,表示很费劲儿。

7.2十

Posted on 2018-07-20 | In 技术
Words count in article: 253 | Reading time ≈ 1
Altium Design 15 间距
一.映射显示绿色
Altium Design 15 从原理图映射到PCB图上,可能会出现部分元件的管脚是绿色,放大之后绿色区域显示许多错号,如下图所示:

这个应该是间距规则设置错误的问题,具体说一下就是封装的间距设置小于等于布线规则里面的最小间距,布线规则里面的最小间距就是电气规则的 mix clearance,只有当规则的最小间距(clearance)大于封装的间距才不会报错,希望对你有所帮助。
二.敷铜显示绿色
如果敷铜显示绿色,网上有很多方案,你可以先试试我自己的一种:将Polygon Pour 管理器Track Width、Grid Size的数值与Design-rule-Routing-width保持一致,即如下界面显示:

如果有多层宽度,就以最大宽度为准。另外:一般线距(电气规则下的clearance)等于线宽(信号线宽)。

7.19

Posted on 2018-07-19 | In 行想(CQ)
Words count in article: 208 | Reading time ≈ 1

新学校的交通

学校太大,导致我的交通费用大大支出,你信不信吧,每天骑车都要2-3元,这还是加上走路,如果骑上大黄车,费用更高,生活已是如此艰难,为何还要为难我。
大黄车不得不说,骑着真给劲儿,骑上后,也不觉得热了,也不觉得晒了,风飕飕地从耳边呼过,想到一句歌词,好像是“我想……”原谅我只听歌不记歌词哈,说了这么久,给你们看一下大黄车:

这里还得夸一下我的手机,拍照逆天啊,美颜效果更是惊艳,就是感觉在我手里有点可惜,是不是咧。再给你们看一张第五食堂后面的湖泊,再次强调,只是随手一拍。

7.17

Posted on 2018-07-17 | In 行想(CQ)
Words count in article: 214 | Reading time ≈ 1

新环境的第一天

距离上次更新真的好久了,这期间发生了好多事,都毕业了,还是借此给大家说句毕业快乐。
7.16独自踏上新的征程,现实一般小于期望值,7.17我一个人搬着36斤的行李在校园里穿梭,俨然一道靓丽的风景,1.1公里,差点把我累死,而且阳光暴晒,新学校让我明白了大学自行车的重要性,其实最好买个电车,校园实在太大了,不过别有一番景致,桥啊,树啊,建筑啊,现代感很强,与我本科的学校形成了较大的反差,各有特色吧。
既然来了,只能慢慢去适应,你说是不是咧。
各位看官,新手机随手一拍,效果是不是很惊艳


4-20

Posted on 2018-04-20 | In 技术
Words count in article: 433 | Reading time ≈ 2

off grid polygon on layer Metal3 in Cadence

我用Cadence画完版图,结果显示几千个错误,下图所示的是经过我改正一些错误后的视图

错误还是很多,但是很多错误属于同类错误,之前画过一个简单的版图,遇到一些错误,所以有一点点经验,但是今天说一说开头显示的那些错误:
off grid polygon ……

这是格点导致的错误,解决问题办法,以下图为例,先点击快捷键E调出格点设置按钮:


重点留意Grid Controls那一栏,如果你的X Snap Spacing 和Y Snap Spacing 设置0.01的话,你的所有器件和布线,引脚等等的坐标精度都不可以超过0.01,比如(12.563,12.191)这个坐标就会报错,你可以改成(12.56,12.19),有人觉得那我直接把精度改成0.001,不久可以了,我试了一次,也会报错,理论上应该可以,有兴趣的同学可以继续研究一下,对了,要感谢原文作者,链接如下:
http://www.pittnuts.com/2015/07/a-quick-way-to-clear-drc-offgrid-warnings-in-calibre-and-assura/
有时候会遇到以下错误,不提示具体哪一层,只出现这个问题:

这个问题比较棘手,首先检查版图提示区有没有多余的金属线,然后修改坐标,确保坐标可以整除2,如2.24或者2.26,如果余0.005就会报错。
最后总结一下我的错误,可能是因为我在两个Cadence 环境下运行,两次修改版图时设置的space不一样导致的,如果出现,可以参考上述解决办法。


12345
Flying Pig

Flying Pig

Are you ok?

38 posts
4 categories
1 tags
© 2020 Flying Pig