diff --git a/_config.next.yml b/_config.next.yml
index 84ef79f..4210738 100644
--- a/_config.next.yml
+++ b/_config.next.yml
@@ -66,8 +66,8 @@ creative_commons:
license: by-nc-sa
# Available values: big | small
size: small
- sidebar: true
- post: false
+ sidebar: false
+ post: true
# You can set a language value if you prefer a translated version of CC license, e.g. deed.zh
# CC licenses are available in 39 languages, you can find the specific and correct abbreviation you need on https://creativecommons.org
language: deed.zh
@@ -402,7 +402,7 @@ bookmark:
color: "#222"
# If auto, save the reading progress when closing the page or clicking the bookmark-icon.
# If manual, only save it by clicking the bookmark-icon.
- save: auto
+ save: manual
# `Follow me on GitHub` banner in the top-right corner.
github_banner:
diff --git a/_config.yml b/_config.yml
index 4cebe73..45f925a 100644
--- a/_config.yml
+++ b/_config.yml
@@ -110,6 +110,9 @@ deploy:
- type: git
repo: josh@101.43.227.73:/home/josh/documents/josh-blog-deploy.git
branch: master
+ - type: git
+ repo: josh@172.245.154.153:/home/josh/documents/josh-blog.git
+ branch: master
- type: git
repo: git@e.coding.net:josh-gao/josh-blog/josh-blog.git
branch: master
@@ -192,4 +195,16 @@ neat_js:
- '**/*.min.js'
- '**/jquery.fancybox.pack.js'
- '**/index.js'
- - '**/fireworks.js'
\ No newline at end of file
+ - '**/fireworks.js'
+
+related_posts:
+ enabled: true
+ filter_threshold: 0.1
+ related_count: 5
+ weight:
+ title: 0.1
+ description: 0.05
+ keywords: 0.01
+ tags: 0.005
+ categories: 0.005
+ text: 1
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index faab5c0..8357c98 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,6 +21,7 @@
"hexo-helper-live2d": "^3.1.1",
"hexo-neat": "^1.0.9",
"hexo-related-popular-posts": "^5.0.1",
+ "hexo-related-posts": "^1.5.1",
"hexo-renderer-ejs": "^2.0.0",
"hexo-renderer-pandoc": "^0.3.1",
"hexo-renderer-stylus": "^2.1.0",
@@ -96,6 +97,15 @@
"node": ">=0.4.0"
}
},
+ "node_modules/afinn-165": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/afinn-165/-/afinn-165-1.0.4.tgz",
+ "integrity": "sha512-7+Wlx3BImrK0HiG6y3lU4xX7SpBPSSu8T9iguPMlaueRFxjbYwAQrp9lqZUuFikqKbd/en8lVREILvP2J80uJA==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz",
@@ -223,6 +233,17 @@
"node": ">= 8"
}
},
+ "node_modules/apparatus": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/apparatus/-/apparatus-0.0.10.tgz",
+ "integrity": "sha512-KLy/ugo33KZA7nugtQ7O0E1c8kQ52N3IvD/XgIh4w/Nr28ypfkwDfA67F1ev4N1m5D+BOk1+b2dEJDfpj/VvZg==",
+ "dependencies": {
+ "sylvester": ">= 0.0.8"
+ },
+ "engines": {
+ "node": ">=0.2.6"
+ }
+ },
"node_modules/aproba": {
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/aproba/-/aproba-1.2.0.tgz",
@@ -4433,6 +4454,18 @@
"node": ">=0.10.0"
}
},
+ "node_modules/hexo-related-posts": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/hexo-related-posts/-/hexo-related-posts-1.5.1.tgz",
+ "integrity": "sha512-KeNGQXcfsDKGyP66wiUVlcqguMyBn0n9tsFE5CftxhD9jiOrCmsqCibY1Aq8w/9f92+uxl+NlNkFhkrLezRFVg==",
+ "dependencies": {
+ "natural": "^2.1.5"
+ },
+ "peerDependencies": {
+ "chalk": "^4.1.0",
+ "hexo": "^4.2.0 || ^5.2.0 || ^6.3.0"
+ }
+ },
"node_modules/hexo-renderer-ejs": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/hexo-renderer-ejs/-/hexo-renderer-ejs-2.0.0.tgz",
@@ -5909,6 +5942,17 @@
"resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
},
+ "node_modules/json-stable-stringify": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz",
+ "integrity": "sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==",
+ "dependencies": {
+ "jsonify": "^0.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmmirror.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
@@ -5925,6 +5969,14 @@
"node": ">=6"
}
},
+ "node_modules/jsonify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz",
+ "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/jsonparse": {
"version": "1.3.1",
"resolved": "https://registry.npmmirror.com/jsonparse/-/jsonparse-1.3.1.tgz",
@@ -6782,6 +6834,22 @@
"node": ">=0.10.0"
}
},
+ "node_modules/natural": {
+ "version": "2.4.5",
+ "resolved": "https://registry.npmjs.org/natural/-/natural-2.4.5.tgz",
+ "integrity": "sha512-fxQou4ubo6Rzf7XL0jjwtC2vHm6Sdicu7ztcE0k1ODZs+d1UzcKF1Hu2IwE2y7OgzU3Sa9o8obw7rnyNrjsd1A==",
+ "dependencies": {
+ "afinn-165": "^1.0.2",
+ "apparatus": "^0.0.10",
+ "json-stable-stringify": "^1.0.1",
+ "sylvester": "^0.0.12",
+ "underscore": "^1.9.1",
+ "wordnet-db": "^3.1.11"
+ },
+ "engines": {
+ "node": ">=0.4.10"
+ }
+ },
"node_modules/ncp": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/ncp/-/ncp-2.0.0.tgz",
@@ -9206,6 +9274,14 @@
"node": ">= 0.4"
}
},
+ "node_modules/sylvester": {
+ "version": "0.0.12",
+ "resolved": "https://registry.npmjs.org/sylvester/-/sylvester-0.0.12.tgz",
+ "integrity": "sha512-SzRP5LQ6Ts2G5NyAa/jg16s8e3R7rfdFjizy1zeoecYWw+nGL+YA1xZvW/+iJmidBGSdLkuvdwTYEyJEb+EiUw==",
+ "engines": {
+ "node": ">=0.2.6"
+ }
+ },
"node_modules/symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmmirror.com/symbol-tree/-/symbol-tree-3.2.4.tgz",
@@ -9519,6 +9595,11 @@
"node": ">=0.8.0"
}
},
+ "node_modules/underscore": {
+ "version": "1.13.6",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
+ "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A=="
+ },
"node_modules/union-value": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/union-value/-/union-value-1.0.1.tgz",
@@ -9954,6 +10035,14 @@
"node": ">=0.10.0"
}
},
+ "node_modules/wordnet-db": {
+ "version": "3.1.14",
+ "resolved": "https://registry.npmjs.org/wordnet-db/-/wordnet-db-3.1.14.tgz",
+ "integrity": "sha512-zVyFsvE+mq9MCmwXUWHIcpfbrHHClZWZiVOzKSxNJruIcFn2RbY55zkhiAMMxM8zCVSmtNiViq8FsAZSFpMYag==",
+ "engines": {
+ "node": ">=0.6.0"
+ }
+ },
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
diff --git a/package.json b/package.json
index 725b3cf..4015b24 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
"hexo-helper-live2d": "^3.1.1",
"hexo-neat": "^1.0.9",
"hexo-related-popular-posts": "^5.0.1",
+ "hexo-related-posts": "^1.5.1",
"hexo-renderer-ejs": "^2.0.0",
"hexo-renderer-pandoc": "^0.3.1",
"hexo-renderer-stylus": "^2.1.0",
diff --git a/source/_posts/2020-11-25-matlab-rcosdesign.md b/source/_posts/2020-11-25-matlab-rcosdesign.md
index ac6f17e..67b92c7 100644
--- a/source/_posts/2020-11-25-matlab-rcosdesign.md
+++ b/source/_posts/2020-11-25-matlab-rcosdesign.md
@@ -3,19 +3,18 @@ title: MATLAB 函数 —— rcosdesign
tags:
- MATLAB
- 翻译
- - 成型滤波器
+ - 成形滤波器
- 滤波器
categories:
- - - MATLAB
- - - 翻译
- - 帮助文档
+ - [MATLAB, 函数用法]
mathjax: true
copyright: true
+comments: true
abbrlink: 5c45edfe
date: 2020-11-25 22:32:42
---
-`rcosdesign`:升余弦 FIR 脉冲成型滤波器设计
+`rcosdesign`:升余弦 FIR 脉冲成形滤波器设计
# 语法
@@ -32,18 +31,18 @@ date: 2020-11-25 22:32:42
# 示例
-## 设计根升余弦滤波器
+## 设计根升余弦滤波器
将滚降系数设为 `0.25`,波器的符号数设为 `6`,每个符号 `4` 个采样点。验证 `sqrt` 是 `shape` 参数的默认值。
-```m
+``` matlab
h = rcosdesign(0.25,6,4);
mx = max(abs(h-rcosdesign(0.25,6,4,'sqrt')))
```
> mx = 0
-```m
+``` matlab
fvtool(h,'Analysis','impulse')
```
@@ -51,13 +50,13 @@ fvtool(h,'Analysis','impulse')
-## 升余弦和根升余弦滤波器的脉冲响应
+## 升余弦和根升余弦滤波器的脉冲响应
-将升余弦滤波器与根升余弦滤波器进行比较。一个理想的(无限长)升余弦脉冲成型滤波器等效于两个级联的理想的根升余弦滤波器。因此,FIR 升余弦滤波器的脉冲响应应类似于与其自身卷积的根升余弦滤波器的脉冲响应。
+将升余弦滤波器与根升余弦滤波器进行比较。一个理想的(无限长)升余弦脉冲成形滤波器等效于两个级联的理想的根升余弦滤波器。因此,FIR 升余弦滤波器的脉冲响应应类似于与其自身卷积的根升余弦滤波器的脉冲响应。
设计一个衰减为 `0.25` 的升余弦滤波器。指定滤波器有 `4` 个符号,每个符号 `3` 个采样点。
-```m
+``` matlab
rf = 0.25;
span = 4;
sps = 3;
@@ -72,7 +71,7 @@ fvtool(h1,'impulse')
**升余弦滤波器在 `sps` 的整数倍处具有零值点**。因此,它满足无码间串扰(ISI)的 Nyquist 准则。但是,根升余弦滤波器没有这样的特性:
-```m
+``` matlab
h2 = rcosdesign(rf,span,sps,'sqrt');
fvtool(h2,'impulse')
```
@@ -83,7 +82,7 @@ fvtool(h2,'impulse')
将根升余弦滤波器与自身进行卷积。在最大值处截断脉冲响应,使其长度与 `h1` 相同。使用最大值将响应归一化。然后,将卷积后的根升余弦滤波器与升余弦滤波器进行比较。
-```m
+``` matlab
h3 = conv(h2,h2);
p2 = ceil(length(h3)/2);
m2 = ceil(p2-length(h1)/2);
@@ -102,13 +101,13 @@ legend('h1','h2 * h2')
卷积响应的长度是有限的,因此根升余弦滤波器与自身进行卷积得到的结果会与升余弦滤波器不一致。增加 `span` 可以在响应之间获得更紧密的一致性,并更好地符合 Nyquist 准则。
-## 将信号通过升余弦滤波器
+## 将信号通过升余弦滤波器
本例说明如何将信号通过根升余弦滤波器。
指定滤波器参数。
-```m
+``` matlab
rolloff = 0.25; % 滚降因子
span = 6; % 滤波器宽度(符号数)
sps = 4; % 每个符号的样本数
@@ -116,31 +115,31 @@ sps = 4; % 每个符号的样本数
生成根升余弦滤波器的系数。
-```m
+``` matlab
b = rcosdesign(rolloff, span, sps);
```
生成双极性数据向量。
-```m
+``` matlab
d = 2*randi([0 1], 100, 1) - 1;
```
-上采样并对数据进行滤波以实现脉冲成型。
+上采样并对数据进行滤波以实现脉冲成形。
-```m
+``` matlab
x = upfirdn(d, b, sps);
```
添加噪声。
-```m
+``` matlab
r = x + randn(size(x))*0.01;
```
对接收到的信号进行滤波和下采样以进行匹配滤波。
-```m
+``` matlab
y = upfirdn(r, b, 1, sps);
```
@@ -196,6 +195,10 @@ y = upfirdn(r, b, 1, sps);
>>
>> 所有输入必须为常数。 如果表达式或变量的值不变,则也允许使用。
+# 版本历史
+
+在 R2013b 中推出
+
# 另请参阅
[`gaussdesign`](https://ww2.mathworks.cn/help/signal/ref/gaussdesign.html)
@@ -204,10 +207,4 @@ y = upfirdn(r, b, 1, sps);
[用 RRC 滤波器进行插值和抽取](https://ww2.mathworks.cn/help/comm/ug/interpolate-and-decimate-using-rrc-filter.html)(Communications Toolbox)
-----
-
-在 R2013b 中推出
-
-----
-
-原文参考:[https://ww2.mathworks.cn/help/signal/ref/rcosdesign.html](https://ww2.mathworks.cn/help/signal/ref/rcosdesign.html)
\ No newline at end of file
+> 原文参考:[https://ww2.mathworks.cn/help/signal/ref/rcosdesign.html](https://ww2.mathworks.cn/help/signal/ref/rcosdesign.html)
diff --git a/source/_posts/2020-11-26-matlab-gaussdesign.md b/source/_posts/2020-11-26-matlab-gaussdesign.md
index 3cbe459..d645618 100644
--- a/source/_posts/2020-11-26-matlab-gaussdesign.md
+++ b/source/_posts/2020-11-26-matlab-gaussdesign.md
@@ -3,19 +3,18 @@ title: MATLAB 函数 —— gaussdesign
tags:
- MATLAB
- 翻译
- - 成型滤波器
+ - 成形滤波器
- 滤波器
categories:
- - - MATLAB
- - - 翻译
- - 帮助文档
+ - [MATLAB, 函数用法]
mathjax: true
copyright: true
+comments: true
abbrlink: a2967b00
date: 2020-11-26 15:56:26
---
-`gaussdesign`:高斯 FIR 脉冲成型滤波器设计
+`gaussdesign`:高斯 FIR 脉冲成形滤波器设计
# 语法
@@ -25,15 +24,15 @@ date: 2020-11-26 15:56:26
# 说明
-`h = gaussdesign(bt,span,sps)` 设计一个低通 FIR 高斯脉冲成型滤波器,并返回滤波器系数向量 `h`。滤波器有 `span` 个符号,每个符号包含 `sps` 个样本。滤波器的阶次,也即 `sps * span` 必须是偶数。[举例](#Examples-01)
+`h = gaussdesign(bt,span,sps)` 设计一个低通 FIR 高斯脉冲成形滤波器,并返回滤波器系数向量 `h`。滤波器有 `span` 个符号,每个符号包含 `sps` 个样本。滤波器的阶次,也即 `sps * span` 必须是偶数。[举例](#Examples-01)
# 示例
-## GSM GMSK 数字蜂窝通信系统的高斯滤波器
+## GSM GMSK 数字蜂窝通信系统的高斯滤波器
指定用于传输比特位的调制是高斯最小频移键控(GMSK)脉冲。此脉冲的 3-dB 带宽等于比特率的 `0.3` 倍,滤波器的符号数为 `4`,每个符号 `8` 个采样点。
-```m
+``` matlab
bt = 0.3;
span = 4;
sps = 8;
@@ -69,7 +68,7 @@ fvtool(h,'impulse')
## `h` - FIR 滤波器系数
-高斯脉冲成型滤波器的 FIR 系数,以**行向量**的形式返回。系数已被归一化,因此标称通带增益始终为 1。
+高斯脉冲成形滤波器的 FIR 系数,以**行向量**的形式返回。系数已被归一化,因此标称通带增益始终为 1。
**数据类型**:`double` | `single`
@@ -79,14 +78,12 @@ fvtool(h,'impulse')
[2] Rappaport, Theodore S. *Wireless Communications: Principles and Practice.* 2nd Ed. Upper Saddle River, NJ: Prentice Hall, 2002.
+# 版本历史
+
+在 R2013b 中推出
+
# 另请参阅
[`rcosdesign`](https://ww2.mathworks.cn/help/signal/ref/rcosdesign.html)
----
-
-在 R2013b 中推出
-
----
-
-原文参考:[https://ww2.mathworks.cn/help/signal/ref/gaussdesign.html](https://ww2.mathworks.cn/help/signal/ref/gaussdesign.html)
\ No newline at end of file
+原文参考:[https://ww2.mathworks.cn/help/signal/ref/gaussdesign.html](https://ww2.mathworks.cn/help/signal/ref/gaussdesign.html)
diff --git a/source/_posts/2020-11-26-matlab-upsample-spt.md b/source/_posts/2020-11-26-matlab-upsample-spt.md
index e791935..f992839 100644
--- a/source/_posts/2020-11-26-matlab-upsample-spt.md
+++ b/source/_posts/2020-11-26-matlab-upsample-spt.md
@@ -5,14 +5,14 @@ tags:
- 翻译
- 上采样
categories:
- - - MATLAB
- - - 翻译
- - 帮助文档
+ - [MATLAB, 函数用法]
mathjax: true
copyright: true
+comments: true
abbrlink: 3a606c9c
date: 2020-11-26 22:23:39
---
+
`upsample`:将采样率提高整数倍
# 语法
@@ -30,16 +30,16 @@ date: 2020-11-26 22:23:39
# 示例
-## 提高采样率
+## 提高采样率
将序列的采样率提高 `3` 倍。
-```m
+``` matlab 输入
x = [1 2 3 4];
y = upsample(x,3)
```
-```no
+``` plain 输出
y = 1×12
1 0 0 2 0 0 3 0 0 4 0 0
@@ -47,12 +47,12 @@ y = 1×12
将序列的采样率增加 `3` 倍,并将相位偏移增加 `2`。
-```m
+``` matlab 输入
x = [1 2 3 4];
y = upsample(x,3,2)
```
-```no
+``` plain 输出
y = 1×12
0 0 1 0 0 2 0 0 3 0 0 4 0
@@ -60,14 +60,14 @@ y = 1×12
将矩阵的采样率提高3倍。
-```m
+``` matlab 输入
x = [1 2;
3 4;
5 6];
y = upsample(x,3)
```
-```no
+``` plain 输出
y = 9×2
1 2
@@ -115,12 +115,12 @@ y = 9×2
> 使用 MATLAB® Coder™ 生成 C 代码和 C++ 代码。
+# 版本历史
+
+在 R2006a 之前推出
+
# 另请参阅
[`decimate`](https://ww2.mathworks.cn/help/signal/ref/decimate.html) | [`downsample`](https://ww2.mathworks.cn/help/signal/ref/downsample.html) | [`interp`](https://ww2.mathworks.cn/help/signal/ref/interp.html) | [`interp1`](https://ww2.mathworks.cn/help/matlab/ref/interp1.html) | [`resample`](https://ww2.mathworks.cn/help/signal/ref/resample.html) | [`spline`](https://ww2.mathworks.cn/help/matlab/ref/spline.html) | [`upfirdn`](https://ww2.mathworks.cn/help/signal/ref/upfirdn.html)
---------------------------------------------------------------------------------
-在 R2006a 之前推出
-
---------------------------------------------------------------------------------
-原文参考:[https://ww2.mathworks.cn/help/signal/ref/upsample.html](https://ww2.mathworks.cn/help/signal/ref/upsample.html)
\ No newline at end of file
+> 原文参考:[https://ww2.mathworks.cn/help/signal/ref/upsample.html](https://ww2.mathworks.cn/help/signal/ref/upsample.html)
diff --git a/source/_posts/2020-11-27-hexo-next-busuanzi-issues.md b/source/_posts/2020-11-27-hexo-next-busuanzi-issues.md
index 0f50ef1..e3ad466 100644
--- a/source/_posts/2020-11-27-hexo-next-busuanzi-issues.md
+++ b/source/_posts/2020-11-27-hexo-next-busuanzi-issues.md
@@ -5,8 +5,10 @@ tags:
- Hexo
- Next
categories:
- - [Blog, Hexo, Next]
+ - [Blog, Hexo]
abbrlink: e96c9b26
+copyright: true
+comments: true
date: 2020-11-27 11:15:21
---
diff --git a/source/_posts/2020-11-27-josh-verilog-part-1.md b/source/_posts/2020-11-27-josh-verilog-part-1.md
index b51744e..052f6d3 100644
--- a/source/_posts/2020-11-27-josh-verilog-part-1.md
+++ b/source/_posts/2020-11-27-josh-verilog-part-1.md
@@ -8,13 +8,11 @@ tags:
- 行为级
- RTL
- 寄存器传输级
-categories:
- - [Verilog, Verilog 简介]
+categories:
- [Josh 的学习笔记, Verilog]
mathjax: true
comments: true
copyright: true
-sticky: false
toc:
enable: true
number: false
diff --git a/source/_posts/2020-11-27-matlab-awgn.md b/source/_posts/2020-11-27-matlab-awgn.md
index fff44e0..d8ed371 100644
--- a/source/_posts/2020-11-27-matlab-awgn.md
+++ b/source/_posts/2020-11-27-matlab-awgn.md
@@ -5,13 +5,11 @@ tags:
- 翻译
- 高斯白噪声
categories:
- - - MATLAB
- - - 翻译
- - 帮助文档
- - - 信号处理
- - 噪声
+ - [MATLAB, 函数用法]
+ - [信号处理, 噪声]
mathjax: true
copyright: true
+comments: true
abbrlink: 2f6db45b
date: 2020-11-27 01:15:12
---
@@ -49,14 +47,14 @@ date: 2020-11-27 01:15:12
创建一个锯齿波。
-```m
+``` matlab
t = (0:0.1:10)';
x = sawtooth(t);
```
添加高斯白噪声并绘制结果。
-```m
+``` matlab
y = awgn(x,10,'measured');
plot(t,[x y])
legend('Original Signal','Signal with AWGN')
@@ -72,32 +70,32 @@ legend('Original Signal','Signal with AWGN')
根据电话线调制解调器的 V.29 标准创建一个 16-QAM 星座。
-```m
+``` matlab
c = [-5 -5i 5 5i -3 -3-3i -3i 3-3i 3 3+3i 3i -3+3i -1 -1i 1 1i];
M = length(c);
```
生成随机符号。
-```m
+``` matlab
data = randi([0 M-1],2000,1);
```
使用 `genqammod` 函数调制数据。由于星座图不是矩形,因此必须进行常规 QAM 调制。
-```m
+``` matlab
modData = genqammod(data,c);
```
使信号通过具有 20 dB 信噪比(SNR)的 AWGN 信道。
-```m
+``` matlab
rxSig = awgn(modData,20,'measured');
```
显示接收信号的星座图和参考星座图。
-```m
+``` matlab
h = scatterplot(rxSig);
hold on
scatterplot(c,[],[],'r*',h)
@@ -111,25 +109,25 @@ hold off
使用 `genqamdemod` 函数解调接收到的信号。计算误符号数和误符号率。
-```m
+``` matlab 输入
demodData = genqamdemod(rxSig,c);
[numErrors,ser] = symerr(data,demodData)
```
-```no
+``` plain 输出
numErrors = 1
ser = 5.0000e-04
```
使用具有 10 dB SNR 的 AWGN 信道重复传输和解调过程。计算降低 SNR 后的误符号率。不出所料,当 SNR 降低时,性能会下降。
-```m
+``` matlab 输入
rxSig = awgn(modData,10,'measured');
demodData = genqamdemod(rxSig,c);
[numErrors,ser] = symerr(data,demodData)
```
-```no
+``` plain 输出
numErrors = 462
ser = 0.2310
```
@@ -140,7 +138,7 @@ ser = 0.2310
将 X 的功率指定为 0 dBW,添加噪声以产生 10 dB 的 SNR,并利用本地随机流。
-```m
+``` matlab 输入
S = RandStream('mt19937ar','Seed',5489);
sigin = sqrt(2)*sin(0:pi/8:6*pi);
sigout1 = awgn(sigin,10,0,S);
@@ -148,25 +146,25 @@ sigout1 = awgn(sigin,10,0,S);
将 AWGN 添加到 `sigin`。 使用 [`isequal`](https://ww2.mathworks.cn/help/matlab/ref/isequal.html) 比较 `sigout1` 和 `sigout2`。 当不重置随机流时,输出不相等。
-```m
+``` matlab 输入
sigout2 = awgn(sigin,10,0,S);
isequal(sigout1,sigout2)
```
-```no
+``` plain 输出
ans = logical
0
```
重置随机流对象,将对象置为初始状态,然后再将 AWGN 添加到 `sigout1`。将 AWGN 添加到 `sigin` 并将 `sigout1` 与 `sigout3` 比较。 重置随机流后,输出相等。
-```m
+``` matlab 输入
reset(S);
sigout3 = awgn(sigin,10,0,S);
isequal(sigout1,sigout3)
```
-```no
+``` plain 输出
ans = logical
1
```
@@ -260,6 +258,10 @@ ans = logical
>>
>> 支持代码生成,但包括 [`RandStream`](https://ww2.mathworks.cn/help/matlab/ref/randstream.html) 对象的语法除外。
+# 版本历史
+
+在 R2006a 之前推出
+
# 另请参阅
## 函数
@@ -274,8 +276,4 @@ ans = logical
[AWGN Channel Noise Level](https://ww2.mathworks.cn/help/comm/ug/awgn-channel.html#a1071501088)
---------------------------------------------------------------------------------
-在 R2006a 之前推出
-
---------------------------------------------------------------------------------
-原文参考:[https://ww2.mathworks.cn/help/comm/ref/awgn.html](https://ww2.mathworks.cn/help/comm/ref/awgn.html)
\ No newline at end of file
+原文参考:[https://ww2.mathworks.cn/help/comm/ref/awgn.html](https://ww2.mathworks.cn/help/comm/ref/awgn.html)
diff --git a/source/_posts/2020-11-28-josh-verilog-part-2.md b/source/_posts/2020-11-28-josh-verilog-part-2.md
index 050f9f1..0b43649 100644
--- a/source/_posts/2020-11-28-josh-verilog-part-2.md
+++ b/source/_posts/2020-11-28-josh-verilog-part-2.md
@@ -8,7 +8,6 @@ tags:
- 自底向上
- Verilog 语法
categories:
- - [Verilog, Verilog 语法]
- [Josh 的学习笔记, Verilog]
mathjax: true
comments: true
@@ -63,7 +62,7 @@ EDA 行业的先行者们发明了 Verilog 硬件描述语言,其最根本的
**这些电路单元都是同时并行工作的,相互之间并没有先后顺序关系,这一点与软件设计程序很不一样。**
-下面具体分析 [JoshVerilog 模块](#JoshVerilog模块)的电路功能。源代码如下。
+下面具体分析 [JoshVerilog 模块](#JoshVerilog模块) 的电路功能。源代码如下。
@@ -260,7 +259,7 @@ reg eq3;
module 模块名称( 端口列表 );
// 声明:
reg, parameter,
- input, output,
+ input, output,
function, task, ...
// 语句:
initial 语句
@@ -288,7 +287,7 @@ input [1:0] A_in;
模块内部使用的 `reg`(寄存器类型的一种)、`wire`(线网类型的一种)、参数、函数以及任务等,都将在 `module` 中声明。
-一般来说,`module` 的
+一般来说,`module` 的
- `input` 默认定义为 `wire` 类型;
- `output` 信号可以是 `wire`,也可以是 `reg` 类型(如果在 `always` 或 `initial` 语句块中被赋值);
@@ -499,9 +498,9 @@ Message = "HeIIo World";
### 7.2.1 `reg` 类型
1. 寄存器类型数
-
+
`reg` 类型可以定位为一个寄存器,可以定义一位或者多位,例如:
-
+
```verilog
reg AB; // 定义一个名为 AB 的 1 位寄存器
reg [3:0] ABC; // 定义一个名为 ABC 的 4 位寄存器
@@ -516,9 +515,9 @@ Message = "HeIIo World";
```
这样,整个 `ABC` 变量的值为 `4'b1010`。
-
+
2. 寄存器类型数组
-
+
`reg` 类型可以作为二维数组,也就是存储器,例如:
```verilog
@@ -532,7 +531,7 @@ Message = "HeIIo World";
```
同时,在 Verilog 中,不存可以对整个存储器赋值的语句,必须对每个单元独立赋值。除非使用 `$readmemb` 或 `$readmemh` 系统任务从文件中读入整个或者部分存储器的数据。
-
+
[comment]: <> (在第7章将讨论如何从文件中读入数据给存储器赋值。)
### 7.2.2. `integer` 类型
diff --git a/source/_posts/2020-11-30-josh-verilog-part-3.md b/source/_posts/2020-11-30-josh-verilog-part-3.md
index 55b7d54..a0ed34b 100644
--- a/source/_posts/2020-11-30-josh-verilog-part-3.md
+++ b/source/_posts/2020-11-30-josh-verilog-part-3.md
@@ -8,7 +8,6 @@ tags:
- 设计层次
- Verilog 语法
categories:
- - [Verilog, Verilog 设计]
- [Josh 的学习笔记, Verilog]
mathjax: true
comments: true
@@ -64,23 +63,23 @@ assign #1 A_xor_wire = eq0 ^ eq1;
### 2.2.1. 连续赋值语句的特点
1. **连续驱动**
-
+
在 [Part 2 的 7.2 驱动和赋值](https://josh-gao.top/posts/fd2ca242.html#%E5%AF%84%E5%AD%98%E5%99%A8%E7%B1%BB%E5%9E%8B)部分,已经解释了驱动和赋值之间的微妙区别。
-
+
连续赋值语句是连续驱动的。也就是说,任何时刻输入的任何变化都将导致该语句的重新计算。
2. **只有线网类型能在 `assign` 中赋值**
-
+
由于仿真器中不会存储连续赋值语句中被赋值的变量值,因此该变量是线网类型(Net),不能是寄存器类型。需要记住,只有线网类型的变量才可以在 `assign` 语句中被赋值。
-
+
另外,线网类型的变量可以被多重驱动,也就是说,可以在多个连续赋值语句中驱动同一个线网。在[2.4 驱动源线网](#drive)中将进一步介绍。但是,寄存器变量就不同了,它不能被不同的行为进程(例如 `always` 语句块)驱动。
-
+
3. **使用 `assign` 对组合逻辑建模**
-
+
通常建议使用 `assign` 对组合逻辑建模。因为 `assign` 语句的连续驱动特点与组合逻辑的行为非常相似。而且,在 `assign` 语句中加延时可以非常精确的模拟组合逻辑的惯性延时。
4. **并行性**
-
+
`assign` 语句和行为语句块(`always` 和 `initial`)、其他连续赋值语句、门级模型之间是并行的。一个连续赋值语句是一个独立的进程,进程之间是并发,同时也是交织的。
### 2.2.2. 实例
@@ -105,7 +104,7 @@ output C_out;
assign sum = X ^ Y;
assign C_out = X & Y;
-endmodule
+endmodule
```
```verilog FullAdd.v
@@ -131,15 +130,15 @@ HalfAdd u_HalfAdd_A(
.s (HalfAdd_A_sum),
.C_out (HalfAdd_A_Cout)
);
-
+
HalfAdd u_HalfAdd_B(
.X (C_in),
.Y (HalfAdd_A_sum),
.s (sum),
.C_out (HalfAdd_B_Cout)
);
-
-endmodule
+
+endmodule
```
在 `HalfAdd` 模块中,两个 `assign` 语句之间是**完全并行独立执行**的,它们的顺序与逻辑功能无关。同样,`FullAdd` 模块中,两个 `HalfAdd` 的实例和或门的 `assign` 语句之间的关系也是独立的。
@@ -329,7 +328,7 @@ always // 每 5ns 将 clk 翻转一次
下面的代码描述了语句组和高级编程语句的互相嵌套:
```verilog
-always @(posedge clk or negedge rst_n)
+always @(posedge clk or negedge rst_n)
begin // 语句组
if (~rst_n) // 高级编程语句
begin // 语句组
@@ -605,7 +604,7 @@ end
always @(negedge clk)
Q = D;
-
+
endmodule
```
@@ -873,18 +872,18 @@ endcase
循环语句后面可以跟语句或语句组(`begin ... end` 或 `fork ... join`)。
1. `forever` 循环:永远执行
-
+
```verilog
initial begin
clk = 0;
forever #25 clk = ~clk;
end
```
-
+
以上语句产生了一个周期为 50 个时间单位的时钟。
2. `repeat` 循环:执行固定的次数
-
+
```verilog
if (rotate == 1)
repeat (8)
@@ -893,11 +892,11 @@ endcase
data = {data<<1, temp};
end
```
-
+
以上语句中,当为 1 时,重复对 `data` 数据做8次循环左移。
3. `while` 循环:当表达式为真时执行
-
+
```verilog
initial begin
count = 0;
@@ -907,11 +906,11 @@ endcase
end
end
```
-
+
在 `while` 语句中,只要后面的条件满足,就持续执行该语句,直到条件不满足,跳出循环。这里,将 `count` 从 0 递增到 101,逐步打印出来。
4. `for` 循环:从初始值开始,如果表达式为真就执行
-
+
```verilog
integer i; // 为 for 循环声明索引
always @(inp or cnt) begin
@@ -924,7 +923,7 @@ endcase
end
end
```
-
+
`for` 语句开始执行直到 `i` 大于 7,跳出循环。如上代码实现了一个位的左移器。
简单介绍了 Verilog 中的高级编程语句,只要对 C 语言有一定基础,就能迅速掌握其中的用法。
@@ -948,7 +947,7 @@ output C_out;
xor u_xor(sum, X, Y); // 门级原语实例
and u_and(C_out, X, Y); // 门级原语实例
-endmodule
+endmodule
```
```verilog FullAdd.v
@@ -973,15 +972,15 @@ HalfAdd u_HalfAdd_A( // 半加器实例 A
.sum (HalfAdd_A_sum),
.C_out (HalfAdd_A_Cout)
);
-
+
HalfAdd u_HalfAdd_B( // 半加器实例 B
.X (C_in),
.Y (HalfAdd_A_sum),
.sum (sum),
.C_out (HalfAdd_B_Cout)
);
-
-endmodule
+
+endmodule
```
上例已将[原半加器代码](#半加器代码)中的语句改为门原语的实例化。在全加器的模块中,有两个半加器模块的实例和一个 `or` 门原语的实例。
@@ -1157,7 +1156,7 @@ defparam
altsyncram_component.widthad_a = 5, // 5 位地址
altsyncram_component.width_a = 8, // 8 位宽的数据
altsyncram_component.width_byteena_a = 1;
-
+
endmodule
```
@@ -1362,7 +1361,7 @@ output C_out;
xor u_xor(sum, X, Y); // 门级原语实例
and u_and(C_out, X, Y); // 门级原语实例
-endmodule
+endmodule
```
其中直接调用了 `xor` 和 `and` 的两个 Verilog 门原语。
diff --git a/source/_posts/2020-12-02-josh-verilog-part-4.md b/source/_posts/2020-12-02-josh-verilog-part-4.md
index 340e9a5..22b50c4 100644
--- a/source/_posts/2020-12-02-josh-verilog-part-4.md
+++ b/source/_posts/2020-12-02-josh-verilog-part-4.md
@@ -21,7 +21,6 @@ tags:
- 异步复位
- 条件语句
categories:
- - [Verilog]
- [Josh 的学习笔记, Verilog]
abbrlink: ecb88422
date: 2020-12-02 01:05:32
@@ -54,15 +53,15 @@ RTL 级语言的最重要特性就是:{% label primary @RTL 级描述是可综
典型的 RTL 设计包含以下3个部分:
1. 时钟域描述
-
+
描述设计所使用的所有时钟,时钟之间的主从与派生关系,时钟域之间的转换。
2. 时序逻辑描述(寄存器描述)
-
+
根据时钟沿的变换,描述寄存器之间的数据传输方式。
3. 组合逻辑描述
-
+
描述电平敏感信号的逻辑组合方式与逻辑功能。
RTL 描述中时序逻辑和组合逻辑的连接关系和拓扑结构决定了设计的性能,如何调整时序逻辑、组合逻辑的连接关系和拓扑结构以达到最佳的性能就是后面讨论的编码风格(Coding Style)的核心。
@@ -70,11 +69,11 @@ RTL 描述中时序逻辑和组合逻辑的连接关系和拓扑结构决定了
工程师们设计 RTL 级代码的顺序各种各样,推荐使用如下的设计步骤:
1. **功能定义与模块划分**
-
+
根据系统功能的定义和模块划分准则(详见Part 5 第 4 节)划分各个功能模块。
2. **定义所有模炔的接口**
-
+
首先清晰定义每个模块的接口,完成每个模块的信号列表。这种思路也和 Modular Design(模块化设计方法)一致,利于模块重用、调试、修改。
3. **设计的时钟域**
@@ -88,7 +87,7 @@ RTL 描述中时序逻辑和组合逻辑的连接关系和拓扑结构决定了
关键路径是指设计中时序要求最难以满足的路径。设计的时序要求主要体现在频率、建立时间、保持时间等时序指标上。在设计初期,设计者可以根据系统的频率要求,粗略地分析出设计的时序难点(如最高频率的路径,计数器的最低位,包含复杂组合逻辑的时序路径等),通过一些时序优化手段(如 Pipeline、Retiming、逻辑复制等,这些时序优化手段在 Part 5 第 7 节有详细介绍)**从代码上缓解设计的时序压力**,这种方法比单依靠综合与布局布线工具的自动优化有效得多。
5. **顶层设计**
-
+
常用的设计方法有两种,一种是自顶而下的设计方法,即先描述设计的顶层,然后描述设计的每个子模块;另一种是由底向上的设计方法,即首先描述设计的子模块,最后定义设计的顶层。RTL 设计推荐使用自顶而下的设计方法,因为这种设计方法与模块规划的顺序一致,而且更利于进行 Modular Design(模块化设计方法),并行开展设计工作,提高模块重用率。
6. **FSM 设计**
@@ -100,7 +99,7 @@ RTL 描述中时序逻辑和组合逻辑的连接关系和拓扑结构决定了
首先根据时钟域规划好寄存器组,然后描述各个寄存器组之间的数据传输方式。
8. **组合逻辑设计**
-
+
一般来说,**大段的组合逻辑最好与时序逻辑分开描述**,这样更利于时序约束和时序分析,使综合器和布局布线器达到更好的优化效果。
# 3. 常用 RTL 级建模
@@ -110,66 +109,66 @@ RTL 描述中时序逻辑和组合逻辑的连接关系和拓扑结构决定了
有很多文章论述阻塞赋值和非阻塞赋值的概念,[《Part 3 —— 描述方式和设计层次》的 3.2 小节](https://josh-gao.top/posts/fd117896.html#3-2-%E8%BF%87%E7%A8%8B%E8%B5%8B%E5%80%BC%E8%AF%AD%E5%8F%A5)详细讨论了因不当使用阻塞赋值和非阻塞赋值引起的仿真与设计意图不一致。为了避免不当使用阻塞賦值和非阻塞赋值而造成的种种歧义和错误,这里推荐:
1. **对于时序逻辑,即 `always` 模块的敏感表为{% label primary @沿敏感信号 %}(多为时钟或复位的正沿或负沿),统一使用非阻塞賦值 `<=`**。例如:
-
+
```verilog // cnt1.v
/******************************
时序逻辑中使用非阻塞赋值。
******************************/
-
+
module cnt1 (clock, cnt_out);
-
+
input clock;
output [3:0] cnt_out;
-
+
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
reg [3:0] cnt_out;
always @(posedge clock)
cnt_out <= cnt_out + 1;
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
-
+
endmodule
```
2. **对于 `always` 模块的敏感表为{% label primary @电平敏感 %}信号的组合逻辑,统一使用阻塞賦值**。例如:
-
+
```verilog cnt2.v
/******************************
always 模块的敏感表为电平敏感信号的组合逻辑, 使用阻塞赋值。请注意, 此例
"cnt_out_plus"虽然被指定为 reg 型, 但是实现时是纯组合逻辑。
******************************/
-
+
module cnt2 (cnt_out, cnt_out_plus);
-
+
input [3:0] cnt_out;
output [3:0] cnt_out_plus;
-
+
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
reg [3:0] cnt_out_plus;
always @(cnt_out)
cnt_out_plus = cnt_out + 1;
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
-
+
endmodule
```
3. **对于 `assign` 关键字描述的{% label primary @组合逻辑 %},称为连续赋值语句,统一使用 `=`,变量被定义为 `wire` 型信号**。例如:
-
+
```verilog cnt3.v
/******************************
assign 描述的组合逻辑。"cnt_out_plus"被定义为 wire 型信号。
******************************/
module cnt3 (cnt_out, cnt_out_plus);
-
+
input [3:0] cnt_out;
output [3:0] cnt_out_plus;
-
+
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
wire [3:0] cnt_out_plus;
assign cnt_out_plus = cnt_out + 1;
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
-
+
endmodule
```
@@ -197,35 +196,35 @@ RTL 描述中时序逻辑和组合逻辑的连接关系和拓扑结构决定了
******************************/
module cnt4 (clock, cnt_out);
-
+
input clock;
output [3:0] cnt_out;
-
+
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
reg [3:0] cnt_out;
always @(negedge clock)
cnt_out <= cnt_out + 1;
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
-
+
endmodule
```
3. **异步复位/置位**:绝大多数目标器件的寄存器模型都包含异步复位/置位端。异步复位/置位是指无论时钟沿是否有效,当复位/置位信号有效沿到达时,复位/置位立即发挥功能。指定异步复位/置位时,**只需在 `always` 的敏感表中加入复位/置位信号的有效沿即可**。下例描述的异步复位电路是最常用的寄存器复位形式之一。
-
+
```verilog
/******************************
最常用的异步复位电路, 设异步复位信号"reset_"是低有效信号(也即下降沿开始复位)。用户可
以在 begin/end 结构之间填入复杂的用户逻辑。
******************************/
-
+
// reg_counter.v
module reg_counter (clock, reset_, cnt_reg_s, cnt_reg_a);
-
+
input clock;
input reset_;
output [3:0] cnt_reg_s;
output [3:0] cnt_reg_a;
-
+
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
reg [3:0] cnt_reg_s; //asynchronous reset
always @(posedge clock or negedge reset_)
@@ -236,7 +235,7 @@ RTL 描述中时序逻辑和组合逻辑的连接关系和拓扑结构决定了
cnt_reg_s [3] <= ~cnt_reg_s [3];
end
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
-
+
reg [3:0] cnt_reg_a; //synchronous reset
always @(posedge clock)
if (!reset_)
@@ -245,25 +244,25 @@ RTL 描述中时序逻辑和组合逻辑的连接关系和拓扑结构决定了
cnt_reg_a [2:0] <= cnt_reg_a [2:0] + 1;
cnt_reg_a [3] <= ~cnt_reg_a [3];
end
-
+
endmodule
```
4. **同步复位/置位**:任何寄存器都可实现同步复位/置位功能。指定同步复位/置位时,**`always` 的敏感表中仅有时钟沿信号**,当同步复位/置位信号变化时,同步复位/置位并不立即发生,仅仅当时钟沿采到同步复位/置位的有效电平时,才会在时钟沿到达时刻进行复位/置位操作。
-
+
```verilog reg_counter.v
/******************************
- 常用的同步复位电路, 设异步复位信号"reset_"是低电平有效信号。请比较上例, 对比 always
+ 常用的同步复位电路, 设异步复位信号"reset_"是低电平有效信号。请比较上例, 对比 always
的敏感表。
******************************/
-
+
module reg_counter (clock, reset_, cnt_reg_s, cnt_reg_a);
-
+
input clock;
input reset_;
output [3:0] cnt_reg_s;
output [3:0] cnt_reg_a;
-
+
reg [3:0] cnt_reg_s; //asynchronous reset
always @ (posedge clock or negedge reset_)
if (!reset_)
@@ -272,7 +271,7 @@ RTL 描述中时序逻辑和组合逻辑的连接关系和拓扑结构决定了
cnt_reg_s [2:0] <= cnt_reg_s [2:0] + 1;
cnt_reg_s [3] <= ~cnt_reg_s [3];
end
-
+
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
reg [3:0] cnt_reg_a; //synchronous reset
always @ (posedge clock)
@@ -283,24 +282,24 @@ RTL 描述中时序逻辑和组合逻辑的连接关系和拓扑结构决定了
cnt_reg_a [3] <= ~cnt_reg_a [3];
end
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
-
+
endmodule
```
> 关于同步复位和异步复位的优缺点,在 [3.9 小节](#0309) 有详细介绍。
5. **同时使用时钟上升和下降沿的问题**:有时因为数据采样或调整数据相位等需求,设计者会在一个 `always` 的敏感表中同时使用时钟的 `posedge` 和 `negedge`,或者在两个 `always` 的敏感表中分别使用时钟的 `posedge` 和 `negedge` 对某些寄存器电路操作。在这两种描述下,当时钟上沿或下沿到达时,该寄存器电路都会做相应的操作。**这个双沿电路往往可以等同于使用了原时钟的倍频时钟的单沿操作电路**。对于实现在 PLD 的设计而言,同时使用时钟的上、下沿往往是不推荐的,因为 PLD 内嵌的 PLL/DLL 和一些时钟电路往往只能对时钟的一个沿保证非常好的指标,而另个沿的抖动、偏斜、斜率等指标不见得非常优化,有时同时使用时钟的正负沿会因时钟的抖动、偏斜、占空比、斜率等问题造成一定的性能恶化。因此推荐的做法是:将原时钟通过 PLL/DLL 倍频,然后使用倍频时钟的单沿(如上升沿)进行操作。但是电路设计不可一概而论,如果必须使用时钟的双沿对同一个寄存器操作时,请设计者明确此时相当于使用了倍频时钟。
-
+
```verilog clock_edge.v
/******************************
某电路使用 50MHz 时钟双沿操作相当于使用同相位 100MHz 倍频时钟操作。
******************************/
-
+
module clock_edge (clk_50M, clk_100M, rst_, cnt1, cnt2);
-
+
input clk_50M, clk_100M, rst_;
output [3:0] cnt1, cnt2;
-
+
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
reg [3:0] cnt_temp1, cnt_temp2;
wire [3:0] cnt1;
@@ -309,45 +308,45 @@ RTL 描述中时序逻辑和组合逻辑的连接关系和拓扑结构决定了
cnt_temp1 <= 4'b0000;
else
cnt_temp1 <= cnt_temp2 + 1;
-
+
always @(negedge clk_50M or negedge rst_ )
if (!rst_)
cnt_temp2 <= 4'b0000;
else
cnt_temp2 <= cnt_temp1 + 1;
-
+
assign cnt1 = (clk_50M)? cnt_temp2 : cnt_temp1;
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
-
+
reg [3:0] cnt2;
always @(posedge clk_100M or negedge rst_ )
if (!rst_)
cnt2 <= 4'b0000;
else
cnt2 <= cnt2 + 1;
-
+
endmodule
```
-
+
这里相当于使用与 50MHz 时钟 `clk_50M` 同相位的 2 倍频时钟 `cIk_100M` 进行累加计算,等效描述如下:
-
+
```verilog
reg [3:0] cnt2;
-
+
always @(posedge clk_100M or negedge rst_ )
if (!rst_)
cnt2 <= 4'b0000;
else
cnt2 <= cnt2 + 1;
```
-
+
以上代码综合后,对应的电路结构如[图 4-1](#图4-1) 所示。
-
+