├── .vscode
└── systemverilog.code-snippets
├── README.md
├── experiment
├── 01display
│ ├── Nexys4DDR_Master.xdc
│ ├── controller.sv
│ ├── display.bit
│ ├── sim.sv
│ ├── sources.tcl
│ └── top.sv
├── 02simulation
│ ├── decoder.sv
│ └── sim.sv
├── lab1
│ ├── Nexys4DDR_Master.xdc
│ ├── README.pdf
│ ├── ans.v
│ ├── display
│ │ ├── decoder2_4.sv
│ │ ├── encoder4_2.sv
│ │ └── priority_encoder4_2.sv
│ ├── lab1.sv
│ ├── myans.sv
│ ├── readme.md
│ ├── sim.sv
│ ├── sources.tcl
│ └── top.sv
├── lab2
│ ├── Nexys4DDR_Master.xdc
│ ├── ans.v
│ ├── decoder.sv
│ ├── display
│ │ └── lab2.drawio
│ ├── imem.sv
│ ├── lab2.sv
│ ├── lab2.svh
│ ├── myans.sv
│ ├── readme.md
│ ├── ref.svh
│ ├── sim.sv
│ ├── sources.tcl
│ └── top.sv
├── lab3
│ ├── Nexys4DDR_Master.xdc
│ ├── lab3 copy.sv
│ ├── lab3 加更.md
│ ├── lab3.sv
│ ├── sim.sv
│ ├── sources.tcl
│ └── top.sv
├── lab4
│ ├── 74LS138.pdf
│ ├── 74LS151.pdf
│ ├── Nexys4DDR_Master.xdc
│ ├── ans.sv
│ ├── lab4.md
│ ├── lab4.pdf
│ ├── lab4.sv
│ ├── lab4display.md
│ ├── sim.sv
│ ├── sources.tcl
│ └── top.sv
├── lab5
│ ├── 74LS194.pdf
│ ├── Nexys4DDR_Master.xdc
│ ├── asset
│ │ ├── circuit.jpg
│ │ ├── ff.jpg
│ │ ├── ff_reset.jpg
│ │ └── 微信图片_20201119201959.jpg
│ ├── clock_convert.sv
│ ├── display.md
│ ├── lab5.sv
│ ├── sim.sv
│ ├── sn74ls175.pdf
│ ├── sources.tcl
│ ├── submit.md
│ ├── top.sv
│ └── 实验五 提交.pdf
├── lab6
│ ├── Nexys4DDR_Master.xdc
│ ├── display.md
│ ├── lab6.md
│ ├── lab6.pdf
│ ├── lab6.sv
│ ├── lab6.svh
│ ├── sim.sv
│ ├── sources.tcl
│ └── top.sv
└── lab7
│ ├── 74LS377.pdf
│ ├── Nexys4DDR_Master.xdc
│ ├── lab7.md
│ ├── lab7.pdf
│ ├── lab7.sv
│ ├── ram2.sv
│ ├── sim.sv
│ ├── sources.tcl
│ └── top.sv
├── notes
├── 00引言
│ └── 00引言.md
├── 01开发流程(上)
│ ├── 01开发流程(上).md
│ ├── 01开发流程(上).pdf
│ └── assets
│ │ ├── account.PNG
│ │ ├── agree.PNG
│ │ ├── customize.PNG
│ │ ├── directory.PNG
│ │ ├── edition.PNG
│ │ ├── progress.PNG
│ │ ├── structure.PNG
│ │ └── summary.PNG
├── 02开发流程(中)
│ ├── 02开发流程(中).md
│ ├── 02开发流程(中).pdf
│ ├── assets
│ │ ├── board_files.PNG
│ │ ├── circuit.jpg
│ │ ├── default_board.PNG
│ │ └── default_part.PNG
│ └── board_files.zip
├── 03开发流程(下)
│ ├── 03开发流程(下).md
│ └── 03开发流程(下).pdf
├── lab1
│ ├── SV Syntax for lab1.md
│ └── display.md
├── systemverilog
│ ├── 1.jpg
│ ├── 2.jpg
│ ├── systemverilog语法简介.md
│ └── systemverilog语法简介.pdf
├── 实验一
│ ├── img
│ │ ├── decoder
│ │ └── encoder
│ ├── 实验一 译码器与编码器.md
│ └── 实验一 译码器与编码器.pdf
├── 实验三
│ └── 实验三 加法器及快速进位电路的设计.md
├── 实验二
│ ├── img_lab2
│ │ └── 身份证.jpg
│ ├── 实验二 译码与编码的应用.md
│ └── 实验二 译码与编码的应用.pdf
├── 实验五
│ └── 实验五 触发器和寄存器.md
├── 实验六
│ ├── light.jpg
│ └── 实验六 有限状态机_1.md
└── 实验四
│ └── 实验四 算数逻辑单元的设计.md
└── syntax
├── 10interface
└── interface.md
├── 1bits
├── bits.drawio
└── bits.md
├── 2oprators
└── oprator.md
├── 3assign
└── assign.md
├── 4module
└── module.md
├── 5always_comb
├── always_comb.md
├── case.md
└── if_for.md
├── 6always_ff
└── always_ff.md
├── 7typedef
└── typedef.md
├── 8parameter
└── parameter.md
└── 9precomplie
└── 预编译.md
/.vscode/systemverilog.code-snippets:
--------------------------------------------------------------------------------
1 | {
2 | // Place your experiment workspace snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
3 | // description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
4 | // is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
5 | // used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
6 | // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
7 | // Placeholders with the same ids are connected.
8 | // Example:
9 | // "Print to console": {
10 | // "scope": "javascript,typescript",
11 | // "prefix": "log",
12 | // "body": [
13 | // "console.log('$1');",
14 | // "$2"
15 | // ],
16 | // "description": "Log output to console"
17 | // }
18 | "module": {
19 | "prefix": "module",
20 | "body": [
21 | "module $1 (",
22 | "\t$0",
23 | ");",
24 | "endmodule\n"
25 | ]
26 | },
27 | "assign": {
28 | "prefix": "assign",
29 | "body": "assign $0 = "
30 | },
31 | "always_comb": {
32 | "prefix": "always_comb",
33 | "body": [
34 | "always_comb begin",
35 | "\t$0",
36 | "end\n"
37 | ]
38 | },
39 | "always_ff": {
40 | "prefix": "always_ff",
41 | "body": [
42 | "always_ff @(posedge clk) begin",
43 | "\t$0",
44 | "end\n"
45 | ]
46 | },
47 | "typedef": {
48 | "prefix": "typedef",
49 | "body": "typedef logic[$1:0] $0;\n"
50 | },
51 | "typedef struct packed": {
52 | "prefix": "typedef struct",
53 | "body": [
54 | "typedef struct packed {",
55 | "\t$0",
56 | "} $1;\n"
57 | ]
58 | },
59 | "typedef enum": {
60 | "prefix": "typedef enum",
61 | "body": [
62 | "typedef enum logic [$1] {",
63 | "\t$0",
64 | "} $2;\n"
65 | ]
66 | },
67 | "for_generate": {
68 | "prefix": "for",
69 | "body": [
70 | "for (genvar i = 0; i < $1; i++) begin",
71 | "\t$0",
72 | "end\n"
73 | ]
74 | },
75 | "for": {
76 | "prefix": "for",
77 | "body": [
78 | "for (int i = 0; i < $1; i++) begin",
79 | "\t$0",
80 | "end\n"
81 | ]
82 | },
83 | "unique case": {
84 | "prefix": "unique",
85 | "body": [
86 | "unique case($1)",
87 | "\t$0",
88 | "\tdefault: begin",
89 | "\t\t",
90 | "\tend",
91 | "endcase"
92 | ]
93 | },
94 | "priority case": {
95 | "prefix": "priority",
96 | "body": [
97 | "priority case(${1:1'b1})",
98 | "\t$0",
99 | "\tdefault: begin",
100 | "\t\t",
101 | "\tend",
102 | "endcase"
103 | ]
104 | }
105 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 复旦大学 数字逻辑与部件设计实验 2020秋
2 |
3 |
4 |
5 | 这是复旦大学2020秋季学期《数字逻辑与部件设计》实验部分的代码仓库。
6 |
7 |
8 |
9 | 本仓库包含以下几个目录:
10 |
11 | * `experiment` 是实验发布内容和参考实现。前几个实验是组合逻辑实验,我写了一个简单的测试框架:用 SystemVerilog 写出参考电路(模块名为`*ans*`),给出很多组测试输入,比较待测电路和参考电路的输出值。参考电路以 Vivado 生成的网表文件(`.v`后缀的文件)给出。如果需要阅读参考电路,请跳过所有 `.v` 后缀的文件。
12 |
13 | 发布包中有 Vivado 项目工程文件,用 Vivado 2018.3 打开。项目工程文件已选好实验板类型,添加好项目文件,只需在指定的源文件里写好电路即可开始 Simulation 与 Generate Bitstream。
14 |
15 | * `notes` 是实验文档的 markdown 源码。
16 |
17 | * `syntax` 是 SystemVerilog 常用语法的讲解,可配合我录的视频 [SystemVerilog常用语法简介](https://www.bilibili.com/video/BV1XA41177of) 来学习(部分实验也有视频讲解)。
18 |
19 | * `.vscode` 里有我使用的 SystemVerilog 代码 snippet,内容是部分语法的自动补全。在 Visual Studio Code 里编写 SystemVerilog 时,可以使用它。
20 |
21 |
--------------------------------------------------------------------------------
/experiment/01display/controller.sv:
--------------------------------------------------------------------------------
1 | module controller (
2 | input logic clk, resetn,
3 | input logic[7:0]sw,
4 | output logic [7:0][6:0]segs
5 | );
6 | logic one_clk;
7 | logic[32:0]cnt;
8 | always_ff @(posedge clk) begin
9 | if (~resetn) begin
10 | cnt <= '0;
11 | one_clk <= '0;
12 | end else begin
13 | cnt <= cnt + sw + 12;
14 | one_clk <= '0;
15 | if (cnt >= 32'd100_000_000) begin
16 | cnt <= '0;
17 | one_clk <= '1;
18 | end
19 | end
20 | end
21 | logic [6:0]state;
22 | always_ff @(posedge one_clk, negedge resetn) begin
23 | if (~resetn) begin
24 | state <= '0;
25 | end else begin
26 | state <= state + 1;
27 | if (state == 7'd98) begin
28 | state <= 7'd15;
29 | end
30 | end
31 | end
32 | mylut mylut(.state, .segs);
33 | endmodule
34 |
35 | module mylut (
36 | input logic [6:0] state,
37 | output logic[7:0][6:0]segs
38 | );
39 | always_comb begin
40 | segs = '1;
41 | unique case(state)
42 | 0: ;
43 | 1: {segs[0][0]} = '0;
44 | 2: {segs[1][0], segs[0][0]} = '0;
45 | 3: {segs[2][0], segs[1][0], segs[0][0]} = '0;
46 | 4: {segs[3][0], segs[2][0], segs[1][0], segs[0][0]} = '0;
47 | 5: {segs[4][0], segs[3][0], segs[2][0], segs[1][0], segs[0][0]} = '0;
48 | 6: {segs[5][0], segs[4][0], segs[3][0], segs[2][0], segs[1][0], segs[0][0]} = '0;
49 | 7: {segs[5][0], segs[4][0], segs[3][0], segs[2][0], segs[1][0], segs[6][0]} = '0;
50 | 8: {segs[5][0], segs[4][0], segs[3][0], segs[2][0], segs[7][0], segs[6][0]} = '0;
51 | 9: {segs[5][0], segs[4][0], segs[3][0], segs[7][5], segs[7][0], segs[6][0]} = '0;
52 | 10: {segs[5][0], segs[4][0], segs[7][4], segs[7][5], segs[7][0], segs[6][0]} = '0;
53 | 11: {segs[5][0], segs[7][3], segs[7][4], segs[7][5], segs[7][0], segs[6][0]} = '0;
54 | 12: {segs[6][3], segs[7][3], segs[7][4], segs[7][5], segs[7][0], segs[6][0]} = '0;
55 | 13: {segs[6][3], segs[7][3], segs[7][4], segs[7][5], segs[7][0], segs[5][3]} = '0;
56 | 14: {segs[6][3], segs[7][3], segs[7][4], segs[7][5], segs[4][3], segs[5][3]} = '0;
57 | 15: {segs[6][3], segs[7][3], segs[7][4], segs[3][3], segs[4][3], segs[5][3]} = '0;
58 | 16: {segs[6][3], segs[7][3], segs[2][3], segs[3][3], segs[4][3], segs[5][3]} = '0;
59 | 17: {segs[6][3], segs[1][3], segs[2][3], segs[3][3], segs[4][3], segs[5][3]} = '0;
60 | 18: {segs[0][3], segs[1][3], segs[2][3], segs[3][3], segs[4][3], segs[5][3]} = '0;
61 | 19: {segs[0][3], segs[1][3], segs[2][3], segs[3][3], segs[4][3], segs[0][2]} = '0;
62 | 20: {segs[0][3], segs[1][3], segs[2][3], segs[3][3], segs[0][1], segs[0][2]} = '0;
63 | 21: {segs[0][3], segs[1][3], segs[2][3], segs[0][0], segs[0][1], segs[0][2]} = '0;
64 | 22: {segs[0][3], segs[1][3], segs[0][5], segs[0][0], segs[0][1], segs[0][2]} = '0;
65 | 23: {segs[0][3], segs[0][4], segs[0][5], segs[0][0], segs[0][1], segs[0][2]} = '0;
66 | 24: {segs[1][3], segs[0][4], segs[0][5], segs[0][0], segs[0][1], segs[0][2]} = '0;
67 | 25: {segs[1][3], segs[0][4], segs[0][5], segs[0][0], segs[0][1], segs[1][4]} = '0;
68 | 26: {segs[1][3], segs[0][4], segs[0][5], segs[0][0], segs[1][5], segs[1][4]} = '0;
69 | 27: {segs[1][3], segs[0][4], segs[0][5], segs[2][0], segs[1][5], segs[1][4]} = '0;
70 | 28: {segs[1][3], segs[0][4], segs[2][5], segs[2][0], segs[1][5], segs[1][4]} = '0;
71 | 29: {segs[1][3], segs[2][4], segs[2][5], segs[2][0], segs[1][5], segs[1][4]} = '0;
72 | 30: {segs[3][3], segs[2][4], segs[2][5], segs[2][0], segs[1][5], segs[1][4]} = '0;
73 | 31: {segs[3][3], segs[2][4], segs[2][5], segs[2][0], segs[1][5], segs[3][4]} = '0;
74 | 32: {segs[3][3], segs[2][4], segs[2][5], segs[2][0], segs[3][5], segs[3][4]} = '0;
75 | 33: {segs[3][3], segs[2][4], segs[2][5], segs[4][0], segs[3][5], segs[3][4]} = '0;
76 | 34: {segs[3][3], segs[2][4], segs[4][5], segs[4][0], segs[3][5], segs[3][4]} = '0;
77 | 35: {segs[3][3], segs[4][4], segs[4][5], segs[4][0], segs[3][5], segs[3][4]} = '0;
78 | 36: {segs[5][3], segs[4][4], segs[4][5], segs[4][0], segs[3][5], segs[3][4]} = '0;
79 | 37: {segs[5][3], segs[4][4], segs[4][5], segs[4][0], segs[3][5], segs[5][4]} = '0;
80 | 38: {segs[5][3], segs[4][4], segs[4][5], segs[4][0], segs[5][5], segs[5][4]} = '0;
81 | 39: {segs[5][3], segs[4][4], segs[4][5], segs[6][0], segs[5][5], segs[5][4]} = '0;
82 | 40: {segs[5][3], segs[4][4], segs[6][5], segs[6][0], segs[6][5], segs[5][4]} = '0;
83 | 41: {segs[5][3], segs[6][4], segs[6][5], segs[6][0], segs[6][5], segs[5][4]} = '0;
84 | 42: {segs[7][3], segs[6][4], segs[6][5], segs[6][0], segs[6][5], segs[5][4]} = '0;
85 | 43: {segs[7][3], segs[6][4], segs[6][5], segs[6][0], segs[6][5], segs[7][4]} = '0;
86 | 44: {segs[7][3], segs[6][4], segs[6][5], segs[6][0], segs[7][6], segs[7][4]} = '0;
87 | 45: {segs[7][3], segs[6][4], segs[6][5], segs[6][6], segs[7][6], segs[7][4]} = '0;
88 | 46: {segs[7][3], segs[6][4], segs[5][6], segs[6][6], segs[7][6], segs[7][4]} = '0;
89 | 47: {segs[7][3], segs[4][6], segs[5][6], segs[6][6], segs[7][6], segs[7][4]} = '0;
90 | 48: {segs[3][6], segs[4][6], segs[5][6], segs[6][6], segs[7][6], segs[7][4]} = '0;
91 | 49: {segs[3][6], segs[4][6], segs[5][6], segs[6][6], segs[7][6], segs[2][6]} = '0;
92 | 50: {segs[3][6], segs[4][6], segs[5][6], segs[6][6], segs[1][6], segs[2][6]} = '0;
93 | 51: {segs[3][6], segs[4][6], segs[5][6], segs[0][6], segs[1][6], segs[2][6]} = '0;
94 | 52: {segs[3][6], segs[4][6], segs[0][1], segs[0][6], segs[1][6], segs[2][6]} = '0;
95 | 53: {segs[3][6], segs[0][0], segs[0][1], segs[0][6], segs[1][6], segs[2][6]} = '0;
96 | 54: {segs[1][0], segs[0][0], segs[0][1], segs[0][6], segs[1][6], segs[2][6]} = '0;
97 | 55: {segs[1][0], segs[0][0], segs[0][1], segs[0][6], segs[1][6], segs[2][0]} = '0;
98 | 56: {segs[1][0], segs[0][0], segs[0][1], segs[0][6], segs[3][0], segs[2][0]} = '0;
99 | 57: {segs[1][0], segs[0][0], segs[0][1], segs[4][0], segs[3][0], segs[2][0]} = '0;
100 | 58: {segs[1][0], segs[0][0], segs[5][0], segs[4][0], segs[3][0], segs[2][0]} = '0;
101 | 59: {segs[1][0], segs[6][0], segs[5][0], segs[4][0], segs[3][0], segs[2][0]} = '0;
102 | 60: {segs[7][0], segs[6][0], segs[5][0], segs[4][0], segs[3][0], segs[2][0]} = '0;
103 | 61: {segs[7][0], segs[6][0], segs[5][0], segs[4][0], segs[3][0], segs[7][5]} = '0;
104 | 62: {segs[7][0], segs[6][0], segs[5][0], segs[4][0], segs[7][4], segs[7][5]} = '0;
105 | 63: {segs[7][0], segs[6][0], segs[5][0], segs[7][3], segs[7][4], segs[7][5]} = '0;
106 | 64: {segs[7][0], segs[6][0], segs[7][2], segs[7][3], segs[7][4], segs[7][5]} = '0;
107 | 65: {segs[7][0], segs[7][1], segs[7][2], segs[7][3], segs[7][4], segs[7][5]} = '0;
108 | 66: {segs[6][0], segs[7][1], segs[7][2], segs[7][3], segs[7][4], segs[7][5]} = '0;
109 | 67: {segs[6][0], segs[7][1], segs[7][2], segs[7][3], segs[7][4], segs[6][1]} = '0;
110 | 68: {segs[6][0], segs[7][1], segs[7][2], segs[7][3], segs[6][2], segs[6][1]} = '0;
111 | 69: {segs[6][0], segs[7][1], segs[7][2], segs[5][3], segs[6][2], segs[6][1]} = '0;
112 | 70: {segs[6][0], segs[7][1], segs[5][2], segs[5][3], segs[6][2], segs[6][1]} = '0;
113 | 71: {segs[6][0], segs[5][1], segs[5][2], segs[5][3], segs[6][2], segs[6][1]} = '0;
114 | 72: {segs[4][0], segs[5][1], segs[5][2], segs[5][3], segs[6][2], segs[6][1]} = '0;
115 | 73: {segs[4][0], segs[5][1], segs[5][2], segs[5][3], segs[6][2], segs[4][1]} = '0;
116 | 74: {segs[4][0], segs[5][1], segs[5][2], segs[5][3], segs[4][2], segs[4][1]} = '0;
117 | 75: {segs[4][0], segs[5][1], segs[5][2], segs[3][3], segs[4][2], segs[4][1]} = '0;
118 | 76: {segs[4][0], segs[5][1], segs[3][2], segs[3][3], segs[4][2], segs[4][1]} = '0;
119 | 77: {segs[4][0], segs[3][1], segs[3][2], segs[3][3], segs[4][2], segs[4][1]} = '0;
120 | 78: {segs[2][0], segs[3][1], segs[3][2], segs[3][3], segs[4][2], segs[4][1]} = '0;
121 | 79: {segs[2][0], segs[3][1], segs[3][2], segs[3][3], segs[4][2], segs[2][1]} = '0;
122 | 80: {segs[2][0], segs[3][1], segs[3][2], segs[3][3], segs[2][2], segs[2][1]} = '0;
123 | 81: {segs[2][0], segs[3][1], segs[3][2], segs[1][3], segs[2][2], segs[2][1]} = '0;
124 | 82: {segs[2][0], segs[3][1], segs[1][2], segs[1][3], segs[2][2], segs[2][1]} = '0;
125 | 83: {segs[2][0], segs[1][1], segs[1][2], segs[1][3], segs[2][2], segs[2][1]} = '0;
126 | 84: {segs[0][0], segs[1][1], segs[1][2], segs[1][3], segs[2][2], segs[2][1]} = '0;
127 | 85: {segs[0][0], segs[1][1], segs[1][2], segs[1][3], segs[2][2], segs[0][1]} = '0;
128 | 86: {segs[0][0], segs[1][1], segs[1][2], segs[1][3], segs[0][6], segs[0][1]} = '0;
129 | 87: {segs[0][0], segs[1][1], segs[1][2], segs[1][6], segs[0][6], segs[0][1]} = '0;
130 | 88: {segs[0][0], segs[1][1], segs[2][6], segs[1][6], segs[0][6], segs[0][1]} = '0;
131 | 89: {segs[0][0], segs[3][6], segs[2][6], segs[1][6], segs[0][6], segs[0][1]} = '0;
132 | 90: {segs[4][6], segs[3][6], segs[2][6], segs[1][6], segs[0][6], segs[0][1]} = '0;
133 | 91: {segs[4][6], segs[3][6], segs[2][6], segs[1][6], segs[0][6], segs[5][6]} = '0;
134 | 92: {segs[4][6], segs[3][6], segs[2][6], segs[1][6], segs[6][6], segs[5][6]} = '0;
135 | 93: {segs[4][6], segs[3][6], segs[2][6], segs[7][6], segs[6][6], segs[5][6]} = '0;
136 | 94: {segs[4][6], segs[3][6], segs[7][4], segs[7][6], segs[6][6], segs[5][6]} = '0;
137 | 95: {segs[4][6], segs[7][3], segs[7][4], segs[7][6], segs[6][6], segs[5][6]} = '0;
138 | 96: {segs[6][3], segs[7][3], segs[7][4], segs[7][6], segs[6][6], segs[5][6]} = '0;
139 | 97: {segs[6][3], segs[7][3], segs[7][4], segs[7][6], segs[6][6], segs[5][3]} = '0;
140 | 98: {segs[6][3], segs[7][3], segs[7][4], segs[7][6], segs[4][3], segs[5][3]} = '0;
141 | default: begin
142 |
143 | end
144 | endcase
145 | end
146 |
147 | endmodule
148 |
--------------------------------------------------------------------------------
/experiment/01display/display.bit:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/experiment/01display/display.bit
--------------------------------------------------------------------------------
/experiment/01display/sim.sv:
--------------------------------------------------------------------------------
1 | module sim (
2 |
3 | );
4 | logic clk, resetn;
5 | logic [7:0]sw;
6 | logic[7:0][6:0]segs;
7 | controller controller(.*);
8 | always #5 clk = ~clk;
9 | // clk_gen clk_gen(.clk_out(clk));
10 |
11 | initial begin
12 | clk = 0;
13 | resetn = '0;
14 | #50 resetn = '1;
15 |
16 |
17 | end
18 | endmodule
--------------------------------------------------------------------------------
/experiment/01display/sources.tcl:
--------------------------------------------------------------------------------
1 | cd [file dirname [info script]]
2 | add_files top.sv
3 | add_files controller.sv
4 | set_property top top [current_fileset]
5 |
6 | cd [file dirname [info script]]
7 | add_files -fileset constrs_1 -norecurse Nexys4DDR_Master.xdc
8 |
9 | set_property SOURCE_SET sources_1 [get_filesets sim_1]
10 | add_files -fileset sim_1 -norecurse sim.sv
11 | set_property top sim [get_filesets sim_1]
12 | set_property top_lib xil_defaultlib [get_filesets sim_1]
--------------------------------------------------------------------------------
/experiment/01display/top.sv:
--------------------------------------------------------------------------------
1 | module top (
2 | input logic CLK100MHZ, CPU_RESETN,
3 | output logic [7:0] AN,
4 | output logic [6:0] A2G,
5 | input logic [7:0] SW,
6 | output logic [7:0] LED
7 | );
8 |
9 | assign LED = SW;
10 | logic[7:0][6:0]segs;
11 | controller ctler(
12 | .clk(CLK100MHZ),
13 | .resetn(CPU_RESETN),
14 | .sw(SW),
15 | .segs
16 | );
17 | logic [19:0] an_ctl;
18 | always_ff @(posedge CLK100MHZ, negedge CPU_RESETN) begin
19 | if (~CPU_RESETN) begin
20 | an_ctl <= '0;
21 | end else begin
22 | an_ctl <= an_ctl + 1;
23 | end
24 | end
25 | assign AN = ~(8'b1 << an_ctl[19:17]);
26 | assign A2G = segs[an_ctl[19:17]];
27 |
28 | endmodule
29 |
--------------------------------------------------------------------------------
/experiment/02simulation/decoder.sv:
--------------------------------------------------------------------------------
1 | module decoder (
2 | input logic [3:0]b,
3 | output logic [3:0]gray
4 | );
5 | assign gray[3] = 1'b0;
6 | assign gray[2:0] = b[3:1] ^ b[2:0];
7 | endmodule
8 |
--------------------------------------------------------------------------------
/experiment/02simulation/sim.sv:
--------------------------------------------------------------------------------
1 | module sim (
2 |
3 | );
4 |
5 | logic [3:0]b, gray;
6 | decoder decoder(.b, .gray);
7 | logic [0:15][3:0]ans;
8 | assign ans = {
9 | 4'b0000,
10 | 4'b0001,
11 | 4'b0011,
12 | 4'b0010,
13 | 4'b0110,
14 | 4'b0111,
15 | 4'b0101,
16 | 4'b0100,
17 | 4'b1100,
18 | 4'b1101,
19 | 4'b1111,
20 | 4'b1110,
21 | 4'b1010,
22 | 4'b1011,
23 | 4'b1001,
24 | 4'b1000
25 | };
26 |
27 | task check(input logic[3:0]b);
28 | #10
29 | if (ans[b] != gray) begin
30 | $display("[%d ns]: expected: 0x%x, got 0x%x!\n", $time, ans[b], gray);
31 | #10 $finish;
32 | end
33 | endtask
34 | initial begin
35 | b = 4'b1001;
36 | #10 check(b);
37 | #10 b = 4'b0101;
38 | #10 check(b);
39 | #10 b = 4'b1111;
40 | #10 check(b);
41 |
42 | $display("PASS!\n");
43 | #10 $finish;
44 | end
45 | endmodule
46 |
--------------------------------------------------------------------------------
/experiment/lab1/Nexys4DDR_Master.xdc:
--------------------------------------------------------------------------------
1 | ## This file is a general .xdc for the Nexys4 DDR Rev. C
2 | ## To use it in a project:
3 | ## - uncomment the lines corresponding to used pins
4 | ## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
5 |
6 | ## Clock signal
7 | set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk }]; #IO_L12P_T1_MRCC_35 Sch=clk100mhz
8 | create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {clk}];
9 |
10 |
11 | #Switches
12 |
13 | set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { SW[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
14 | set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { SW[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
15 | set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { SW[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
16 | set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { SW[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
17 | set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { SW[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4]
18 | set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { SW[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5]
19 | set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { SW[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6]
20 | set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { SW[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7]
21 | set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { SW[8] }]; #IO_L24N_T3_34 Sch=sw[8]
22 | set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { SW[9] }]; #IO_25_34 Sch=sw[9]
23 | set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { SW[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10]
24 | set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { SW[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11]
25 | set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { SW[12] }]; #IO_L24P_T3_35 Sch=sw[12]
26 | set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { SW[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13]
27 | set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { SW[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14]
28 | set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { SW[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
29 |
30 |
31 | # LEDs
32 |
33 | set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { LED[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
34 | set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { LED[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
35 | set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { LED[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
36 | set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { LED[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
37 | set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { LED[4] }]; #IO_L7P_T1_D09_14 Sch=led[4]
38 | set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { LED[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5]
39 | set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { LED[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6]
40 | set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { LED[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7]
41 | set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { LED[8] }]; #IO_L16N_T2_A15_D31_14 Sch=led[8]
42 | set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { LED[9] }]; #IO_L14N_T2_SRCC_14 Sch=led[9]
43 | set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { LED[10] }]; #IO_L22P_T3_A05_D21_14 Sch=led[10]
44 | set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { LED[11] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[11]
45 | set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { LED[12] }]; #IO_L16P_T2_CSI_B_14 Sch=led[12]
46 | set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { LED[13] }]; #IO_L22N_T3_A04_D20_14 Sch=led[13]
47 | set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { LED[14] }]; #IO_L20N_T3_A07_D23_14 Sch=led[14]
48 | set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { LED[15] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=led[15]
49 |
50 | set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { LED16_B }]; #IO_L5P_T0_D06_14 Sch=led16_b
51 | set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { LED16_G }]; #IO_L10P_T1_D14_14 Sch=led16_g
52 | set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { LED16_R }]; #IO_L11P_T1_SRCC_14 Sch=led16_r
53 | set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { LED17_B }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=led17_b
54 | set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { LED17_G }]; #IO_0_14 Sch=led17_g
55 | set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { LED17_R }]; #IO_L11N_T1_SRCC_14 Sch=led17_r
56 |
57 |
58 | #7 segment display
59 |
60 | set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { A2G[0] }]; #IO_L24N_T3_A00_D16_14 Sch=ca
61 | set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { A2G[1] }]; #IO_25_14 Sch=cb
62 | set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { A2G[2] }]; #IO_25_15 Sch=cc
63 | set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { A2G[3] }]; #IO_L17P_T2_A26_15 Sch=cd
64 | set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { A2G[4] }]; #IO_L13P_T2_MRCC_14 Sch=ce
65 | set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { A2G[5] }]; #IO_L19P_T3_A10_D26_14 Sch=cf
66 | set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { A2G[6] }]; #IO_L4P_T0_D04_14 Sch=cg
67 |
68 | set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { DP }]; #IO_L19N_T3_A21_VREF_15 Sch=dp
69 |
70 | set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { AN[0] }]; #IO_L23P_T3_FOE_B_15 Sch=an[0]
71 | set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { AN[1] }]; #IO_L23N_T3_FWE_B_15 Sch=an[1]
72 | set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { AN[2] }]; #IO_L24P_T3_A01_D17_14 Sch=an[2]
73 | set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { AN[3] }]; #IO_L19P_T3_A22_15 Sch=an[3]
74 | set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { AN[4] }]; #IO_L8N_T1_D12_14 Sch=an[4]
75 | set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { AN[5] }]; #IO_L14P_T2_SRCC_14 Sch=an[5]
76 | set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { AN[6] }]; #IO_L23P_T3_35 Sch=an[6]
77 | set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { AN[7] }]; #IO_L23N_T3_A02_D18_14 Sch=an[7]
78 |
79 |
80 | #Buttons
81 |
82 | set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { resetn }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn
83 |
84 | set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { BTNC }]; #IO_L9P_T1_DQS_14 Sch=btnc
85 | set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { BTNU }]; #IO_L4N_T0_D05_14 Sch=btnu
86 | set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { BTNL }]; #IO_L12P_T1_MRCC_14 Sch=btnl
87 | set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { BTNR }]; #IO_L10N_T1_D15_14 Sch=btnr
88 | set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { BTND }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
89 |
90 |
91 | #Pmod Headers
92 |
93 |
94 | #Pmod Header JA
95 |
96 | set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { JA[1] }]; #IO_L20N_T3_A19_15 Sch=ja[1]
97 | set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { JA[2] }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2]
98 | set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { JA[3] }]; #IO_L21P_T3_DQS_15 Sch=ja[3]
99 | set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { JA[4] }]; #IO_L18N_T2_A23_15 Sch=ja[4]
100 | set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { JA[7] }]; #IO_L16N_T2_A27_15 Sch=ja[7]
101 | set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { JA[8] }]; #IO_L16P_T2_A28_15 Sch=ja[8]
102 | set_property -dict { PACKAGE_PIN F18 IOSTANDARD LVCMOS33 } [get_ports { JA[9] }]; #IO_L22N_T3_A16_15 Sch=ja[9]
103 | set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { JA[10] }]; #IO_L22P_T3_A17_15 Sch=ja[10]
104 |
105 |
106 | #Pmod Header JB
107 |
108 | set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { JB[1] }]; #IO_L1P_T0_AD0P_15 Sch=jb[1]
109 | set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { JB[2] }]; #IO_L14N_T2_SRCC_15 Sch=jb[2]
110 | set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { JB[3] }]; #IO_L13N_T2_MRCC_15 Sch=jb[3]
111 | set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { JB[4] }]; #IO_L15P_T2_DQS_15 Sch=jb[4]
112 | set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { JB[7] }]; #IO_L11N_T1_SRCC_15 Sch=jb[7]
113 | set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { JB[8] }]; #IO_L5P_T0_AD9P_15 Sch=jb[8]
114 | set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { JB[9] }]; #IO_0_15 Sch=jb[9]
115 | set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { JB[10] }]; #IO_L13P_T2_MRCC_15 Sch=jb[10]
116 |
117 |
118 | #Pmod Header JC
119 |
120 | set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { JC[1] }]; #IO_L23N_T3_35 Sch=jc[1]
121 | set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { JC[2] }]; #IO_L19N_T3_VREF_35 Sch=jc[2]
122 | set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { JC[3] }]; #IO_L22N_T3_35 Sch=jc[3]
123 | set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { JC[4] }]; #IO_L19P_T3_35 Sch=jc[4]
124 | set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS33 } [get_ports { JC[7] }]; #IO_L6P_T0_35 Sch=jc[7]
125 | set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { JC[8] }]; #IO_L22P_T3_35 Sch=jc[8]
126 | set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { JC[9] }]; #IO_L21P_T3_DQS_35 Sch=jc[9]
127 | set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { JC[10] }]; #IO_L5P_T0_AD13P_35 Sch=jc[10]
128 |
129 |
130 | #Pmod Header JD
131 |
132 | set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { JD[1] }]; #IO_L21N_T3_DQS_35 Sch=jd[1]
133 | set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { JD[2] }]; #IO_L17P_T2_35 Sch=jd[2]
134 | set_property -dict { PACKAGE_PIN G1 IOSTANDARD LVCMOS33 } [get_ports { JD[3] }]; #IO_L17N_T2_35 Sch=jd[3]
135 | set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { JD[4] }]; #IO_L20N_T3_35 Sch=jd[4]
136 | set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { JD[7] }]; #IO_L15P_T2_DQS_35 Sch=jd[7]
137 | set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { JD[8] }]; #IO_L20P_T3_35 Sch=jd[8]
138 | set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { JD[9] }]; #IO_L15N_T2_DQS_35 Sch=jd[9]
139 | set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { JD[10] }]; #IO_L13N_T2_MRCC_35 Sch=jd[10]
140 |
141 |
142 | #Pmod Header JXADC
143 |
144 | set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVDS } [get_ports { XA_N[1] }]; #IO_L9N_T1_DQS_AD3N_15 Sch=xa_n[1]
145 | set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVDS } [get_ports { XA_P[1] }]; #IO_L9P_T1_DQS_AD3P_15 Sch=xa_p[1]
146 | set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVDS } [get_ports { XA_N[2] }]; #IO_L8N_T1_AD10N_15 Sch=xa_n[2]
147 | set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVDS } [get_ports { XA_P[2] }]; #IO_L8P_T1_AD10P_15 Sch=xa_p[2]
148 | set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVDS } [get_ports { XA_N[3] }]; #IO_L7N_T1_AD2N_15 Sch=xa_n[3]
149 | set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVDS } [get_ports { XA_P[3] }]; #IO_L7P_T1_AD2P_15 Sch=xa_p[3]
150 | set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVDS } [get_ports { XA_N[4] }]; #IO_L10N_T1_AD11N_15 Sch=xa_n[4]
151 | set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVDS } [get_ports { XA_P[4] }]; #IO_L10P_T1_AD11P_15 Sch=xa_p[4]
152 |
153 |
154 | #VGA Connector
155 |
156 | set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[0] }]; #IO_L8N_T1_AD14N_35 Sch=vga_r[0]
157 | set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[1] }]; #IO_L7N_T1_AD6N_35 Sch=vga_r[1]
158 | set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[2] }]; #IO_L1N_T0_AD4N_35 Sch=vga_r[2]
159 | set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[3] }]; #IO_L8P_T1_AD14P_35 Sch=vga_r[3]
160 |
161 | set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[0] }]; #IO_L1P_T0_AD4P_35 Sch=vga_g[0]
162 | set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=vga_g[1]
163 | set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[2] }]; #IO_L2N_T0_AD12N_35 Sch=vga_g[2]
164 | set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[3] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=vga_g[3]
165 |
166 | set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[0] }]; #IO_L2P_T0_AD12P_35 Sch=vga_b[0]
167 | set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[1] }]; #IO_L4N_T0_35 Sch=vga_b[1]
168 | set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[2] }]; #IO_L6N_T0_VREF_35 Sch=vga_b[2]
169 | set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[3] }]; #IO_L4P_T0_35 Sch=vga_b[3]
170 |
171 | set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { VGA_HS }]; #IO_L4P_T0_15 Sch=vga_hs
172 | set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { VGA_VS }]; #IO_L3N_T0_DQS_AD1N_15 Sch=vga_vs
173 |
174 |
175 | #Micro SD Connector
176 |
177 | set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { SD_RESET }]; #IO_L14P_T2_SRCC_35 Sch=sd_reset
178 | set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { SD_CD }]; #IO_L9N_T1_DQS_AD7N_35 Sch=sd_cd
179 | set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { SD_SCK }]; #IO_L9P_T1_DQS_AD7P_35 Sch=sd_sck
180 | set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { SD_CMD }]; #IO_L16N_T2_35 Sch=sd_cmd
181 | set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[0] }]; #IO_L16P_T2_35 Sch=sd_dat[0]
182 | set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[1] }]; #IO_L18N_T2_35 Sch=sd_dat[1]
183 | set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[2] }]; #IO_L18P_T2_35 Sch=sd_dat[2]
184 | set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[3] }]; #IO_L14N_T2_SRCC_35 Sch=sd_dat[3]
185 |
186 |
187 | #Accelerometer
188 |
189 | set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { ACL_MISO }]; #IO_L11P_T1_SRCC_15 Sch=acl_miso
190 | set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports { ACL_MOSI }]; #IO_L5N_T0_AD9N_15 Sch=acl_mosi
191 | set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { ACL_SCLK }]; #IO_L14P_T2_SRCC_15 Sch=acl_sclk
192 | set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { ACL_CSN }]; #IO_L12P_T1_MRCC_15 Sch=acl_csn
193 | set_property -dict { PACKAGE_PIN B13 IOSTANDARD LVCMOS33 } [get_ports { ACL_INT[1] }]; #IO_L2P_T0_AD8P_15 Sch=acl_int[1]
194 | set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { ACL_INT[2] }]; #IO_L20P_T3_A20_15 Sch=acl_int[2]
195 |
196 |
197 | #Temperature Sensor
198 |
199 | set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { TMP_SCL }]; #IO_L1N_T0_AD0N_15 Sch=tmp_scl
200 | set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { TMP_SDA }]; #IO_L12N_T1_MRCC_15 Sch=tmp_sda
201 | set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports { TMP_INT }]; #IO_L6N_T0_VREF_15 Sch=tmp_int
202 | set_property -dict { PACKAGE_PIN B14 IOSTANDARD LVCMOS33 } [get_ports { TMP_CT }]; #IO_L2N_T0_AD8N_15 Sch=tmp_ct
203 |
204 | #Omnidirectional Microphone
205 |
206 | set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { M_CLK }]; #IO_25_35 Sch=m_clk
207 | set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { M_DATA }]; #IO_L24N_T3_35 Sch=m_data
208 | set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 } [get_ports { M_LRSEL }]; #IO_0_35 Sch=m_lrsel
209 |
210 |
211 | #PWM Audio Amplifier
212 |
213 | set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { AUD_PWM }]; #IO_L4N_T0_15 Sch=aud_pwm
214 | set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { AUD_SD }]; #IO_L6P_T0_15 Sch=aud_sd
215 |
216 |
217 | #USB-RS232 Interface
218 |
219 | set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { UART_TXD_IN }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
220 | set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { UART_RXD_OUT }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out
221 | set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { UART_CTS }]; #IO_L12N_T1_MRCC_35 Sch=uart_cts
222 | set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { UART_RTS }]; #IO_L5N_T0_AD13N_35 Sch=uart_rts
223 |
224 | #USB HID (PS/2)
225 |
226 | set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { PS2_CLK }]; #IO_L13P_T2_MRCC_35 Sch=ps2_clk
227 | set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { PS2_DATA }]; #IO_L10N_T1_AD15N_35 Sch=ps2_data
228 |
229 |
230 | #SMSC Ethernet PHY
231 |
232 | set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { ETH_MDC }]; #IO_L11P_T1_SRCC_16 Sch=eth_mdc
233 | set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { ETH_MDIO }]; #IO_L14N_T2_SRCC_16 Sch=eth_mdio
234 | set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { ETH_RSTN }]; #IO_L10P_T1_AD15P_35 Sch=eth_rstn
235 | set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { ETH_CRSDV }]; #IO_L6N_T0_VREF_16 Sch=eth_crsdv
236 | set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXERR }]; #IO_L13N_T2_MRCC_16 Sch=eth_rxerr
237 | set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXD[0] }]; #IO_L13P_T2_MRCC_16 Sch=eth_rxd[0]
238 | set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXD[1] }]; #IO_L19N_T3_VREF_16 Sch=eth_rxd[1]
239 | set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXEN }]; #IO_L11N_T1_SRCC_16 Sch=eth_txen
240 | set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXD[0] }]; #IO_L14P_T2_SRCC_16 Sch=eth_txd[0]
241 | set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXD[1] }]; #IO_L12N_T1_MRCC_16 Sch=eth_txd[1]
242 | set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { ETH_REFCLK }]; #IO_L11P_T1_SRCC_35 Sch=eth_refclk
243 | set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { ETH_INTN }]; #IO_L12P_T1_MRCC_16 Sch=eth_intn
244 |
245 |
246 | #Quad SPI Flash
247 |
248 | set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[0] }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0]
249 | set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[1] }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1]
250 | set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[2] }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2]
251 | set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[3] }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3]
252 | set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { QSPI_CSN }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_csn
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
--------------------------------------------------------------------------------
/experiment/lab1/README.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/experiment/lab1/README.pdf
--------------------------------------------------------------------------------
/experiment/lab1/display/decoder2_4.sv:
--------------------------------------------------------------------------------
1 | module decoder2_4 (
2 | input logic [1:0] in,
3 | output logic [3:0] out,
4 | input logic en
5 | );
6 |
7 | endmodule
8 |
9 | module decoder2_4ver1 (
10 | input logic [1:0] in,
11 | output logic [3:0] out,
12 | input logic en
13 | );
14 | assign out[3] = en & in[1] & in[0];
15 | assign out[2] = en & in[1] & ~in[0];
16 | assign out[1] = en & ~in[1] & in[0];
17 | assign out[0] = en & ~in[1] & ~in[0];
18 |
19 | endmodule
20 |
21 | module decoder2_4ver2 (
22 | input logic [1:0] in,
23 | output logic [3:0] out,
24 | input logic en
25 | );
26 | always_comb begin
27 | unique case(in) begin
28 | 2'd0: out = 4'b0001 & {4{en}};
29 | 2'd1: out = 4'b0010 & {4{en}};
30 | 2'd2: out = 4'b0100 & {4{en}};
31 | 2'd3: out = 4'b1000 & {4{en}};
32 | default: begin
33 | out = '0;
34 | end
35 | end
36 | end
37 |
38 | endmodule
39 |
40 | module decoder2_4ver3 (
41 | input logic [1:0] in,
42 | output logic [3:0] out,
43 | input logic en
44 | );
45 | always_comb begin
46 | out = '0;
47 | unique case(in) begin
48 | 2'd0: out[0] = 1'b1;
49 | 2'd1: out[1] = 1'b1;
50 | 2'd2: out[2] = 1'b1;
51 | 2'd3: out[3] = 1'b1;
52 | default: begin
53 | out[0] = 1'b0;
54 | end
55 | end
56 | if (en == 1'b0) begin
57 | out = '0;
58 | end
59 | end
60 |
61 | endmodule
62 |
--------------------------------------------------------------------------------
/experiment/lab1/display/encoder4_2.sv:
--------------------------------------------------------------------------------
1 | module encoder4_2 (
2 | input logic [3:0] in,
3 | output logic [1:0] out
4 | );
5 |
6 | endmodule
7 |
8 | module encoder4_2ver1 (
9 | input logic [3:0] in,
10 | output logic [1:0] out
11 | );
12 | assign out[1] = (~in[3] & in[2] & ~in[1] & ~in[0]) |
13 | (in[3] & ~in[2] & ~in[1] & ~in[0]);
14 | assign out[0] = (~in[3] & ~in[2] & in[1] & ~in[0]) |
15 | (in[3] & ~in[2] & ~in[1] & ~in[0]);
16 | endmodule
17 |
18 | module encoder4_2ver2 (
19 | input logic [3:0] in,
20 | output logic [1:0] out
21 | );
22 | always_comb begin
23 | unique case(in) begin
24 | 4'b0001: out = 2'b00;
25 | 4'b0010: out = 2'b01;
26 | 4'b0100: out = 2'b10;
27 | 4'b1000: out = 2'b11;
28 | default: begin
29 | out = '0;
30 | end
31 | end
32 | end
33 |
34 | endmodule
35 |
--------------------------------------------------------------------------------
/experiment/lab1/display/priority_encoder4_2.sv:
--------------------------------------------------------------------------------
1 | module priority_encoder4_2 (
2 | input logic [3:0] in,
3 | output logic [1:0] out
4 | );
5 |
6 | endmodule
7 |
8 | module priority_encoder4_2ver1 (
9 | input logic [3:0] in,
10 | output logic [1:0] out
11 | );
12 | always_comb begin
13 | if (in[3]) begin
14 | out = 2'b11;
15 | end else if (in[2]) begin
16 | out = 2'b10;
17 | end else if (in[1]) begin
18 | out = 2'b01;
19 | end else if (in[0]) begin
20 | out = 2'b00;
21 | end else begin
22 | out = 2'b00;
23 | end
24 | end
25 |
26 | endmodule
27 |
28 | module priority_encoder4_2 (
29 | input logic [3:0] in,
30 | output logic [1:0] out
31 | );
32 | always_comb begin
33 | priority case(1'b1) begin
34 | in[3]: out = 2'b11;
35 | in[2]: out = 2'b10;
36 | in[1]: out = 2'b01;
37 | in[0]: out = 2'b00;
38 | default: begin
39 | out = 2'b00;
40 | end
41 | end
42 | end
43 |
44 | endmodule
45 |
--------------------------------------------------------------------------------
/experiment/lab1/lab1.sv:
--------------------------------------------------------------------------------
1 | module decoder4_16 (
2 | input logic [3:0]in,
3 | output logic [15:0]out,
4 | input logic en
5 | );
6 | // TODO: add logic here
7 |
8 | endmodule
9 |
10 | module decoder5_32 (
11 | input logic [4:0]in,
12 | output logic [31:0]out
13 | );
14 | decoder4_16 decoder1(
15 | // TODO: add ports here
16 |
17 | );
18 |
19 | decoder4_16 decoder2(
20 | // TODO: add ports here
21 |
22 | );
23 | endmodule
24 |
25 | module encoder16_4 (
26 | input logic [15:0]in,
27 | output logic [3:0]out
28 | );
29 | // TODO: add logic here
30 |
31 | endmodule
32 |
33 | module priority_encoder16_4(
34 | input logic [15:0]in,
35 | output logic [3:0]out
36 | );
37 | // TODO: add logic here
38 |
39 | endmodule
--------------------------------------------------------------------------------
/experiment/lab1/myans.sv:
--------------------------------------------------------------------------------
1 | (* keep = "true" *)module ans (
2 | input logic [3:0]in1,
3 | input logic [4:0]in2,
4 | input logic [15:0]in3, in4,
5 | output logic [15:0]ans1,
6 | output logic [31:0]ans2,
7 | output logic [3:0]ans3,
8 | output logic [3:0]ans4,
9 | input logic en
10 | );
11 | ans_decoder4_16 ans_sim1(.in(in1), .out(ans1), .en);
12 | ans_decoder5_32 ans_sim2(.in(in2), .out(ans2));
13 | ans_encoder16_4 ans_sim3(.in(in3), .out(ans3));
14 | ans_priority_encoder16_4 ans_sim4(.in(in4), .out(ans4));
15 | endmodule
16 |
17 |
18 | module ans_decoder4_16 (
19 | input logic [3:0]in,
20 | output logic [15:0]out,
21 | input logic en
22 | );
23 | // TODO: write your code here
24 | assign out = (16'b1 << in) & {16{en}};
25 |
26 | endmodule
27 |
28 | module ans_decoder5_32 (
29 | input logic [4:0]in,
30 | output logic [31:0]out
31 | );
32 | assign out = 32'b1 << in;
33 | endmodule
34 |
35 | module ans_encoder16_4 (
36 | input logic [15:0]in,
37 | output logic [3:0]out
38 | );
39 | // TODO: add logic here
40 | always_comb begin
41 | out = '0;
42 | for (int i = 0; i < 16; i++) begin
43 | if (in[i]) begin
44 | out = 4'(i);
45 | end
46 | end
47 | end
48 |
49 | endmodule
50 |
51 | module ans_priority_encoder16_4(
52 | input logic [15:0]in,
53 | output logic [3:0]out
54 | );
55 | // TODO: add logic here
56 | always_comb begin
57 | out = '0;
58 | for (int i = 0; i < 16; i++) begin
59 | if (in[i]) begin
60 | out = 4'(i);
61 | end
62 | end
63 | end
64 | endmodule
--------------------------------------------------------------------------------
/experiment/lab1/readme.md:
--------------------------------------------------------------------------------
1 | # lab1注意事项
2 |
3 | ## 新建项目
4 |
5 | 先新建一个项目。
6 |
7 | 然后在点击`Tools --> Run Tcl Script`,运行本目录下的 `sources.tcl`添加文件。
8 |
9 | 
10 |
11 | 随后,在 `lab1.sv`中填写代码。
12 |
13 | ## 仿真
14 |
15 | 仿真文件`sim.sv`集成了本实验要完成的4个模块的调试。
16 |
17 | 如果只想调试某一个模块(比如其他模块还没写),在 `sim.sv`中修改debug enable信号,把不想调试的模块的debug信号置为`1'b0`:
18 |
19 | ```verilog
20 | // TODO: modify the debug enable to 1'b0 if you don't want to debug the module
21 | assign debug_decoder4_16 = 1'b1;
22 | assign debug_decoder5_32 = 1'b1;
23 | assign debug_encoder16_4 = 1'b1;
24 | assign debug_priority_encoder16_4 = 1'b1;
25 | ```
26 |
27 | 开始仿真后,点击 `Run all`, 使仿真跑完:
28 |
29 | ## 上板
30 |
31 | 下一次实验课上板。你可以提前 `generate bitstream`,下节实验课上直接 `program device`。
32 |
33 |
--------------------------------------------------------------------------------
/experiment/lab1/sim.sv:
--------------------------------------------------------------------------------
1 | module sim (
2 |
3 | );
4 | logic debug_decoder4_16;
5 | logic debug_decoder5_32;
6 | logic debug_encoder16_4;
7 | logic debug_priority_encoder16_4;
8 |
9 | // TODO: modify the debug enable to 1'b0 if you don't want to debug the module
10 | assign debug_decoder4_16 = 1'b1;
11 | assign debug_decoder5_32 = 1'b1;
12 | assign debug_encoder16_4 = 1'b0;
13 | assign debug_priority_encoder16_4 = 1'b0;
14 |
15 | logic [3:0]sim1_in;
16 | logic [4:0]sim2_in;
17 | logic [15:0]sim3_in, sim4_in;
18 | logic en;
19 |
20 | logic [15:0]sim1_out, sim1_tmp;
21 | logic [31:0]sim2_out, sim2_tmp;
22 | logic [3:0]sim3_out, sim4_out, sim3_tmp, sim4_tmp;
23 |
24 | logic [15:0]ans1;
25 | logic [31:0]ans2;
26 | logic [3:0]ans3;
27 | logic [3:0]ans4;
28 |
29 | assign sim1_out = debug_decoder4_16 ? sim1_tmp : ans1;
30 | assign sim2_out = debug_decoder5_32 ? sim2_tmp : ans2;
31 | assign sim3_out = debug_encoder16_4 ? sim3_tmp : ans3;
32 | assign sim4_out = debug_priority_encoder16_4 ? sim4_tmp : ans4;
33 |
34 | decoder4_16 sim1(.in(sim1_in), .out(sim1_tmp), .en);
35 | decoder5_32 sim2(.in(sim2_in), .out(sim2_tmp));
36 | encoder16_4 sim3(.in(sim3_in), .out(sim3_tmp));
37 | priority_encoder16_4 sim4(.in(sim4_in), .out(sim4_tmp));
38 |
39 | ans ans_inst(.in1(sim1_in), .in2(sim2_in), .in3(sim3_in), .in4(sim4_in), .*);
40 |
41 | logic clk, resetn;
42 | always #5 clk = ~clk;
43 | logic [16:0]counter, counter_nxt;
44 | assign sim1_in = counter[3:0];
45 | assign sim2_in = counter[4:0];
46 | assign sim3_in = 16'b1 << counter[3:0];
47 | assign sim4_in = counter[15:0];
48 | assign en = counter[4];
49 | initial begin
50 | clk = 1'b0;
51 | resetn = 1'b0;
52 | #100 resetn = 1'b1;
53 | end
54 |
55 | always_ff @(posedge clk) begin
56 | if ( ~resetn ) begin
57 | counter <= '0;
58 | end else begin
59 | counter <= counter_nxt;
60 | end
61 | end
62 |
63 | always_comb begin
64 | counter_nxt = counter;
65 | if (counter < 17'h10000 && sim1_out == ans1 && sim2_out == ans2 && sim3_out == ans3 && (sim4_in == 16'b0 || sim4_out == ans4) ) begin
66 | counter_nxt = counter_nxt + 1;
67 | end
68 | end
69 |
70 | always_ff @(posedge clk) begin
71 | if (~resetn) begin
72 |
73 | end else if (counter == 17'h10000) begin
74 | $display("PASS!\n");
75 | $finish;
76 | end else if (~(sim1_out === ans1)) begin
77 | $display("[%d ns]: Decoder4_16 expected 0x %x, got 0x %x!\n", $time, ans1, sim1_out);
78 | $finish;
79 | end else if (~(sim2_out === ans2)) begin
80 | $display("[%d ns]: Decoder5_32 expected 0x %x, got 0x %x!\n", $time, ans2, sim2_out);
81 | $finish;
82 | end else if (~(sim3_out === ans3)) begin
83 | $display("[%d ns]: Encoder16_4 expected 0x %x, got 0x %x!\n", $time, ans3, sim3_out);
84 | $finish;
85 | end else if (~(sim4_in == 16'b0 || sim4_out === ans4)) begin
86 | $display("[%d ns]: Priority_encoder16_4 expected 0x %x, got 0x %x!\n", $time, ans4, sim4_out);
87 | $finish;
88 | end else if (counter_nxt == counter) begin
89 | $display("Unknown error!");
90 | $finish;
91 | end
92 | end
93 |
94 | endmodule
95 |
--------------------------------------------------------------------------------
/experiment/lab1/sources.tcl:
--------------------------------------------------------------------------------
1 | cd [file dirname [info script]]
2 | add_files ans.v
3 | add_files top.sv
4 | add_files lab1.sv
5 | set_property top top [current_fileset]
6 |
7 | cd [file dirname [info script]]
8 | add_files -fileset constrs_1 -norecurse Nexys4DDR_Master.xdc
9 |
10 | set_property SOURCE_SET sources_1 [get_filesets sim_1]
11 | add_files -fileset sim_1 -norecurse sim.sv
12 | set_property top sim [get_filesets sim_1]
13 | set_property top_lib xil_defaultlib [get_filesets sim_1]
14 |
15 | set_param general.maxThreads 16
--------------------------------------------------------------------------------
/experiment/lab1/top.sv:
--------------------------------------------------------------------------------
1 | module top (
2 | input logic clk, resetn,
3 | output logic LED16_G, LED16_R, LED17_G
4 | );
5 | logic [3:0]top1_in;
6 | logic [4:0]top2_in;
7 | logic [15:0]top3_in, top4_in;
8 | logic en;
9 |
10 | logic [15:0]top1_out;
11 | logic [31:0]top2_out;
12 | logic [3:0]top3_out, top4_out;
13 |
14 | logic [15:0]ans1;
15 | logic [31:0]ans2;
16 | logic [3:0]ans3;
17 | logic [3:0]ans4;
18 |
19 | decoder4_16 top1(.in(top1_in), .out(top1_out), .en(en));
20 | decoder5_32 top2(.in(top2_in), .out(top2_out));
21 | encoder16_4 top3(.in(top3_in), .out(top3_out));
22 | priority_encoder16_4 top4(.in(top4_in), .out(top4_out));
23 |
24 | ans ans_inst_top(.in1(top1_in), .in2(top2_in), .in3(top3_in), .in4(top4_in), .*);
25 |
26 | logic [16:0]counter, counter_nxt;
27 | assign top1_in = counter[3:0];
28 | assign top2_in = counter[4:0];
29 | assign top3_in = 16'b1 << counter[3:0];
30 | assign top4_in = counter[15:0];
31 | assign en = counter[4];
32 | logic [15:0]clk_counter;
33 | always_ff @(posedge clk) begin
34 | if (~resetn) begin
35 | clk_counter <= '0;
36 |
37 | end
38 | else begin
39 | clk_counter <= clk_counter + 1;
40 | end
41 | end
42 |
43 | always_ff @(posedge clk_counter[5], negedge resetn) begin
44 | if ( ~resetn ) begin
45 | counter <= '0;
46 | {LED16_G, LED16_R, LED17_G} <= '0;
47 | end else begin
48 | counter <= counter_nxt;
49 | if (counter == 17'h10000) begin
50 | LED16_G <= 1'b1;
51 | LED17_G <= 1'b1;
52 | end else if (counter == counter_nxt) begin
53 | LED16_R <= 1'b1;
54 | LED17_G <= 1'b1;
55 | end
56 | end
57 | end
58 |
59 | always_comb begin
60 | counter_nxt = counter;
61 | if (counter < 17'h10000 && top1_out == ans1 && top2_out == ans2 && top3_out == ans3 && (top4_in == 16'b0 || top4_out == ans4) ) begin
62 | counter_nxt = counter_nxt + 1;
63 | end
64 | end
65 | endmodule
66 |
--------------------------------------------------------------------------------
/experiment/lab2/Nexys4DDR_Master.xdc:
--------------------------------------------------------------------------------
1 | ## This file is a general .xdc for the Nexys4 DDR Rev. C
2 | ## To use it in a project:
3 | ## - uncomment the lines corresponding to used pins
4 | ## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
5 |
6 | ## Clock signal
7 | set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk }]; #IO_L12P_T1_MRCC_35 Sch=clk100mhz
8 | create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {clk}];
9 |
10 |
11 | #Switches
12 |
13 | set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { SW[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
14 | set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { SW[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
15 | set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { SW[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
16 | set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { SW[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
17 | set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { SW[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4]
18 | set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { SW[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5]
19 | set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { SW[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6]
20 | set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { SW[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7]
21 | set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { SW[8] }]; #IO_L24N_T3_34 Sch=sw[8]
22 | set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { SW[9] }]; #IO_25_34 Sch=sw[9]
23 | set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { SW[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10]
24 | set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { SW[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11]
25 | set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { SW[12] }]; #IO_L24P_T3_35 Sch=sw[12]
26 | set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { SW[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13]
27 | set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { SW[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14]
28 | set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { SW[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
29 |
30 |
31 | # LEDs
32 |
33 | set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { LED[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
34 | set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { LED[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
35 | set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { LED[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
36 | set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { LED[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
37 | set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { LED[4] }]; #IO_L7P_T1_D09_14 Sch=led[4]
38 | set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { LED[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5]
39 | set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { LED[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6]
40 | set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { LED[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7]
41 | set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { LED[8] }]; #IO_L16N_T2_A15_D31_14 Sch=led[8]
42 | set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { LED[9] }]; #IO_L14N_T2_SRCC_14 Sch=led[9]
43 | set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { LED[10] }]; #IO_L22P_T3_A05_D21_14 Sch=led[10]
44 | set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { LED[11] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[11]
45 | set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { LED[12] }]; #IO_L16P_T2_CSI_B_14 Sch=led[12]
46 | set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { LED[13] }]; #IO_L22N_T3_A04_D20_14 Sch=led[13]
47 | set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { LED[14] }]; #IO_L20N_T3_A07_D23_14 Sch=led[14]
48 | set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { LED[15] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=led[15]
49 |
50 | set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports { LED16_B }]; #IO_L5P_T0_D06_14 Sch=led16_b
51 | set_property -dict { PACKAGE_PIN M16 IOSTANDARD LVCMOS33 } [get_ports { LED16_G }]; #IO_L10P_T1_D14_14 Sch=led16_g
52 | set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { LED16_R }]; #IO_L11P_T1_SRCC_14 Sch=led16_r
53 | set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { LED17_B }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=led17_b
54 | set_property -dict { PACKAGE_PIN R11 IOSTANDARD LVCMOS33 } [get_ports { LED17_G }]; #IO_0_14 Sch=led17_g
55 | set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { LED17_R }]; #IO_L11N_T1_SRCC_14 Sch=led17_r
56 |
57 |
58 | #7 segment display
59 |
60 | set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { A2G[0] }]; #IO_L24N_T3_A00_D16_14 Sch=ca
61 | set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { A2G[1] }]; #IO_25_14 Sch=cb
62 | set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { A2G[2] }]; #IO_25_15 Sch=cc
63 | set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { A2G[3] }]; #IO_L17P_T2_A26_15 Sch=cd
64 | set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { A2G[4] }]; #IO_L13P_T2_MRCC_14 Sch=ce
65 | set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { A2G[5] }]; #IO_L19P_T3_A10_D26_14 Sch=cf
66 | set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { A2G[6] }]; #IO_L4P_T0_D04_14 Sch=cg
67 |
68 | set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { DP }]; #IO_L19N_T3_A21_VREF_15 Sch=dp
69 |
70 | set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { AN[0] }]; #IO_L23P_T3_FOE_B_15 Sch=an[0]
71 | set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { AN[1] }]; #IO_L23N_T3_FWE_B_15 Sch=an[1]
72 | set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { AN[2] }]; #IO_L24P_T3_A01_D17_14 Sch=an[2]
73 | set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { AN[3] }]; #IO_L19P_T3_A22_15 Sch=an[3]
74 | set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { AN[4] }]; #IO_L8N_T1_D12_14 Sch=an[4]
75 | set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { AN[5] }]; #IO_L14P_T2_SRCC_14 Sch=an[5]
76 | set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { AN[6] }]; #IO_L23P_T3_35 Sch=an[6]
77 | set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { AN[7] }]; #IO_L23N_T3_A02_D18_14 Sch=an[7]
78 |
79 |
80 | #Buttons
81 |
82 | set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { resetn }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn
83 |
84 | set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { BTNC }]; #IO_L9P_T1_DQS_14 Sch=btnc
85 | set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { BTNU }]; #IO_L4N_T0_D05_14 Sch=btnu
86 | set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { BTNL }]; #IO_L12P_T1_MRCC_14 Sch=btnl
87 | set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { BTNR }]; #IO_L10N_T1_D15_14 Sch=btnr
88 | set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { BTND }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
89 |
90 |
91 | #Pmod Headers
92 |
93 |
94 | #Pmod Header JA
95 |
96 | set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { JA[1] }]; #IO_L20N_T3_A19_15 Sch=ja[1]
97 | set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { JA[2] }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2]
98 | set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { JA[3] }]; #IO_L21P_T3_DQS_15 Sch=ja[3]
99 | set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { JA[4] }]; #IO_L18N_T2_A23_15 Sch=ja[4]
100 | set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { JA[7] }]; #IO_L16N_T2_A27_15 Sch=ja[7]
101 | set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { JA[8] }]; #IO_L16P_T2_A28_15 Sch=ja[8]
102 | set_property -dict { PACKAGE_PIN F18 IOSTANDARD LVCMOS33 } [get_ports { JA[9] }]; #IO_L22N_T3_A16_15 Sch=ja[9]
103 | set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { JA[10] }]; #IO_L22P_T3_A17_15 Sch=ja[10]
104 |
105 |
106 | #Pmod Header JB
107 |
108 | set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { JB[1] }]; #IO_L1P_T0_AD0P_15 Sch=jb[1]
109 | set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { JB[2] }]; #IO_L14N_T2_SRCC_15 Sch=jb[2]
110 | set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { JB[3] }]; #IO_L13N_T2_MRCC_15 Sch=jb[3]
111 | set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { JB[4] }]; #IO_L15P_T2_DQS_15 Sch=jb[4]
112 | set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { JB[7] }]; #IO_L11N_T1_SRCC_15 Sch=jb[7]
113 | set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { JB[8] }]; #IO_L5P_T0_AD9P_15 Sch=jb[8]
114 | set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { JB[9] }]; #IO_0_15 Sch=jb[9]
115 | set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { JB[10] }]; #IO_L13P_T2_MRCC_15 Sch=jb[10]
116 |
117 |
118 | #Pmod Header JC
119 |
120 | set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { JC[1] }]; #IO_L23N_T3_35 Sch=jc[1]
121 | set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { JC[2] }]; #IO_L19N_T3_VREF_35 Sch=jc[2]
122 | set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { JC[3] }]; #IO_L22N_T3_35 Sch=jc[3]
123 | set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { JC[4] }]; #IO_L19P_T3_35 Sch=jc[4]
124 | set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS33 } [get_ports { JC[7] }]; #IO_L6P_T0_35 Sch=jc[7]
125 | set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { JC[8] }]; #IO_L22P_T3_35 Sch=jc[8]
126 | set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { JC[9] }]; #IO_L21P_T3_DQS_35 Sch=jc[9]
127 | set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { JC[10] }]; #IO_L5P_T0_AD13P_35 Sch=jc[10]
128 |
129 |
130 | #Pmod Header JD
131 |
132 | set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { JD[1] }]; #IO_L21N_T3_DQS_35 Sch=jd[1]
133 | set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { JD[2] }]; #IO_L17P_T2_35 Sch=jd[2]
134 | set_property -dict { PACKAGE_PIN G1 IOSTANDARD LVCMOS33 } [get_ports { JD[3] }]; #IO_L17N_T2_35 Sch=jd[3]
135 | set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { JD[4] }]; #IO_L20N_T3_35 Sch=jd[4]
136 | set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { JD[7] }]; #IO_L15P_T2_DQS_35 Sch=jd[7]
137 | set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { JD[8] }]; #IO_L20P_T3_35 Sch=jd[8]
138 | set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { JD[9] }]; #IO_L15N_T2_DQS_35 Sch=jd[9]
139 | set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { JD[10] }]; #IO_L13N_T2_MRCC_35 Sch=jd[10]
140 |
141 |
142 | #Pmod Header JXADC
143 |
144 | set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVDS } [get_ports { XA_N[1] }]; #IO_L9N_T1_DQS_AD3N_15 Sch=xa_n[1]
145 | set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVDS } [get_ports { XA_P[1] }]; #IO_L9P_T1_DQS_AD3P_15 Sch=xa_p[1]
146 | set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVDS } [get_ports { XA_N[2] }]; #IO_L8N_T1_AD10N_15 Sch=xa_n[2]
147 | set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVDS } [get_ports { XA_P[2] }]; #IO_L8P_T1_AD10P_15 Sch=xa_p[2]
148 | set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVDS } [get_ports { XA_N[3] }]; #IO_L7N_T1_AD2N_15 Sch=xa_n[3]
149 | set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVDS } [get_ports { XA_P[3] }]; #IO_L7P_T1_AD2P_15 Sch=xa_p[3]
150 | set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVDS } [get_ports { XA_N[4] }]; #IO_L10N_T1_AD11N_15 Sch=xa_n[4]
151 | set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVDS } [get_ports { XA_P[4] }]; #IO_L10P_T1_AD11P_15 Sch=xa_p[4]
152 |
153 |
154 | #VGA Connector
155 |
156 | set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[0] }]; #IO_L8N_T1_AD14N_35 Sch=vga_r[0]
157 | set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[1] }]; #IO_L7N_T1_AD6N_35 Sch=vga_r[1]
158 | set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[2] }]; #IO_L1N_T0_AD4N_35 Sch=vga_r[2]
159 | set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[3] }]; #IO_L8P_T1_AD14P_35 Sch=vga_r[3]
160 |
161 | set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[0] }]; #IO_L1P_T0_AD4P_35 Sch=vga_g[0]
162 | set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=vga_g[1]
163 | set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[2] }]; #IO_L2N_T0_AD12N_35 Sch=vga_g[2]
164 | set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[3] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=vga_g[3]
165 |
166 | set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[0] }]; #IO_L2P_T0_AD12P_35 Sch=vga_b[0]
167 | set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[1] }]; #IO_L4N_T0_35 Sch=vga_b[1]
168 | set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[2] }]; #IO_L6N_T0_VREF_35 Sch=vga_b[2]
169 | set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[3] }]; #IO_L4P_T0_35 Sch=vga_b[3]
170 |
171 | set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { VGA_HS }]; #IO_L4P_T0_15 Sch=vga_hs
172 | set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { VGA_VS }]; #IO_L3N_T0_DQS_AD1N_15 Sch=vga_vs
173 |
174 |
175 | #Micro SD Connector
176 |
177 | set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { SD_RESET }]; #IO_L14P_T2_SRCC_35 Sch=sd_reset
178 | set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { SD_CD }]; #IO_L9N_T1_DQS_AD7N_35 Sch=sd_cd
179 | set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { SD_SCK }]; #IO_L9P_T1_DQS_AD7P_35 Sch=sd_sck
180 | set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { SD_CMD }]; #IO_L16N_T2_35 Sch=sd_cmd
181 | set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[0] }]; #IO_L16P_T2_35 Sch=sd_dat[0]
182 | set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[1] }]; #IO_L18N_T2_35 Sch=sd_dat[1]
183 | set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[2] }]; #IO_L18P_T2_35 Sch=sd_dat[2]
184 | set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[3] }]; #IO_L14N_T2_SRCC_35 Sch=sd_dat[3]
185 |
186 |
187 | #Accelerometer
188 |
189 | set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { ACL_MISO }]; #IO_L11P_T1_SRCC_15 Sch=acl_miso
190 | set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports { ACL_MOSI }]; #IO_L5N_T0_AD9N_15 Sch=acl_mosi
191 | set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { ACL_SCLK }]; #IO_L14P_T2_SRCC_15 Sch=acl_sclk
192 | set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { ACL_CSN }]; #IO_L12P_T1_MRCC_15 Sch=acl_csn
193 | set_property -dict { PACKAGE_PIN B13 IOSTANDARD LVCMOS33 } [get_ports { ACL_INT[1] }]; #IO_L2P_T0_AD8P_15 Sch=acl_int[1]
194 | set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { ACL_INT[2] }]; #IO_L20P_T3_A20_15 Sch=acl_int[2]
195 |
196 |
197 | #Temperature Sensor
198 |
199 | set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { TMP_SCL }]; #IO_L1N_T0_AD0N_15 Sch=tmp_scl
200 | set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { TMP_SDA }]; #IO_L12N_T1_MRCC_15 Sch=tmp_sda
201 | set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports { TMP_INT }]; #IO_L6N_T0_VREF_15 Sch=tmp_int
202 | set_property -dict { PACKAGE_PIN B14 IOSTANDARD LVCMOS33 } [get_ports { TMP_CT }]; #IO_L2N_T0_AD8N_15 Sch=tmp_ct
203 |
204 | #Omnidirectional Microphone
205 |
206 | set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { M_CLK }]; #IO_25_35 Sch=m_clk
207 | set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { M_DATA }]; #IO_L24N_T3_35 Sch=m_data
208 | set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 } [get_ports { M_LRSEL }]; #IO_0_35 Sch=m_lrsel
209 |
210 |
211 | #PWM Audio Amplifier
212 |
213 | set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { AUD_PWM }]; #IO_L4N_T0_15 Sch=aud_pwm
214 | set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { AUD_SD }]; #IO_L6P_T0_15 Sch=aud_sd
215 |
216 |
217 | #USB-RS232 Interface
218 |
219 | set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { UART_TXD_IN }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
220 | set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { UART_RXD_OUT }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out
221 | set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { UART_CTS }]; #IO_L12N_T1_MRCC_35 Sch=uart_cts
222 | set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { UART_RTS }]; #IO_L5N_T0_AD13N_35 Sch=uart_rts
223 |
224 | #USB HID (PS/2)
225 |
226 | set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { PS2_CLK }]; #IO_L13P_T2_MRCC_35 Sch=ps2_clk
227 | set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { PS2_DATA }]; #IO_L10N_T1_AD15N_35 Sch=ps2_data
228 |
229 |
230 | #SMSC Ethernet PHY
231 |
232 | set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { ETH_MDC }]; #IO_L11P_T1_SRCC_16 Sch=eth_mdc
233 | set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { ETH_MDIO }]; #IO_L14N_T2_SRCC_16 Sch=eth_mdio
234 | set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { ETH_RSTN }]; #IO_L10P_T1_AD15P_35 Sch=eth_rstn
235 | set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { ETH_CRSDV }]; #IO_L6N_T0_VREF_16 Sch=eth_crsdv
236 | set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXERR }]; #IO_L13N_T2_MRCC_16 Sch=eth_rxerr
237 | set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXD[0] }]; #IO_L13P_T2_MRCC_16 Sch=eth_rxd[0]
238 | set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXD[1] }]; #IO_L19N_T3_VREF_16 Sch=eth_rxd[1]
239 | set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXEN }]; #IO_L11N_T1_SRCC_16 Sch=eth_txen
240 | set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXD[0] }]; #IO_L14P_T2_SRCC_16 Sch=eth_txd[0]
241 | set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXD[1] }]; #IO_L12N_T1_MRCC_16 Sch=eth_txd[1]
242 | set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { ETH_REFCLK }]; #IO_L11P_T1_SRCC_35 Sch=eth_refclk
243 | set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { ETH_INTN }]; #IO_L12P_T1_MRCC_16 Sch=eth_intn
244 |
245 |
246 | #Quad SPI Flash
247 |
248 | set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[0] }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0]
249 | set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[1] }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1]
250 | set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[2] }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2]
251 | set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[3] }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3]
252 | set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { QSPI_CSN }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_csn
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
--------------------------------------------------------------------------------
/experiment/lab2/decoder.sv:
--------------------------------------------------------------------------------
1 | `timescale 1ns / 1ps
2 | //////////////////////////////////////////////////////////////////////////////////
3 | // Company:
4 | // Engineer:
5 | //
6 | // Create Date: 2020/10/10 23:17:35
7 | // Design Name:
8 | // Module Name: decoder
9 | // Project Name:
10 | // Target Devices:
11 | // Tool Versions:
12 | // Description:
13 | //
14 | // Dependencies:
15 | //
16 | // Revision:
17 | // Revision 0.01 - File Created
18 | // Additional Comments:
19 | //
20 | //////////////////////////////////////////////////////////////////////////////////
21 |
22 |
23 | module lab2(
24 | input logic [31:0]instr,
25 | output logic [ 7:0]aluout
26 | );
27 |
28 | logic [3:0]alucontrol;
29 | logic wmem;
30 | logic rmem;
31 | logic jump;
32 | logic [5:0] op, funct;
33 |
34 | logic [7:0]imm1;
35 | logic [7:0]imm2;
36 | logic [2:0]shamt;
37 |
38 | assign op = instr[31:26];
39 | assign imm1 = instr[25:18];
40 | assign imm2 = instr[17:10];
41 | assign shamt = instr[9:7];
42 | assign funct = instr[5:0];
43 |
44 | always_comb
45 | begin
46 | unique case(op)
47 | 6'b000000:begin
48 | unique case(funct)
49 | 6'b100000:alucontrol = 4'b0001;
50 | 6'b100010:alucontrol = 4'b0010;
51 | 6'b101010:alucontrol = 4'b0011;
52 | 6'b100100:alucontrol = 4'b0100;
53 | 6'b100111:alucontrol = 4'b0101;
54 | 6'b100101:alucontrol = 4'b0110;
55 | 6'b100110:alucontrol = 4'b0111;
56 | 6'b101111:alucontrol = 4'b1000;
57 | 6'b000000:alucontrol = 4'b1001;
58 | 6'b000010:alucontrol = 4'b1010;
59 | 6'b000011:alucontrol = 4'b1011;
60 | default: alucontrol = 4'b0000;
61 | endcase
62 | end
63 | default:alucontrol = 4'b0000;
64 | endcase
65 | end
66 |
67 | assign rmem = (op == 6'b100011);
68 | assign wmem = (op == 6'b101011);
69 | assign jump = (op == 6'b000010) || (op == 6'b000100 && imm1 == imm2) || (op == 6'b000101 && imm1 != imm2);
70 |
71 | always_comb
72 | begin
73 | unique case(alucontrol)
74 | 4'b0001: aluout = imm1 + imm2 ;
75 | 4'b0010: aluout = imm1 - imm2 ;
76 | 4'b0011: aluout = signed'(imm1) < signed'(imm2) ;
77 | 4'b0100: aluout = imm1 & imm2 ;
78 | 4'b0101: aluout = ~(imm1 | imm2) ;
79 | 4'b0110: aluout = imm1 | imm2 ;
80 | 4'b0111: aluout = imm1 ^ imm2 ;
81 | 4'b1000: aluout = ~imm1 ;
82 | 4'b1001: aluout = imm1 << shamt ;
83 | 4'b1010: aluout = imm1 >> shamt ;
84 | 4'b1011: aluout = (imm1) >>> shamt ;
85 | default: aluout = '0 ;
86 | endcase
87 | end
88 |
89 |
90 |
91 | endmodule
92 |
--------------------------------------------------------------------------------
/experiment/lab2/display/lab2.drawio:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/experiment/lab2/imem.sv:
--------------------------------------------------------------------------------
1 | `include "ref.svh"
2 | module imem (
3 | input logic [7:0] id,
4 | output instruction_t instr
5 | );
6 |
7 | logic [0:255][31:0]imem;
8 | always_comb begin
9 | instr = '0;
10 | for (int i = 0; i < 256; i++) begin
11 | if (id == i) begin
12 | instr = imem[i];
13 | end
14 | end
15 | end
16 |
17 |
18 | assign imem = {
19 | 32'h00a24183,
20 | 32'h00be0503,
21 | 32'h017aa4aa,
22 | 32'h00222a20,
23 | 32'h03c5d526,
24 | 32'h0208c100,
25 | 32'h017f6280,
26 | 32'h006bb582,
27 | 32'h00e43ea4,
28 | 32'h025b7d25,
29 | 32'h00ebcaa2,
30 | 32'h11cca500,
31 | 32'h0172bea2,
32 | 32'h03b88783,
33 | 32'h032d2127,
34 | 32'h0376e003,
35 | 32'h02d45427,
36 | 32'h038d69a0,
37 | 32'h0192dba2,
38 | 32'h03aaa4a2,
39 | 32'h14b4de00,
40 | 32'h031a9da5,
41 | 32'h02703e22,
42 | 32'h01864e20,
43 | 32'h01e30083,
44 | 32'h8f3ef280,
45 | 32'h14fb9780,
46 | 32'h138e6e80,
47 | 32'h0380252f,
48 | 32'h03a98282,
49 | 32'h0379f3a0,
50 | 32'h009764aa,
51 | 32'h0001e883,
52 | 32'h02b8542a,
53 | 32'h0019cfa6,
54 | 32'h01467100,
55 | 32'h014425aa,
56 | 32'h01a8a825,
57 | 32'h162b2280,
58 | 32'h033f7ea4,
59 | 32'h02a66783,
60 | 32'h11819400,
61 | 32'h01787ea4,
62 | 32'h00842827,
63 | 32'h01c08c27,
64 | 32'h03173226,
65 | 32'h025daba6,
66 | 32'h01fd3680,
67 | 32'h00289b03,
68 | 32'h03d70a2f,
69 | 32'h02ada8aa,
70 | 32'h007d2ca6,
71 | 32'h0099f3a7,
72 | 32'had5b9b00,
73 | 32'h02a2a383,
74 | 32'h017bfb00,
75 | 32'h0102bb24,
76 | 32'h00efc7a4,
77 | 32'h142d4500,
78 | 32'h009f7702,
79 | 32'h01c6f7a0,
80 | 32'h00212fa7,
81 | 32'h104ed100,
82 | 32'h01d3c7a7,
83 | 32'h09558400,
84 | 32'h01ef5582,
85 | 32'h017f0127,
86 | 32'h024b1627,
87 | 32'h032608a4,
88 | 32'h00c3b2a6,
89 | 32'h0378bb83,
90 | 32'h169b5180,
91 | 32'h02b6d2a5,
92 | 32'h005d2683,
93 | 32'h14d62480,
94 | 32'h0360a02f,
95 | 32'h02150020,
96 | 32'h084c3300,
97 | 32'h03db0327,
98 | 32'h02b439af,
99 | 32'h02a98d24,
100 | 32'h00c03082,
101 | 32'h01d148a7,
102 | 32'h02db6da5,
103 | 32'h0807b680,
104 | 32'h0170a402,
105 | 32'h010f6aa7,
106 | 32'h01194220,
107 | 32'h01f8b322,
108 | 32'h012ce326,
109 | 32'h0384aa26,
110 | 32'h00856b2a,
111 | 32'h168fad80,
112 | 32'h11095900,
113 | 32'h01f72e83,
114 | 32'h01ea33a0,
115 | 32'h03640e2a,
116 | 32'h0143a327,
117 | 32'h01ab57a0,
118 | 32'h030f7100,
119 | 32'h0067eaaf,
120 | 32'h03ebc6a5,
121 | 32'h0314fba0,
122 | 32'h02884424,
123 | 32'h0b280480,
124 | 32'h0046c525,
125 | 32'h013c532f,
126 | 32'h00c90722,
127 | 32'h01a6c683,
128 | 32'h03759a00,
129 | 32'h01252c20,
130 | 32'h02cd7caf,
131 | 32'h03504820,
132 | 32'h01b5ec24,
133 | 32'h03457eaa,
134 | 32'h035f2026,
135 | 32'h00427780,
136 | 32'h03feed25,
137 | 32'h037e1825,
138 | 32'h02c59100,
139 | 32'h00e2bb83,
140 | 32'h09453600,
141 | 32'h00c3d683,
142 | 32'h01dfa826,
143 | 32'h0046f980,
144 | 32'h01384ca2,
145 | 32'h8c161500,
146 | 32'h0088ae27,
147 | 32'h00c374a7,
148 | 32'h03b781af,
149 | 32'h03ef9025,
150 | 32'h03335203,
151 | 32'h0229b582,
152 | 32'h00968aa0,
153 | 32'h02937302,
154 | 32'h01a8172a,
155 | 32'h12226d80,
156 | 32'h03beae22,
157 | 32'h005713a0,
158 | 32'h00da9826,
159 | 32'h02912aa2,
160 | 32'h038efd22,
161 | 32'h021d2326,
162 | 32'h037405a7,
163 | 32'h02f6d5a5,
164 | 32'h00c87925,
165 | 32'h03befba0,
166 | 32'h028f84aa,
167 | 32'h0362f4a6,
168 | 32'h00b3e602,
169 | 32'h013f75a7,
170 | 32'h0028bc03,
171 | 32'h0236a6a4,
172 | 32'h014feea7,
173 | 32'h0328b12a,
174 | 32'h00106200,
175 | 32'h03e83fa0,
176 | 32'h02494922,
177 | 32'h03450b03,
178 | 32'h0065c32f,
179 | 32'h0061c3a4,
180 | 32'h0bfa9500,
181 | 32'h0031f3af,
182 | 32'h019024a5,
183 | 32'had299c80,
184 | 32'h01564126,
185 | 32'h03e0ce03,
186 | 32'h02f98802,
187 | 32'h005c2b24,
188 | 32'h02d300a5,
189 | 32'h01b48a03,
190 | 32'h013929af,
191 | 32'h03e9d883,
192 | 32'h8cd4d200,
193 | 32'h01c704a4,
194 | 32'h02196ea5,
195 | 32'h033632a5,
196 | 32'h02745c22,
197 | 32'h00dcb622,
198 | 32'h10925680,
199 | 32'h01cc71af,
200 | 32'h01ff9a22,
201 | 32'h01e4e2aa,
202 | 32'h00ced7a4,
203 | 32'h8e200e80,
204 | 32'h02317aa5,
205 | 32'h03c57e20,
206 | 32'h02338580,
207 | 32'h00d696a5,
208 | 32'h01714726,
209 | 32'h00d0f5a4,
210 | 32'h03cbf325,
211 | 32'h011f1c83,
212 | 32'h8ef6c180,
213 | 32'h004f6a25,
214 | 32'h02936824,
215 | 32'h03ecb5a7,
216 | 32'h038bc920,
217 | 32'h03d831a0,
218 | 32'h000ef6a5,
219 | 32'h03c5ef25,
220 | 32'h002a9da7,
221 | 32'h038b44af,
222 | 32'h021b5fa5,
223 | 32'h03b45aa4,
224 | 32'h0155eaa6,
225 | 32'h0199bf2a,
226 | 32'h08e69b80,
227 | 32'h026627a5,
228 | 32'h01bac903,
229 | 32'h013f5682,
230 | 32'h019da802,
231 | 32'h028f882a,
232 | 32'h01c93a26,
233 | 32'h001401af,
234 | 32'h02f19e2f,
235 | 32'h018f38a5,
236 | 32'h007b55a5,
237 | 32'h0048f3af,
238 | 32'h01258b00,
239 | 32'h02681ea5,
240 | 32'h022f1aa0,
241 | 32'h13cd4480,
242 | 32'h035d9e2f,
243 | 32'h031bd6af,
244 | 32'h01acaa83,
245 | 32'h00b5cea7,
246 | 32'h036ab4af,
247 | 32'h037efaa6,
248 | 32'h001bf6a5,
249 | 32'h035c4103,
250 | 32'h034e0020,
251 | 32'h01559b83,
252 | 32'h000440a2,
253 | 32'h0a6e5b00,
254 | 32'h08a0c000,
255 | 32'h8f43fc00,
256 | 32'h019f88a7,
257 | 32'h039cea26,
258 | 32'h00b196a5,
259 | 32'h018a6903,
260 | 32'h018c4300,
261 | 32'h02ee0226,
262 | 32'h00843a00,
263 | 32'h02be68a0,
264 | 32'h024849a0,
265 | 32'h0127cd24,
266 | 32'h03b98702,
267 | 32'h001fcaa2,
268 | 32'h008bca24,
269 | 32'h00664022,
270 | 32'h0170462f,
271 | 32'h02d93ca2,
272 | 32'h0316f880,
273 | 32'h00e1bf22,
274 | 32'h03132f00
275 | };
276 | endmodule
--------------------------------------------------------------------------------
/experiment/lab2/lab2.sv:
--------------------------------------------------------------------------------
1 | `include "lab2.svh"
2 | module lab2 (
3 | input logic [31:0]instr,
4 | output logic [7:0]aluout
5 | );
6 | // TODO: add signal declaration here
7 |
8 | decoder myDecoder(
9 | // TODO: add ports here
10 | .instr
11 | );
12 |
13 | alu myALU(
14 | // TODO: add ports here
15 | );
16 |
17 | endmodule
18 |
19 | module decoder (
20 | // TODO: add port declaration here
21 | input logic [31:0] instr,
22 | output myALUfunc_t alufunc,
23 | output logic [7:0] imm1, imm2,
24 | output logic [2:0] shamt
25 | );
26 | // TODO: add logic here
27 | assign imm1 = instr[25:18];
28 | assign imm2 = instr[17:10];
29 | assign shamt = instr[9:7];
30 |
31 | /*
32 | ADD: 4'b0000;
33 | SUB: 4'b0001;
34 | */
35 |
36 | always_comb begin
37 | alufunc = RES;
38 | unique case(instr[31:26])
39 | OP_ALU: begin
40 | unique case(instr[5:0])
41 | F_ADD: begin
42 | alufunc = ALU_ADD;
43 | end
44 | F_SUB: begin
45 | alufunc = ALU_SUB;
46 | end
47 | default: begin
48 |
49 | end
50 | endcase
51 | end
52 | default: begin
53 |
54 | end
55 | endcase
56 | end
57 |
58 | endmodule
59 |
60 | module alu (
61 | // TODO: add port declaration here
62 | );
63 | // TODO: add logic here
64 |
65 | endmodule
66 |
--------------------------------------------------------------------------------
/experiment/lab2/lab2.svh:
--------------------------------------------------------------------------------
1 | `ifndef __LAB2_SVH
2 | `define __LAB2_SVH
3 |
4 | // fixed encoding
5 |
6 | parameter OP_ALU = 6'b000000;
7 |
8 | parameter F_ADD = 6'b100000;
9 | parameter F_SUB = 6'b100010;
10 |
11 | // flexible encoding
12 |
13 | typedef enum logic [3:0] {
14 | ALU_ADD, ALU_SUB, RES
15 | } myALUfunc_t;
16 |
17 |
18 | `endif
19 |
--------------------------------------------------------------------------------
/experiment/lab2/myans.sv:
--------------------------------------------------------------------------------
1 | `include "ref.svh"
2 | (* keep = "true" *)module ans (
3 | input instruction_t instr,
4 | output byte_t aluout,
5 | output decoded_op_t decoded_op,
6 | output alufunc_t alufunc,
7 | output logic memread,
8 | output logic memwrite,
9 | output logic branch_taken,
10 | output logic is_alu
11 | );
12 | decode_data_t decode_data;
13 | byte_t imm1, imm2;
14 | assign imm1 = instr[25:18];
15 | assign imm2 = instr[17:10];
16 |
17 | shamt_t shamt;
18 | assign shamt = instr[9:7];
19 |
20 | decoder_ref decoder_ref(.instr,
21 | .decode_data,
22 | .is_alu);
23 |
24 | alu_ref alu_ref(.src1(imm1),
25 | .src2(imm2),
26 | .shamt(shamt),
27 | .alufunc(decode_data.alufunc),
28 | .aluout(aluout));
29 |
30 | assign decoded_op = decode_data.op;
31 | assign alufunc = decode_data.alufunc;
32 | assign memread = decode_data.memread;
33 | assign memwrite = decode_data.memwrite;
34 | assign branch_taken = decode_data.branch_taken;
35 | endmodule
36 |
37 | module decoder_ref (
38 | input instruction_t instr,
39 | output decode_data_t decode_data,
40 | output logic is_alu
41 | );
42 | byte_t imm1, imm2;
43 | assign imm1 = instr[25:18];
44 | assign imm2 = instr[17:10];
45 |
46 | op_t op;
47 | assign op = instr[31:26];
48 |
49 | func_t func;
50 | assign func = instr[5:0];
51 | always_comb begin
52 | decode_data = '0;
53 | is_alu = '0;
54 | unique case(op)
55 | OP_ALU_REF: begin
56 | is_alu = 1'b1;
57 | unique case(func)
58 | F_ADD_REF: begin
59 | decode_data.op = ADD_REF;
60 | decode_data.alufunc = ALU_ADD_REF;
61 | end
62 | F_SUB_REF: begin
63 | decode_data.op = SUB_REF;
64 | decode_data.alufunc = ALU_SUB_REF;
65 | end
66 | F_SLT_REF: begin
67 | decode_data.op = SLT_REF;
68 | decode_data.alufunc = ALU_SLT_REF;
69 | end
70 | F_AND_REF: begin
71 | decode_data.op = AND_REF;
72 | decode_data.alufunc = ALU_AND_REF;
73 | end
74 | F_NOR_REF: begin
75 | decode_data.op = NOR_REF;
76 | decode_data.alufunc = ALU_NOR_REF;
77 | end
78 | F_OR_REF: begin
79 | decode_data.op = OR_REF;
80 | decode_data.alufunc = ALU_OR_REF;
81 | end
82 | F_XOR_REF: begin
83 | decode_data.op = XOR_REF;
84 | decode_data.alufunc = ALU_XOR_REF;
85 | end
86 | F_NOT_REF: begin
87 | decode_data.op = NOT_REF;
88 | decode_data.alufunc = ALU_NOT_REF;
89 | end
90 | F_SLL_REF: begin
91 | decode_data.op = SLL_REF;
92 | decode_data.alufunc = ALU_SLL_REF;
93 | end
94 | F_SRL_REF: begin
95 | decode_data.op = SRL_REF;
96 | decode_data.alufunc = ALU_SRL_REF;
97 | end
98 | F_SRA_REF: begin
99 | decode_data.op = SRA_REF;
100 | decode_data.alufunc = ALU_SRA_REF;
101 | end
102 | default: begin
103 | is_alu = 1'b0;
104 | end
105 | endcase
106 | end
107 | OP_LW_REF: begin
108 | decode_data.op = LW_REF;
109 | decode_data.memread = 1'b1;
110 | end
111 | OP_SW_REF: begin
112 | decode_data.op = SW_REF;
113 | decode_data.memwrite = 1'b1;
114 | end
115 | OP_J_REF: begin
116 | decode_data.op = J_REF;
117 | decode_data.branch_taken = 1'b1;
118 | end
119 | OP_BEQ_REF: begin
120 | decode_data.op = BEQ_REF;
121 | decode_data.branch_taken = imm1 == imm2;
122 | end
123 | OP_BNE_REF: begin
124 | decode_data.op = BNE_REF;
125 | decode_data.branch_taken = imm1 != imm2;
126 | end
127 | default: begin
128 |
129 | end
130 | endcase
131 | end
132 | endmodule
133 |
134 | module alu_ref (
135 | input byte_t src1, src2,
136 | input shamt_t shamt,
137 | input alufunc_t alufunc,
138 | output byte_t aluout
139 | );
140 | always_comb begin
141 | unique case(alufunc)
142 | ALU_ADD_REF: begin
143 | aluout = src1 + src2;
144 | end
145 | ALU_SUB_REF: begin
146 | aluout = src1 - src2;
147 | end
148 | ALU_SLT_REF: begin
149 | aluout = signed'(src1) < signed'(src2);
150 | end
151 | ALU_AND_REF: begin
152 | aluout = src1 & src2;
153 | end
154 | ALU_NOR_REF: begin
155 | aluout = ~(src1 | src2);
156 | end
157 | ALU_OR_REF: begin
158 | aluout = src1 | src2;
159 | end
160 | ALU_XOR_REF: begin
161 | aluout = src1 ^ src2;
162 | end
163 | ALU_NOT_REF: begin
164 | aluout = ~src1;
165 | end
166 | ALU_SLL_REF: begin
167 | aluout = src1 << shamt;
168 | end
169 | ALU_SRL_REF: begin
170 | aluout = src1 >> shamt;
171 | end
172 | ALU_SRA_REF: begin
173 | aluout = signed'(src1) >>> shamt;
174 | end
175 | default: begin
176 | aluout = '0;
177 | end
178 | endcase
179 | end
180 | endmodule
181 |
--------------------------------------------------------------------------------
/experiment/lab2/readme.md:
--------------------------------------------------------------------------------
1 | # lab2注意事项
2 |
3 | `DEADLINE: 2020-11-3 23:59:59`
4 |
5 | ## 新建项目
6 |
7 | 先新建一个项目。
8 |
9 | 然后在点击`Tools --> Run Tcl Script`,运行本目录下的 `sources.tcl`添加文件。
10 |
11 | 
12 |
13 | 随后,在 `lab2.sv`中填写代码。
14 |
15 | ## 需要完成的代码
16 |
17 | 你需要完成`lab2.sv`。
18 |
19 | ```verilog
20 | module lab2 (
21 | input logic [31:0]instr,
22 | output logic [7:0]aluout
23 | );
24 | // TODO: add signal declaration here
25 |
26 | decoder myDecoder(
27 | // TODO: add ports here
28 | );
29 |
30 | alu myALU(
31 | // TODO: add ports here
32 | );
33 |
34 | endmodule
35 |
36 | module decoder (
37 | // TODO: add port declaration here
38 |
39 | );
40 | // TODO: add logic here
41 |
42 | endmodule
43 |
44 | module alu (
45 | // TODO: add port declaration here
46 | );
47 | // TODO: add logic here
48 |
49 | endmodule
50 |
51 | ```
52 |
53 |
54 |
55 | ## 仿真
56 |
57 | 仿真文件`sim.sv`集成了本实验的测试。
58 |
59 | 调试`decoder`模块时,只能通过看波形图的方式检查。
60 |
61 | 当你开始调试`ALU`时,请把`debug_en`设为`1'b1`。
62 |
63 | ```verilog
64 | // TODO: to debug alu, set this to 1'b1
65 | assign debug_en = 1'b0;
66 | ```
67 |
68 | 开始仿真后,点击 `Run all`, 使仿真跑完:
69 |
70 | 当你修改过源文件后,点击`relaunch simulation`重新发起仿真。
71 |
72 | 
73 |
74 | ## 上板
75 |
76 | `11月2日`的实验课上板。你可以提前 `generate bitstream`,下节实验课上直接 `program device`。
77 |
78 |
--------------------------------------------------------------------------------
/experiment/lab2/ref.svh:
--------------------------------------------------------------------------------
1 | `ifndef __REF_SVH
2 | `define __REF_SVH
3 |
4 | typedef logic[31:0] instruction_t;
5 | typedef logic[7:0] byte_t;
6 | typedef logic[5:0] op_t; // instr[31:26], before decode
7 | typedef logic[5:0] func_t;
8 | typedef logic[2:0] shamt_t;
9 |
10 |
11 | // op
12 | parameter OP_ALU_REF = 6'b000000;
13 | parameter OP_LW_REF = 6'b100011;
14 | parameter OP_SW_REF = 6'b101011;
15 | parameter OP_J_REF = 6'b000010;
16 | parameter OP_BEQ_REF = 6'b000100;
17 | parameter OP_BNE_REF = 6'b000101;
18 |
19 | // funct
20 | parameter F_ADD_REF = 6'b100000;
21 | parameter F_SUB_REF = 6'b100010;
22 | parameter F_SLT_REF = 6'b101010;
23 | parameter F_AND_REF = 6'b100100;
24 | parameter F_NOR_REF = 6'b100111;
25 | parameter F_OR_REF = 6'b100101;
26 | parameter F_XOR_REF = 6'b100110;
27 | parameter F_NOT_REF = 6'b101111;
28 | parameter F_SLL_REF = 6'b000000;
29 | parameter F_SRL_REF = 6'b000010;
30 | parameter F_SRA_REF = 6'b000011;
31 |
32 | typedef enum logic [3:0] {
33 | ADD_REF, SUB_REF, SLT_REF,
34 | AND_REF, NOR_REF, OR_REF,
35 | XOR_REF, NOT_REF, SLL_REF,
36 | SRL_REF, SRA_REF, LW_REF,
37 | SW_REF, J_REF, BEQ_REF,
38 | BNE_REF
39 | } decoded_op_t;
40 |
41 | typedef enum logic [3:0] {
42 | ALU_ADD_REF, ALU_SUB_REF, ALU_SLT_REF,
43 | ALU_AND_REF, ALU_NOR_REF, ALU_OR_REF,
44 | ALU_XOR_REF, ALU_NOT_REF, ALU_SLL_REF,
45 | ALU_SRL_REF, ALU_SRA_REF
46 | } alufunc_t;
47 |
48 | typedef struct packed {
49 | decoded_op_t op;
50 | alufunc_t alufunc;
51 | logic memread;
52 | logic memwrite;
53 | logic branch_taken;
54 | } decode_data_t;
55 |
56 |
57 | `endif
58 |
--------------------------------------------------------------------------------
/experiment/lab2/sim.sv:
--------------------------------------------------------------------------------
1 | `include "ref.svh"
2 | module sim (
3 |
4 | );
5 | logic debug_en;
6 |
7 | // TODO: to debug alu, set this to 1'b1
8 | assign debug_en = 1'b0;
9 |
10 | instruction_t instr;
11 | byte_t aluout_ans, aluout, aluout_check;
12 | // decode_data_t decode_data_ans;
13 | logic [3:0] temp1, temp2;
14 | decoded_op_t decoded_op;
15 | assign decoded_op = decoded_op_t'(temp1);
16 | alufunc_t alufunc;
17 | assign alufunc = alufunc_t'(temp2);
18 | logic memread;
19 | logic memwrite;
20 | logic branch_taken;
21 | logic is_alu;
22 |
23 | ans sim_ans(.instr,
24 | .aluout(aluout_ans),
25 | .is_alu,
26 | .decoded_op(temp1),
27 | .alufunc(temp2),
28 | .*
29 | );
30 | lab2 sim_lab2(.instr,
31 | .aluout(aluout));
32 |
33 | assign aluout_check = (debug_en) ? aluout : aluout_ans;
34 | logic[8:0] counter, counter_nxt;
35 | logic clk, resetn;
36 | always #5 clk = ~clk;
37 | initial begin
38 | clk = 1'b0;
39 | resetn = 1'b0;
40 | #100 resetn = 1'b1;
41 | end
42 | always_ff @(posedge clk) begin
43 | if ( ~resetn ) begin
44 | counter <= '0;
45 | end else begin
46 | counter <= counter_nxt;
47 | end
48 | end
49 | always_comb begin
50 | counter_nxt = counter;
51 | if (counter != 9'h100 && (~is_alu || (aluout_ans === aluout_check))) begin
52 | counter_nxt = counter_nxt + 1;
53 | end
54 | end
55 |
56 | always_ff @(posedge clk) begin
57 | if (~resetn) begin
58 |
59 | end else if (counter == 9'h100) begin
60 | $display("PASS!\n");
61 | $finish;
62 | end
63 | else if (~(~is_alu || (aluout_ans === aluout_check))) begin
64 | $display("[%d ns]: ALUOUT expected 0x%x, got 0x%x!\n",
65 | $time, aluout_ans, aluout_check);
66 | $finish;
67 | end
68 | end
69 |
70 |
71 |
72 | imem imem(.instr, .id(counter[7:0]));
73 | endmodule
74 |
--------------------------------------------------------------------------------
/experiment/lab2/sources.tcl:
--------------------------------------------------------------------------------
1 | cd [file dirname [info script]]
2 | add_files ans.v
3 | add_files top.sv
4 | add_files lab2.sv
5 | add_files imem.sv
6 | add_files ref.svh
7 | set_property top top [current_fileset]
8 |
9 | cd [file dirname [info script]]
10 | add_files -fileset constrs_1 -norecurse Nexys4DDR_Master.xdc
11 |
12 | set_property SOURCE_SET sources_1 [get_filesets sim_1]
13 | add_files -fileset sim_1 -norecurse sim.sv
14 | set_property top sim [get_filesets sim_1]
15 | set_property top_lib xil_defaultlib [get_filesets sim_1]
16 |
17 | set_param general.maxThreads 16
--------------------------------------------------------------------------------
/experiment/lab2/top.sv:
--------------------------------------------------------------------------------
1 | `include "ref.svh"
2 | module top (
3 | input logic clk, resetn,
4 | output logic LED16_G, LED16_R, LED17_G
5 | );
6 |
7 | instruction_t instr;
8 | byte_t aluout_ans, aluout, aluout_check;
9 | logic is_alu;
10 |
11 | ans sim_ans(.instr,
12 | .aluout(aluout_ans),
13 | .is_alu
14 | );
15 | lab2 sim_lab2(.instr,
16 | .aluout(aluout));
17 |
18 | assign aluout_check = aluout;
19 | logic[8:0] counter, counter_nxt;
20 |
21 | logic [15:0]clk_counter;
22 | always_ff @(posedge clk) begin
23 | if (~resetn) begin
24 | clk_counter <= '0;
25 |
26 | end
27 | else begin
28 | clk_counter <= clk_counter + 1;
29 | end
30 | end
31 | always_ff @(posedge clk_counter[6], negedge resetn) begin
32 | if ( ~resetn ) begin
33 | counter <= '0;
34 | end else begin
35 | counter <= counter_nxt;
36 | end
37 | end
38 | always_comb begin
39 | counter_nxt = counter;
40 | if (counter != 9'h100 && (~is_alu || (aluout_ans === aluout_check))) begin
41 | counter_nxt = counter_nxt + 1;
42 | end
43 | end
44 |
45 | always_ff @(posedge clk_counter[6], negedge resetn) begin
46 | if (~resetn) begin
47 | {LED16_G, LED16_R, LED17_G} <= '0;
48 | end else if (counter == 9'h100) begin
49 | {LED16_G, LED17_G} <= '1;
50 | end
51 | else if (~(~is_alu || (aluout_ans === aluout_check))) begin
52 | {LED16_R, LED17_G} <= '1;
53 | end
54 | end
55 |
56 |
57 |
58 | imem imem(.instr, .id(counter[7:0]));
59 |
60 | endmodule
61 |
--------------------------------------------------------------------------------
/experiment/lab3/lab3 copy.sv:
--------------------------------------------------------------------------------
1 | module lab3 (
2 | (*keep="true"*)input logic [3:0]a, b, cin,
3 | (*keep="true"*)output logic [3:0]c_ripple, c_ahead,
4 | (*keep="true"*)output logic cout_ripple, cout_ahead
5 | // c = a + b
6 | );
7 | ripple_adder ripple_adder(.a, .b, .cin, .c(c_ripple), .cout(cout_ripple));
8 | ahead_adder ahead_adder(.a, .b, .cin, .c(c_ahead), .cout(cout_ahead));
9 | endmodule
10 |
11 | (*keep="true"*)module full_adder (
12 | (*keep="true"*)input logic a, b, cin,
13 | (*keep="true"*)output logic c, cout
14 | );
15 | assign c = a ^ b ^ cin;
16 | assign cout = (a & b) | (a & cin) | (b & cin);
17 | endmodule
18 |
19 | (*keep="true"*)module ripple_adder (
20 | (*keep="true"*)input logic [3:0]a, b,
21 | (*keep="true"*)input logic cin,
22 | (*keep="true"*)output logic [3:0]c,
23 | (*keep="true"*)output logic cout
24 | );
25 | // TODO: Add logic here; Only use full_adder instants here
26 | (*keep="true"*)logic [3:0]cin_temp, cout_temp;
27 | assign cin_temp = {cout_temp[2:0], cin};
28 | for (genvar i = 0; i < 4; i++) begin
29 | full_adder full_adder(.a(a[i]), .b(b[i]), .cin(cin_temp[i]), .c(c[i]), .cout(cout_temp[i]));
30 | end
31 | assign cout = cout_temp[3];
32 | // logic [4:0] p, q;
33 | // assign {cout, c} = {1'b0, a} + {1'b0, b} + {4'b0, cin};
34 | endmodule
35 |
36 | // module ahead_adder (
37 | // input logic [3:0]a, b,
38 | // input logic cin,
39 | // output logic [3:0]c,
40 | // output logic cout
41 | // );
42 | // // TODO: Add logic here
43 |
44 | // endmodule
45 |
46 | (*keep="true"*)module gp_fulladder(
47 | (*keep="true"*)input logic A,
48 | (*keep="true"*)input logic B,
49 | (*keep="true"*)input logic Cin,
50 | (*keep="true"*)output logic S,
51 | (*keep="true"*)output logic G,P
52 | );
53 | assign S = A ^ B ^ Cin;
54 | assign G = A & B;
55 | assign P = A ^ B;
56 |
57 | endmodule
58 | (*keep="true"*)module chain(
59 | (*keep="true"*)input logic [3:0]G,
60 | (*keep="true"*)input logic [3:0]P,
61 | (*keep="true"*)input logic Cin,
62 | (*keep="true"*)output logic C1,C2,C3,C4
63 | );
64 | assign C1 = G[0] | (P[0] & Cin);
65 | assign C2 = G[1] | (P[1] & G[0]) | (P[1] & P[0] & Cin);
66 | assign C3 = G[2] | (P[2] & G[1]) | (P[2] & P[1] & G[0]) | (P[2] & P[1] & P[0] & Cin);
67 | assign C4 = G[3] | (P[3] & G[2]) | (P[3] & P[2] & G[1]) | (P[3] & P[2] & P[1] & G[0]) | (P[3] & P[2] & P[1] & P[0] & Cin);
68 | endmodule
69 | (*keep="true"*)module ahead_adder(
70 | (*keep="true"*)input logic [3:0]a,
71 | (*keep="true"*)input logic [3:0]b,
72 | (*keep="true"*)input logic cin,
73 | (*keep="true"*)output logic [3:0]c,
74 | (*keep="true"*)output logic cout
75 | );
76 | (*keep="true"*)logic [3:0]G;
77 | (*keep="true"*)logic [3:0]P;
78 | // assign G = A & B;
79 | // assign P = A ^ B;
80 | (*keep="true"*)logic C1,C2,C3;
81 | chain f(G,P,cin,C1,C2,C3,cout);
82 | gp_fulladder gp0(a[0],b[0],cin,c[0],G[0],P[0]),
83 | gp1(a[1],b[1],C1,c[1],G[1],P[1]),
84 | gp2(a[2],b[2],C2,c[2],G[2],P[2]),
85 | gp3(a[3],b[3],C3,c[3],G[3],P[3]);
86 | endmodule
87 |
--------------------------------------------------------------------------------
/experiment/lab3/lab3 加更.md:
--------------------------------------------------------------------------------
1 | # 超前进位加法器
2 |
3 | 类比:前缀和
4 |
5 | 超前进位的要点:求进位Carry[4:0]
6 |
7 | ```verilog
8 | assign carry[0] = cin;
9 | assign carry[1] = G[1] | (P[1] & cin);
10 | ```
11 |
12 | 我看到了三种求`carry[2]`的写法:
13 |
14 | ```verilog
15 | // assign carry[2] = G[2] | (P[2] & carry[1]);
16 | // assign carry[2] = G[2] | (P[2] & (G[1] | (P[1] & cin)));
17 | assign carry[2] = G[2] | (P[2] & G[1]) | (P[2] & P[1] & cin);
18 | ```
19 |
20 | 
--------------------------------------------------------------------------------
/experiment/lab3/lab3.sv:
--------------------------------------------------------------------------------
1 | module lab3 (
2 | input logic [3:0]a, b, cin,
3 | output logic [3:0]c_ripple, c_ahead,
4 | output logic cout_ripple, cout_ahead
5 | // c = a + b
6 | );
7 | ripple_adder ripple_adder(.a, .b, .cin, .c(c_ripple), .cout(cout_ripple));
8 | ahead_adder ahead_adder(.a, .b, .cin, .c(c_ahead), .cout(cout_ahead));
9 | endmodule
10 |
11 | module full_adder (
12 | input logic a, b, cin,
13 | output logic c, cout
14 | );
15 |
16 | endmodule
17 |
18 |
19 | module ripple_adder (
20 | input logic [3:0]a, b,
21 | input logic cin,
22 | output logic [3:0]c,
23 | output logic cout
24 | );
25 | // TODO: Add logic here; Only use full_adder instants here
26 |
27 | endmodule
28 |
29 | module ahead_adder (
30 | input logic [3:0]a, b,
31 | input logic cin,
32 | output logic [3:0]c,
33 | output logic cout
34 | );
35 | // TODO: Add logic here
36 | logic [3:0]G, P;
37 | logic [4:0]CO;
38 | assign G = a & b;
39 | assign P = a ^ b;
40 |
41 | assign CO[0] = cin;
42 | // assign CO[1]= G[0] | (cin&P[0]);
43 | // assign CO[2]= G[1] | (P[1]&G[0]) | (&P[1:0]&cin);
44 | // assign CO[3]= G[2] | (P[2]&G[1]) | (&P[2:1]&G[0]) | (&P[2:0]&cin);
45 | // assign CO[4]= G[3] | (P[3]&G[2]) | (&P[3:2]&G[1]) | (&P[3:1]&G[0]) | (&P[3:0]&cin);
46 | logic temp; // One product item
47 | always_comb begin
48 | for (int i = 1; i <= 4; i++) begin
49 | CO[i] = G[i - 1];
50 | for (int j = i - 1; j >= 0; j--) begin
51 | temp = (j == 0) ? cin : G[j - 1];
52 | for (int k = i - 1; k >= j; k--) begin
53 | temp &= P[k];
54 | end
55 | CO[i] |= temp;
56 | end
57 | end
58 | end
59 |
60 | // for (genvar i = 1; i <= 4; i++) begin
61 | // carry_gen #(.BIT(i)) carry_gen_inst(.cin, .G(G[i - 1:0]), .P(P[i - 1:0]), .cout(CO[i]));
62 | // end
63 |
64 | assign c = a ^ b ^ CO;
65 | assign cout = CO[4];
66 | endmodule
67 | module carry_gen
68 | #(parameter BIT = 1)
69 | (
70 | input logic cin,
71 | input logic [BIT-1:0]G, P,
72 | output logic cout
73 | );
74 | logic [BIT - 1 + 1:0] products;
75 | assign cout = |products;
76 | for (genvar i = 0; i <= BIT; i++) begin
77 | case(i)
78 | 0: assign products[i] = &P & cin;
79 | BIT: assign products[i] = G[i - 1];
80 | default: begin
81 | assign products[i] = G[i - 1] & (&P[BIT-1:i]);
82 | end
83 | endcase
84 | end
85 | endmodule
--------------------------------------------------------------------------------
/experiment/lab3/sim.sv:
--------------------------------------------------------------------------------
1 | module sim (
2 |
3 | );
4 | logic debug_ripple, debug_ahead;
5 | // TODO: If you don't want to debug, set the debug enable to 1'b0
6 | assign debug_ripple = 1'b1;
7 | assign debug_ahead = 1'b1;
8 |
9 | logic clk, resetn;
10 | always #5 clk = ~clk;
11 | initial begin
12 | clk = 1'b0;
13 | resetn = 1'b0;
14 | #100 resetn = 1'b1;
15 | end
16 |
17 | logic [3:0] a, b;
18 | logic cin;
19 |
20 | logic [3:0] c_ref, c_ripple, c_ahead;
21 | logic cout_ref, cout_ripple, cout_ahead;
22 | logic [9:0] counter, counter_nxt;
23 | lab3 lab3_sim(.*);
24 | always_ff @(posedge clk) begin
25 | if ( ~resetn ) begin
26 | counter <= '0;
27 | end else begin
28 | counter <= counter_nxt;
29 | end
30 | end
31 |
32 | always_comb begin
33 | counter_nxt = counter;
34 | if (counter_nxt != 10'h200
35 | && (({c_ref, cout_ref} === {c_ripple, cout_ripple}) || ~debug_ripple)
36 | && (({c_ref, cout_ref} === {c_ahead, cout_ahead}) || ~debug_ahead)
37 | ) begin
38 | counter_nxt = counter_nxt + 1;
39 | end
40 | end
41 | assign a = counter[3:0];
42 | assign b = counter[7:4];
43 | assign cin = counter[8];
44 | assign c_ref = a + b + {3'b0, cin};
45 |
46 | logic [4:0] c_ext;
47 | assign c_ext = {1'b0, a} + {1'b0, b} + {4'b0, cin};
48 | assign cout_ref = c_ext[4];
49 | always_ff @(posedge clk) begin
50 | if ( ~resetn ) begin
51 |
52 | end else if ( counter_nxt == 10'h200 ) begin
53 | $display("PASS!");
54 | $finish;
55 | end else if (~(({c_ref, cout_ref} === {c_ripple, cout_ripple}) || ~debug_ripple)) begin
56 | $display("[%d ns]: a = 0x %x, b = 0x %x, cin = 0x %x\n Ripple adder: \n Expect c = 0x %x, cout = 0x %x\n Got c = 0x %x, cout = 0x %x",
57 | $time, a, b, cin, c_ref, cout_ref, c_ripple, cout_ripple);
58 | $finish;
59 | end else if (~(({c_ref, cout_ref} === {c_ahead, cout_ahead}) || ~debug_ahead)) begin
60 | $display("[%d ns]: a = 0x %x, b = 0x %x, cin = 0x %x\n Ahead adder: \n Expect c = 0x %x, cout = 0x %x\n Got c = 0x %x, cout = 0x %x",
61 | $time, a, b, cin, c_ref, cout_ref, c_ahead, cout_ahead);
62 | $finish;
63 | end
64 | end
65 |
66 | endmodule
67 |
--------------------------------------------------------------------------------
/experiment/lab3/sources.tcl:
--------------------------------------------------------------------------------
1 | cd [file dirname [info script]]
2 | add_files top.sv
3 | add_files lab3.sv
4 | set_property top top [current_fileset]
5 |
6 | cd [file dirname [info script]]
7 | add_files -fileset constrs_1 -norecurse Nexys4DDR_Master.xdc
8 |
9 | set_property SOURCE_SET sources_1 [get_filesets sim_1]
10 | add_files -fileset sim_1 -norecurse sim.sv
11 | set_property top sim [get_filesets sim_1]
12 | set_property top_lib xil_defaultlib [get_filesets sim_1]
13 |
14 | set_param general.maxThreads 16
--------------------------------------------------------------------------------
/experiment/lab3/top.sv:
--------------------------------------------------------------------------------
1 | module top (
2 | input logic clk, resetn,
3 | output logic LED16_G, LED16_R, LED17_G
4 | );
5 | logic [3:0] a, b;
6 | logic cin;
7 |
8 | logic [3:0] c_ref, c_ripple, c_ahead;
9 | logic cout_ref, cout_ripple, cout_ahead;
10 | logic [9:0] counter, counter_nxt;
11 | lab3 lab3_top(.*);
12 |
13 | logic [15:0]clk_counter;
14 | always_ff @(posedge clk) begin
15 | if (~resetn) begin
16 | clk_counter <= '0;
17 | end
18 | else begin
19 | clk_counter <= clk_counter + 1;
20 | end
21 | end
22 | always_ff @(posedge clk_counter[6], negedge resetn) begin
23 | if ( ~resetn ) begin
24 | counter <= '0;
25 | end else begin
26 | counter <= counter_nxt;
27 | end
28 | end
29 |
30 | always_comb begin
31 | counter_nxt = counter;
32 | if (counter_nxt != 9'h100
33 | && ({c_ref, cout_ref} === {c_ripple, cout_ripple})
34 | && ({c_ref, cout_ref} === {c_ahead, cout_ahead})
35 | ) begin
36 | counter_nxt = counter_nxt + 1;
37 | end
38 | end
39 | assign a = counter[3:0];
40 | assign b = counter[7:4];
41 | assign cin = counter[8];
42 | assign c_ref = a + b + {3'b0, cin};
43 |
44 | logic [4:0] c_ext;
45 | assign c_ext = {1'b0, a} + {1'b0, b} + {4'b0, cin};
46 | assign cout_ref = c_ext[4];
47 |
48 | always_ff @(posedge clk_counter[6], negedge resetn) begin
49 | if ( ~resetn ) begin
50 | {LED16_G, LED16_R, LED17_G} <= '0;
51 | end else if ( counter_nxt == 9'h100 ) begin
52 | {LED16_G, LED17_G} <= '1;
53 | end else if (~({c_ref, cout_ref} === {c_ripple, cout_ripple})) begin
54 | {LED16_R, LED17_G} <= '1;
55 | end else if (~({c_ref, cout_ref} === {c_ahead, cout_ahead})) begin
56 | {LED16_R, LED17_G} <= '1;
57 | end
58 | end
59 |
60 | endmodule
61 |
--------------------------------------------------------------------------------
/experiment/lab4/74LS138.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/experiment/lab4/74LS138.pdf
--------------------------------------------------------------------------------
/experiment/lab4/74LS151.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/experiment/lab4/74LS151.pdf
--------------------------------------------------------------------------------
/experiment/lab4/ans.sv:
--------------------------------------------------------------------------------
1 | module ans (
2 | input logic [3:0]in,
3 | output logic [6:0]out
4 | );
5 | always_comb begin
6 | unique case(in)
7 | 4'h0: out = 7'b1000000;
8 | 4'h1: out = 7'b1111001;
9 | 4'h2: out = 7'b0100100;
10 | 4'h3: out = 7'b0110000;
11 | 4'h4: out = 7'b0011001;
12 | 4'h5: out = 7'b0010010;
13 | 4'h6: out = 7'b0000010;
14 | 4'h7: out = 7'b1111000;
15 | 4'h8: out = 7'b0000000;
16 | 4'h9: out = 7'b0010000;
17 | 4'hA: out = 7'b0001000;
18 | 4'hB: out = 7'b0000011;
19 | 4'hC: out = 7'b1000110;
20 | 4'hD: out = 7'b0100001;
21 | 4'hE: out = 7'b0000110;
22 | 4'hF: out = 7'b0001110;
23 | default: out = 7'b1000000;
24 | endcase
25 | end
26 |
27 | endmodule
28 |
--------------------------------------------------------------------------------
/experiment/lab4/lab4.md:
--------------------------------------------------------------------------------
1 | # 实验四 七段数码管
2 |
3 | **DDL: 2020-11-10**
4 |
5 | ## 实验要求
6 |
7 | 1. 阅读 `74LS138.pdf`和 `74LS151.pdf`,并在`lab4.sv`中的模块`mod_74LS138`和`mod_74LS151`中实现这两个逻辑器件(语法无限制)。
8 | 2. 阅读 `ans.sv`中七段数码管的硬件代码,在实验报告中画出真值表(**实验报告第一部分**)。
9 | 3. 分别使用`74LS138`和逻辑门、`74LS151`和逻辑门(不允许使用`always_comb`),实现该真值表。在实验报告中画出电路图(**实验报告第二部分**)。
10 | 4. 在模块`seg_138`和`seg_151`中,用你画好的电路图,实现该真值表的功能。
11 | 5. 仿真+上板测试。上板现象拍照,作为**实验报告第三部分**。
12 |
13 | 上板现象:
14 |
15 | * `Step 0`: 先把右边八个开关往上拨。
16 | * `Step 1`: 把最左边开关往下拨,数码管从左到右依次显示7到0。(拍照)
17 | * `Step 2`: 把最左边开关往上拨,数码管从左到右依次显示F到8。(拍照)
18 | * 可选:拨下右边八个开关中的任意一部分,对应的数码管会灭掉。
19 |
20 | ## 实验报告
21 |
22 | 总结一下实验报告的要求:
23 |
24 | * 第一部分为七段数码管的真值表。
25 | * 第二部分为使用`74LS138`和逻辑门、`74LS151`和逻辑门实现该真值表的电路图,共两张。
26 | * 第三部分为实验现象的图片。
27 | * (可选)第四部分为实验感想、对助教工作的评价、以及任何想说的话。
28 |
29 |
30 |
--------------------------------------------------------------------------------
/experiment/lab4/lab4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/experiment/lab4/lab4.pdf
--------------------------------------------------------------------------------
/experiment/lab4/lab4.sv:
--------------------------------------------------------------------------------
1 | module lab4 (
2 | input logic [3:0]in,
3 | output logic [6:0]out_use138, out_use151
4 | );
5 | seg_138 seg_138_inst(.in, .out(out_use138));
6 | seg_151 seg_151_inst(.in, .out(out_use151));
7 | endmodule
8 |
9 | module seg_138 (
10 | input logic [3:0]in,
11 | output logic [6:0]out
12 | );
13 | // TODO: add logic here
14 | // NOTE: "always_comb" are not allowed here. You should use mod_74LS138 instants and logic gates(assign) here
15 |
16 | endmodule
17 |
18 | module mod_74LS138 (
19 | // TODO: add ports here
20 |
21 | );
22 | // TODO: add logic here
23 | // NOTE: No syntax limitation
24 |
25 | endmodule
26 |
27 | module seg_151 (
28 | input logic [3:0]in,
29 | output logic [6:0]out
30 | );
31 | // TODO: add logic here
32 | // NOTE: "always_comb" are not allowed here. You should use mod_74LS151 instants and logic gates(assign) here
33 |
34 | endmodule
35 |
36 | module mod_74LS151 (
37 | // TODO: add ports here
38 |
39 | );
40 | // TODO: add logic here
41 | // NOTE: No syntax limitation
42 |
43 | endmodule
--------------------------------------------------------------------------------
/experiment/lab4/lab4display.md:
--------------------------------------------------------------------------------
1 | # 实现n位输入的任意给定组合逻辑电路
2 |
3 | > 与非门能实现任意组合逻辑电路,只要数量管够。
4 |
5 | 组合电路即真值表,问题转化为描述n位输入的任意真值表。
6 |
7 | 真值表即最小项之和,问题转化为我们熟悉的最小项:
8 |
9 | 两个思路:
10 |
11 | 1. 器件能表示n位变量的所有最小项(选一部分出来相加)
12 | 2. 器件能表示n位变量最小项任意组合的和
13 |
14 | n位输入的译码器加上或门可以实现(思路1)
15 |
16 |
17 |
18 | $2^m$选1(m位选择信号)的选择器呢?
19 |
20 | 以$m=3$为例:输出$Z = (D_0\&\overline{S_0}\&\overline{S_1}\&\overline{S_2}|...|D_7\&S_0\&S_1\&S_2)$
21 |
22 | 显然,根据思路2,它能实现$m=3$位任意给定组合电路。
23 |
24 | 和$\overline{S_0}\&\overline{S_1}\&\overline{S_2}$相关的最小项,有2个:$m(0)$和$m(8)$;组合有4个
25 |
26 | $D_0$可取$0, 1, S_3, \overline{S_3}$
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/experiment/lab4/sim.sv:
--------------------------------------------------------------------------------
1 | module sim (
2 |
3 | );
4 | logic clk, resetn;
5 | initial begin
6 | clk = 1'b0;
7 | resetn = 1'b0;
8 | #100 resetn = 1'b1;
9 | end
10 | always #5 clk = ~clk;
11 | logic [4:0] counter, counter_nxt;
12 | always_ff @(posedge clk) begin
13 | if (~resetn) begin
14 | counter <= '0;
15 | end else begin
16 | counter <= counter_nxt;
17 | end
18 | end
19 | logic [3:0]in;
20 | logic [6:0]out_use138, out_use151, out_ans;
21 | assign in = counter[3:0];
22 |
23 | lab4 lab4_inst(.*);
24 | ans ans_inst(.in, .out(out_ans));
25 |
26 | always_comb begin
27 | counter_nxt = counter;
28 | if ((counter != 5'h10) && (out_use138 == out_ans) && (out_use151 == out_ans)) begin
29 | counter_nxt = counter_nxt + 1;
30 | end
31 | end
32 |
33 | always_ff @(posedge clk) begin
34 | if (~resetn) begin
35 |
36 | end else if (counter == 5'h10) begin
37 | $display("PASS!\n");
38 | $finish;
39 | end else if (~(out_use138 === out_ans)) begin
40 | $display("[%d ns]: Seg_138 (input 0x%x) expected 0x%x, got 0x%x!\n", $time, in, out_ans, out_use138);
41 | $finish;
42 | end else if (~(out_use151 === out_ans)) begin
43 | $display("[%d ns]: Seg_151 (input 0x%x) expected 0x%x, got 0x%x!\n", $time, in, out_ans, out_use151);
44 | $finish;
45 | end
46 | end
47 |
48 | endmodule
49 |
--------------------------------------------------------------------------------
/experiment/lab4/sources.tcl:
--------------------------------------------------------------------------------
1 | cd [file dirname [info script]]
2 | add_files top.sv
3 | add_files lab4.sv
4 | add_files ans.sv
5 | set_property top top [current_fileset]
6 |
7 | cd [file dirname [info script]]
8 | add_files -fileset constrs_1 -norecurse Nexys4DDR_Master.xdc
9 |
10 | set_property SOURCE_SET sources_1 [get_filesets sim_1]
11 | add_files -fileset sim_1 -norecurse sim.sv
12 | set_property top sim [get_filesets sim_1]
13 | set_property top_lib xil_defaultlib [get_filesets sim_1]
14 |
15 | set_param general.maxThreads 1
--------------------------------------------------------------------------------
/experiment/lab4/top.sv:
--------------------------------------------------------------------------------
1 | module top (
2 | input logic clk, resetn,
3 | input logic [15:0]SW,
4 | output logic [7:0]AN,
5 | output logic [6:0]A2G
6 | );
7 |
8 | logic [20:0] counter;
9 | always_ff @(posedge clk) begin
10 | if (~resetn) begin
11 | counter <= '0;
12 | end else begin
13 | counter <= counter + 1;
14 | end
15 | end
16 |
17 | logic [15:0][6:0] outs;
18 | logic [3:0] temp;
19 | assign temp = {SW[15], counter[15:13]};
20 | assign AN = ~(SW[7:0] & (8'h1 << counter[15:13]));
21 | assign A2G = outs[temp];
22 |
23 | for (genvar i = 0; i < 16; i++) begin
24 | if ( i[0] ) begin
25 | lab4 lab4_inst1(.in(i[3:0]), .out_use138(outs[i[3:0]]));
26 | end else begin
27 | lab4 lab4_inst2(.in(i[3:0]), .out_use151(outs[i[3:0]]));
28 | end
29 | end
30 |
31 |
32 | endmodule
33 |
--------------------------------------------------------------------------------
/experiment/lab5/74LS194.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/experiment/lab5/74LS194.pdf
--------------------------------------------------------------------------------
/experiment/lab5/asset/circuit.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/experiment/lab5/asset/circuit.jpg
--------------------------------------------------------------------------------
/experiment/lab5/asset/ff.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/experiment/lab5/asset/ff.jpg
--------------------------------------------------------------------------------
/experiment/lab5/asset/ff_reset.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/experiment/lab5/asset/ff_reset.jpg
--------------------------------------------------------------------------------
/experiment/lab5/asset/微信图片_20201119201959.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/experiment/lab5/asset/微信图片_20201119201959.jpg
--------------------------------------------------------------------------------
/experiment/lab5/clock_convert.sv:
--------------------------------------------------------------------------------
1 | module clock_convert (
2 | input logic clk_100mhz,
3 | input logic resetn,
4 | output logic clk_1hz
5 | );
6 | logic [30:0] counter, counter_nxt;
7 | always_ff @(posedge clk_100mhz) begin
8 | if ( ~resetn ) begin
9 | counter <= '0;
10 | end else begin
11 | counter <= counter_nxt;
12 | end
13 | end
14 |
15 | always_comb begin
16 | counter_nxt = counter;
17 | if (counter > 31'd100_000_000) begin
18 | counter_nxt = '0;
19 | end else begin
20 | counter_nxt = counter_nxt + 1;
21 | end
22 | end
23 | // assign clk_1hz = (counter > 31'd100_000_000);
24 | assign clk_1hz = counter[26];
25 |
26 | endmodule
27 |
--------------------------------------------------------------------------------
/experiment/lab5/display.md:
--------------------------------------------------------------------------------
1 | # 时序电路入门:触发器
2 |
3 | ## 1. 简单的D触发器
4 |
5 | 
6 |
7 | 新的真值表:
8 |
9 | | $D$ | 时钟$clk$ | $Q_{n+1}$ |
10 | | ---- | --------- | --------- |
11 | | x | 0 | $Q_n$ |
12 | | 0 | ↑ | 0 |
13 | | 1 | ↑ | 1 |
14 |
15 | ```verilog
16 | always_ff @(posedge clk) begin /* flip_flop */
17 | Q <= D;
18 | end
19 | ```
20 |
21 |
22 |
23 | ## 2. 带复位的D触发器
24 |
25 | 
26 |
27 | | $D$ | $clk$ | $Reset$(低电平有效, 同步) | $Q_{n+1}$ |
28 | | ---- | ----- | ---------------------------- | --------- |
29 | | x | 0 | x | $Q_n$ |
30 | | x | ↑ | 0 | 0 |
31 | | | ↑ | 1 | $D$ |
32 |
33 | ```verilog
34 | always_ff @(posedge clk) begin
35 | if (~resetn)
36 | Q <= '0;
37 | else
38 | Q <= D;
39 | end
40 | ```
41 |
42 | | $D$ | $clk$ | $R$(低电平有效, 异步) | $Q_{n+1}$ |
43 | | ---- | ----- | ------------------------ | --------- |
44 | | x | x | ↓ | 0 |
45 | | x | 0 | 0 or 1 or ↑ | $Q_n$ |
46 | | x | ↑ | 0 | 0 |
47 | | | ↑ | 1 | $D$ |
48 |
49 | ```verilog
50 | always_ff @(posedge clk, negedge resetn) begin
51 | if (~resetn)
52 | Q <= '0;
53 | else
54 | Q <= D;
55 | end
56 | ```
57 |
58 | ## 3. 带使能的D触发器
59 |
60 | | $D$ | $clk$ | $en$ | $Q_{n+1}$ |
61 | | ---- | ----- | ---- | --------- |
62 | | x | 0 | x | $Q_n$ |
63 | | x | ↑ | 0 | $Q_n$ |
64 | | | ↑ | 1 | $D$ |
65 |
66 | ```verilog
67 | always_ff @(posedge clk) begin
68 | if (en) begin
69 | Q <= D;
70 | end
71 | end
72 | ```
73 |
74 | ## 4. 抽象化的电路图
75 |
76 |
77 | $$
78 | Q_{n+1} = F(Q_n)
79 | $$
80 |
81 | ```verilog
82 | logic q, q_nxt;
83 | always_ff @(posedge clk) begin
84 | if (~resetn) begin
85 | q <= '0;
86 | end else if (en) begin
87 | q <= q_nxt;
88 | end
89 | end
90 |
91 | always_comb begin
92 | q_nxt = q;
93 | // ...
94 | end
95 | ```
96 |
97 | 不要这么写:
98 |
99 | ```verilog
100 | logic q, q_nxt;
101 | always_ff @(posedge clk) begin
102 | q <= q_nxt;
103 | // q <= ~resetn & (en ? q : q_nxt);
104 | end
105 |
106 | always_comb begin
107 | q_nxt = q;
108 | // ...
109 | q_nxt = en ? q : q_nxt;
110 | q_nxt = q_nxt & resetn;
111 | end
112 | ```
113 |
114 |
--------------------------------------------------------------------------------
/experiment/lab5/lab5.sv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/experiment/lab5/lab5.sv
--------------------------------------------------------------------------------
/experiment/lab5/sim.sv:
--------------------------------------------------------------------------------
1 | module sim (
2 |
3 | );
4 |
5 | logic clk_1hz, clk_100mhz, resetn;
6 | always #500_000_000 clk_1hz = ~clk_1hz;
7 | always #5 clk_100mhz = ~clk_100mhz;
8 |
9 | initial begin
10 | clk_1hz = '0;
11 | clk_100mhz = '0;
12 | resetn = 1'b0;
13 | #100 resetn = 1'b1;
14 | end
15 |
16 | // TODO: declare variables here
17 |
18 | initial begin
19 | // TODO: add input drives here
20 |
21 | end
22 |
23 | // TODO: add module instantiation and other circuit codes here
24 |
25 |
26 | endmodule
27 |
--------------------------------------------------------------------------------
/experiment/lab5/sn74ls175.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/experiment/lab5/sn74ls175.pdf
--------------------------------------------------------------------------------
/experiment/lab5/sources.tcl:
--------------------------------------------------------------------------------
1 | cd [file dirname [info script]]
2 | add_files top.sv
3 | add_files lab5.sv
4 | add_files clock_convert.sv
5 | set_property top top [current_fileset]
6 |
7 | cd [file dirname [info script]]
8 | add_files -fileset constrs_1 -norecurse Nexys4DDR_Master.xdc
9 |
10 | set_property SOURCE_SET sources_1 [get_filesets sim_1]
11 | add_files -fileset sim_1 -norecurse sim.sv
12 | set_property top sim [get_filesets sim_1]
13 | set_property top_lib xil_defaultlib [get_filesets sim_1]
14 |
15 | set_param general.maxThreads 1
--------------------------------------------------------------------------------
/experiment/lab5/submit.md:
--------------------------------------------------------------------------------
1 | # 实验五 触发器和寄存器 提交
2 |
3 | ## 1. D触发器(异步置数,异步清零)
4 |
5 | 这是`74LS74`,手册在新上传的`lab5.zip`中。我们可以假设异步置数信号和异步清零信号不会同时有效。
6 |
7 | `74LS74`集成了两个1位的D触发器,我们只要求实现一个1位的。
8 |
9 | 提交内容:
10 |
11 | * 源代码
12 | * 功能描述(真值表)
13 | * 仿真代码(可以是`.sv`文件,也可以放在报告里,排版正常即可)
14 | * 你的仿真代码如何验证正确性(可配合波形图或`Tcl Console`输出)
15 |
16 | ## 2. 加法计数器
17 |
18 | 这是`74LS163`,手册在新上传的`lab5.zip`中。
19 |
20 | `74LS163`是四位的加法计数器,我们只要求实现两位的。
21 |
22 | 计数器的功能包括:置数,同步清零,自增,计算进位(当加到3时,进位输入为1,而不是回到0时)。可参考四位加法计数器`74LS163`。
23 |
24 | 提交内容:
25 |
26 | * 源代码
27 | * 功能描述(真值表或状态方程)。进位信号的产生是组合电路,可以和计数信号分开写。
28 | * 仿真代码(可以是`.sv`文件,也可以放在报告里,排版正常即可)
29 | * 你的仿真代码如何验证正确性(可配合波形图或`Tcl Console`输出)
30 |
31 | ## 3. 74LS175
32 |
33 | 提交内容:
34 |
35 | * 源代码
36 | * 功能描述(真值表)
37 | * 仿真代码(可以是`.sv`文件,也可以放在报告里,排版正常即可)
38 | * 你的仿真代码如何验证正确性(可配合波形图或`Tcl Console`输出)
39 |
40 | 如果你只用第1题中写的D触发器元件例化语句实现,而不用`always_ff`语法,报告中可以只写实现思路(文字描述)。源代码还是要交的。
41 |
42 | ## 4. 74LS194
43 |
44 | `74LS194`是双向移位寄存器,功能包括:保存数据、置数、左移和右移(带补位输入)、异步清零。
45 |
46 | 提交内容:
47 |
48 | * 源代码
49 | * 功能描述(真值表或状态方程)。
50 | * 仿真代码(可以是`.sv`文件,也可以放在报告里,排版正常即可)
51 | * 你的仿真代码如何验证正确性(可配合波形图或`Tcl Console`输出)
52 | * 上板现象描述
53 |
54 | ## 5. 感想或建议(可选)
55 |
56 | 欢迎大家对助教们的工作提出建议。
57 |
58 |
59 |
60 | 注:这门课是3学分,和另一门2学分的实验课不同:这门课实验报告是用来证明你做对了。如果你做出来了,报告很好写,不用写很多内容就是满分;如果你没做出来,会扣一些分,请和身边的大佬或者助教交流,把不懂的部分补上,学到知识是最重要的。
--------------------------------------------------------------------------------
/experiment/lab5/top.sv:
--------------------------------------------------------------------------------
1 | module top (
2 | input logic clk, resetn,
3 | input logic [15:0] SW,
4 | output logic [15:0] LED
5 | );
6 |
7 | // clk is 100MHz
8 |
9 | logic clk_1hz;
10 | clock_convert clock_convert_inst0(.clk_100mhz(clk), .resetn, .clk_1hz(clk_1hz));
11 |
12 | // TODO: add circuit codes here
13 |
14 | endmodule
15 |
--------------------------------------------------------------------------------
/experiment/lab5/实验五 提交.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/experiment/lab5/实验五 提交.pdf
--------------------------------------------------------------------------------
/experiment/lab6/display.md:
--------------------------------------------------------------------------------
1 | # 有限状态机
2 |
3 | 有限状态机是时序电路的一种应用。
4 |
5 | ## 1 计数器
6 |
7 | 我们已经写过了两位加法计数器。
8 |
9 | 可以用真值表来描述这个计数器。在这个真值表中,计数变量有次态和现态。我们也可以用状态图来描述这个计数器:
10 |
11 |
12 |
13 | ## 2 触发器模型
14 |
15 | 次态对应D触发器的输入D,现态对应D触发器的输出Q
16 |
17 | $D = Q_{nxt} = F(\ ...)$
18 |
19 | 有限状态机的方程(D可为多位):
20 |
21 | $D = Q_{nxt} = F(Q, \ ...)$
22 |
23 | ## 3 有限状态机
24 |
25 | ### 3.1 状态机电路→状态转换图(现实意义)
26 |
27 | 以D触发器为例:先找有没有一部分D触发器,除时钟外的输入都来自外界。这部分D触发器不是状态机的部分。
28 |
29 | 其他,每个1位的D触发器的输出Q即1位状态变量。
30 |
31 | 然后,列状态方程,画出状态图。
32 |
33 | ### 3.2 (现实意义→)状态转换图→状态机电路
34 |
35 | 对一个随时间变化的现象,先抽象出有限个状态。
36 |
37 | 对这些状态进行编码,得到状态变量,画出状态图(处理多余状态)。
38 |
39 | 每位状态变量为一个触发器,写出状态方程后,就可以写电路了。
40 |
41 | ## 4 语法
42 |
43 | ### 4.1 计数器类型
44 |
45 | 按正常的D触发器语法即可。
46 |
47 | ```verilog
48 | logic [3:0]q, q_nxt;
49 |
50 | always_ff @(posedge clk) begin
51 | q <= q_nxt;
52 | end
53 |
54 | always_comb begin
55 | q_nxt = q + 1;
56 | if (~en) begin
57 | q_nxt = q;
58 | end
59 | end
60 | ```
61 |
62 | ### 4.2 状态有实际意义
63 |
64 | 1. 枚举所有状态。
65 |
66 | 2. 计算状态用多少位来存储。
67 |
68 | 3. ```verilog
69 | typedef enum logic [2-1:0] {
70 | SOUTH_EAST_GREEN, SOUTH_EAST_YELLOW
71 | } state_t;
72 | ```
73 |
74 | 4. ```verilog
75 | state_t state, state_nxt;
76 | always_ff @(posedge clk) begin
77 | if (~resetn) begin
78 | state <= state_t'('0);
79 | end else begin
80 | state <= state_nxt;
81 | end
82 | end
83 |
84 | always_comb begin
85 | unique case(state)
86 | SOUTH_EAST_GREEN: begin
87 | if ...
88 | state_nxt = SOUTH_EAST_YELLOW;
89 | end
90 | SOUTH_EAST_YELLOW: begin
91 | state_nxt = SOUTH_EAST_GREEN;
92 | end
93 | endcase
94 | end
95 |
96 | // outputs that are related to the state
97 |
98 | logic allowed_to_go;
99 | assign allowed_to_go = state == SOUTH_EAST_GREEN;
100 | ```
101 |
102 |
--------------------------------------------------------------------------------
/experiment/lab6/lab6.md:
--------------------------------------------------------------------------------
1 | # 实验六 有限状态机
2 |
3 | > 人有悲欢离合,月有阴晴圆缺。
4 | >
5 | > 今人未见古时月,今月曾经照古人。古人今人若流水,共看明月皆如此。
6 |
7 | ## 1 必做内容
8 |
9 | ### 1.1 数字时钟
10 |
11 | 显示时、分、秒。
12 |
13 | 为方便检测,时钟里秒的频率可以是几十赫兹。
14 |
15 | ### 1.2 十字路口红绿灯
16 |
17 | 我们要控制一组红绿灯。
18 |
19 | 绿灯维持3秒变为黄灯;黄灯维持1秒变为红灯,此时另一边变绿。
20 |
21 | 其中,有一条路车很少,我们加了一个sensor,检测这条路上有没有车(用一个开关控制)。如果没车,下一时刻就转到边绿灯,并一直为绿灯。
22 |
23 | 
24 |
25 | ### 1.3 加法计数器的精妙设计
26 |
27 | ```verilog
28 | module mod_cnt #(
29 | parameter logic [30:0] N = 31'd100_000_000,
30 | parameter int W = 8 // default value
31 | )(
32 | input logic clk, resetn,
33 | input logic en,
34 | output logic [W-1:0] counter,
35 | output logic carry // `carry` as `en` of another instance
36 | );
37 | logic [W-1:0]counter_nxt;
38 | always_ff @(posedge clk) begin
39 | if (~resetn) begin
40 | counter <= '0;
41 | end else if (en) begin
42 | counter <= counter_nxt;
43 | end
44 | end
45 | always_comb begin
46 | if (counter == N - 1) begin
47 | counter_nxt = '0;
48 | end else begin
49 | counter_nxt = counter + 1;
50 | end
51 | end
52 | assign carry = en && (counter == N - 1);
53 | endmodule
54 |
55 | module foo();
56 | mod_cnt #(.N(100_000), .W(4)) cnt_inst1(/*TODO*/);
57 | mod_cnt cnt_inst2(/*TODO*/);
58 | endmodule
59 | ```
60 |
61 | ### 1.4 参考思路
62 |
63 | 数字时钟:
64 |
65 | 1. 确定计数器级联结构
66 | 2. 连接各计数器
67 | 3. 处理输出
68 |
69 | 红绿灯:
70 |
71 | 1. 理解状态机
72 | 2. 生成1秒和3秒的进位信号
73 | 3. 实现状态机
74 |
75 | ## 2 选做内容
76 |
77 | 有限状态机的运用是很广泛的。
78 |
79 | ### 2.1 有限状态机与组合电路
80 |
81 | 延迟很高的组合逻辑电路,我们可以分步做了。
82 |
83 | 乘法器、除法器、浮点数运算、甚至加法器。
84 |
85 | ### 2.2 有限状态机与现实世界
86 |
87 | 用有限状态机的视角去描述世界
--------------------------------------------------------------------------------
/experiment/lab6/lab6.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/experiment/lab6/lab6.pdf
--------------------------------------------------------------------------------
/experiment/lab6/lab6.sv:
--------------------------------------------------------------------------------
1 | `include "lab6.svh"
2 | module lab6 #(
3 | parameter logic SIM = 1'b0
4 | )(
5 | input logic clk, resetn,
6 |
7 | input logic has_car,
8 | output logic [1:0] red, yellow, green,
9 |
10 | output logic [1:0][3:0] hour, minute, second
11 | );
12 | logic one_second;
13 | add_counter #(.N(SIM ? 100 : 2_000_000)) one_second_gen
14 | (.clk, .resetn, .en(1'b1), .carry(one_second));
15 |
16 | logic [3:0] carry;
17 | add_counter #(.N(10), .W(4)) second_gen_0
18 | (.clk, .resetn, .en(one_second), .counter(second[0]), .carry(carry[0]));
19 | add_counter #(.N(6), .W(4)) second_gen_1
20 | (.clk, .resetn, .en(carry[0]), .counter(second[1]), .carry(carry[1]));
21 | add_counter #(.N(10), .W(4)) minute_gen_0
22 | (.clk, .resetn, .en(carry[1]), .counter(minute[0]), .carry(carry[2]));
23 | add_counter #(.N(6), .W(4)) minute_gen_1
24 | (.clk, .resetn, .en(carry[2]), .counter(minute[1]), .carry(carry[3]));
25 | logic [4:0] hour_temp;
26 | add_counter #(.N(24), .W(5)) hour_gen
27 | (.clk, .resetn, .en(carry[3]), .counter(hour_temp));
28 | assign hour[0] = hour_temp % 10;
29 | assign hour[1] = hour_temp / 10;
30 |
31 | logic one_s, three_s;
32 | add_counter #(.N(SIM ? 10 : 100_000_000)) one_s_gen
33 | (.clk, .resetn(resetn & has_car), .en(1'b1), .carry(one_s));
34 | add_counter #(.N(3), .W(2)) three_s_gen
35 | (.clk, .resetn(resetn & has_car), .en(one_s), .carry(three_s));
36 |
37 | typedef enum logic[1:0] {
38 | HG, HY, FG, FY
39 | } state_t;
40 |
41 | state_t state, state_nxt;
42 | assign red[0] = state == FG || state == FY;
43 | assign red[1] = state == HG || state == HY;
44 | assign yellow[0] = state == HY;
45 | assign yellow[1] = state == FY;
46 | assign green[0] = state == HG;
47 | assign green[1] = state == FG;
48 | always_ff @(posedge clk) begin
49 | if (~resetn) begin
50 | state <= state_t'('0);
51 | end else if (~has_car) begin
52 | state <= state_t'('0);
53 | end else begin
54 | state <= state_nxt;
55 | end
56 | end
57 | always_comb begin
58 | state_nxt = state;
59 | unique case(state)
60 | HG: begin
61 | if (three_s) begin
62 | state_nxt = HY;
63 | end
64 | end
65 | HY: begin
66 | if (one_s) begin
67 | state_nxt = FG;
68 | end
69 | end
70 | FG: begin
71 | if (three_s) begin
72 | state_nxt = FY;
73 | end
74 | end
75 | FY: begin
76 | if (one_s) begin
77 | state_nxt = HG;
78 | end
79 | end
80 | default: begin
81 |
82 | end
83 | endcase
84 | end
85 |
86 | endmodule
87 |
88 | module add_counter #(
89 | parameter int N = 100_000_000,
90 | parameter logic[10:0] W = 30
91 | )(
92 | input logic clk, resetn,
93 | input logic en,
94 | output logic [W - 1:0]counter,
95 | output logic carry
96 | );
97 | always_ff @(posedge clk) begin
98 | if (~resetn) begin
99 | counter <= '0;
100 | end else if(en) begin
101 | counter <= counter + 1;
102 | if (counter == N - 1) begin
103 | counter <= '0;
104 | end
105 | end
106 | end
107 | assign carry = (counter == N - 1) && en;
108 | endmodule
109 |
--------------------------------------------------------------------------------
/experiment/lab6/lab6.svh:
--------------------------------------------------------------------------------
1 | `ifndef __LAB6_SVH
2 | `define __LAB6_SVH
3 |
4 |
5 |
6 | `endif
7 |
--------------------------------------------------------------------------------
/experiment/lab6/sim.sv:
--------------------------------------------------------------------------------
1 | module sim (
2 |
3 | );
4 | logic clk, resetn;
5 |
6 | initial begin
7 | clk = '0;
8 | resetn = '0;
9 | #100 resetn = '1;
10 | end
11 | always #5 clk = ~clk;
12 |
13 | logic has_car;
14 |
15 | initial begin
16 | has_car = 1'b0;
17 | end
18 |
19 | always #1000 has_car = ~has_car;
20 | lab6 #(.SIM(1'b1)) lab6_inst(.clk, .resetn, .has_car);
21 | endmodule
22 |
--------------------------------------------------------------------------------
/experiment/lab6/sources.tcl:
--------------------------------------------------------------------------------
1 | cd [file dirname [info script]]
2 | add_files top.sv
3 | add_files lab6.sv
4 | add_files lab6.svh
5 | set_property top top [current_fileset]
6 |
7 | cd [file dirname [info script]]
8 | add_files -fileset constrs_1 -norecurse Nexys4DDR_Master.xdc
9 |
10 | set_property SOURCE_SET sources_1 [get_filesets sim_1]
11 | add_files -fileset sim_1 -norecurse sim.sv
12 | set_property top sim [get_filesets sim_1]
13 | set_property top_lib xil_defaultlib [get_filesets sim_1]
14 |
15 | set_param general.maxThreads 1
--------------------------------------------------------------------------------
/experiment/lab6/top.sv:
--------------------------------------------------------------------------------
1 | `include "lab6.svh"
2 | module top (
3 | input logic clk, resetn,
4 | input logic [15:0] SW,
5 | output logic LED16_G, LED16_R, LED17_G, LED17_R,
6 | output logic [6:0]A2G,
7 | output logic [7:0]AN
8 | );
9 | logic [15:0] counter;
10 | logic [7:0][6:0] segs;
11 |
12 | logic [7:0][3:0] raw_segs; // TODO: drive these signals
13 |
14 | always_ff @(posedge clk) begin
15 | if (~resetn) begin
16 | counter <= '0;
17 | end else begin
18 | counter <= counter + 1;
19 | end
20 | end
21 |
22 | for (genvar i = 0; i < 8; i++) begin
23 | seg7 seg7_inst (.in(raw_segs[i]), .out(segs[i]));
24 | end
25 |
26 | assign A2G = segs[counter[15:13]];
27 | assign AN[7:0] = ~({7'b0, resetn} << counter[15:13]);
28 |
29 | logic [1:0] red, yellow, green; // TODO: drive these signals
30 | assign LED16_G = green[0] | yellow[0];
31 | assign LED16_R = red[0] | yellow[0];
32 | assign LED17_G = green[1] | yellow[1];
33 | assign LED17_R = red[1] | yellow[1];
34 |
35 | // TODO: drive these signals
36 | lab6 lab6_inst(.clk, .resetn, .has_car(SW[0]), .hour(raw_segs[5:4]), .minute(raw_segs[3:2]), .second(raw_segs[1:0]), .*);
37 | endmodule
38 |
39 | module seg7 (
40 | input logic [3:0]in,
41 | output logic [6:0]out
42 | );
43 | always_comb begin
44 | unique case(in)
45 | 4'h0: out = 7'b1000000;
46 | 4'h1: out = 7'b1111001;
47 | 4'h2: out = 7'b0100100;
48 | 4'h3: out = 7'b0110000;
49 | 4'h4: out = 7'b0011001;
50 | 4'h5: out = 7'b0010010;
51 | 4'h6: out = 7'b0000010;
52 | 4'h7: out = 7'b1111000;
53 | 4'h8: out = 7'b0000000;
54 | 4'h9: out = 7'b0010000;
55 | 4'hA: out = 7'b0001000;
56 | 4'hB: out = 7'b0000011;
57 | 4'hC: out = 7'b1000110;
58 | 4'hD: out = 7'b0100001;
59 | 4'hE: out = 7'b0000110;
60 | 4'hF: out = 7'b0001110;
61 | default: out = 7'b1000000;
62 | endcase
63 | end
64 | endmodule
--------------------------------------------------------------------------------
/experiment/lab7/74LS377.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/experiment/lab7/74LS377.pdf
--------------------------------------------------------------------------------
/experiment/lab7/lab7.md:
--------------------------------------------------------------------------------
1 | # 实验七 总线
2 |
3 | 思想:信号线复用
4 |
5 | ## 多周期CPU的总线
6 |
7 | | 信号 | 位数 |
8 | | ------ | ---- |
9 | | aluout | 64 |
10 | | valA | 64 |
11 | | valC | 64 |
12 | | | |
13 | | | |
14 | | | |
15 | | | |
16 |
17 | 新的语法:union
18 |
19 | ```verilog
20 | typedef union packed {
21 | struct packed {
22 |
23 | } fetch;
24 | struct packed {
25 |
26 | } decode;
27 | struct packed {
28 |
29 | } execute;
30 | struct packed {
31 |
32 | } memory;
33 | struct packed {
34 |
35 | } writeback;
36 | } reg_data_t;
37 | ```
38 |
39 |
40 |
41 | ## 接下来两周的内容
42 |
43 | 实验做完了,接下来两周,助教可以准备:
44 |
45 | * 实验板上的逻辑部件
46 | * 流水线
--------------------------------------------------------------------------------
/experiment/lab7/lab7.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/experiment/lab7/lab7.pdf
--------------------------------------------------------------------------------
/experiment/lab7/lab7.sv:
--------------------------------------------------------------------------------
1 | module lab7 (
2 | input logic clk,
3 | // ...
4 |
5 | );
6 |
7 | endmodule
8 |
--------------------------------------------------------------------------------
/experiment/lab7/ram2.sv:
--------------------------------------------------------------------------------
1 | module ram2 (
2 | input logic clk,
3 | input logic wen,
4 | input logic [3:0] addr,
5 | input logic [3:0] din,
6 | output logic [3:0] qout
7 | );
8 | logic [15:0][3:0] ram;
9 | for (genvar i = 0; i < 16; i++) begin
10 | always_ff @(posedge clk) begin
11 | if (wen && i[3:0] == addr) begin
12 | ram[i] <= din;
13 | end
14 | end
15 | end
16 | assign qout = ram[addr];
17 |
18 | endmodule
19 |
--------------------------------------------------------------------------------
/experiment/lab7/sim.sv:
--------------------------------------------------------------------------------
1 | module sim (
2 |
3 | );
4 | logic clk, resetn;
5 | logic [15:0] SW;
6 | logic [15:0] LED;
7 | top #(.SIM(1'b1)) top_inst(.clk, .resetn, .SW, .LED);
8 |
9 | parameter logic[3:0]x = 4'b1010;
10 | parameter logic[3:0]y = 4'b0111;
11 | initial begin
12 | clk = 1'b0;
13 | resetn = 1'b0;
14 | #100 resetn = 1'b1;
15 |
16 | // TODO: add something here
17 |
18 |
19 | $finish;
20 | end
21 |
22 | always #5 clk = ~clk;
23 |
24 |
25 | endmodule
26 |
--------------------------------------------------------------------------------
/experiment/lab7/sources.tcl:
--------------------------------------------------------------------------------
1 | cd [file dirname [info script]]
2 | add_files top.sv
3 | add_files lab7.sv
4 | add_files ram2.sv
5 | set_property top top [current_fileset]
6 |
7 | cd [file dirname [info script]]
8 | add_files -fileset constrs_1 -norecurse Nexys4DDR_Master.xdc
9 |
10 | set_property SOURCE_SET sources_1 [get_filesets sim_1]
11 | add_files -fileset sim_1 -norecurse sim.sv
12 | set_property top sim [get_filesets sim_1]
13 | set_property top_lib xil_defaultlib [get_filesets sim_1]
14 |
15 | set_param general.maxThreads 1
--------------------------------------------------------------------------------
/experiment/lab7/top.sv:
--------------------------------------------------------------------------------
1 | module top #(
2 | parameter logic SIM = 1'b0
3 | ) (
4 | input logic clk, resetn,
5 | input logic [15:0]SW,
6 | output logic [15:0]LED
7 | );
8 | logic clk_lab7; // use this clk
9 | logic clk_1hz;
10 | generate if (SIM) begin
11 | assign clk_lab7 = clk;
12 | end else begin
13 | assign clk_lab7 = clk_1hz;
14 | end
15 | endgenerate
16 | clkdiv clkdiv_inst(.clk, .resetn, .clk_1hz);
17 |
18 | lab7 lab7_inst(
19 | .clk(clk_lab7),
20 | // TODO: ADD PORTS HERE
21 | );
22 |
23 | endmodule
24 |
25 | module clkdiv (
26 | input logic clk, resetn,
27 | output logic clk_1hz
28 | );
29 | logic [30:0] counter, counter_nxt;
30 | always_ff @(posedge clk) begin
31 | if ( ~resetn ) begin
32 | counter <= '0;
33 | end else begin
34 | counter <= counter_nxt;
35 | end
36 | end
37 |
38 | always_comb begin
39 | counter_nxt = counter;
40 | if (counter > 31'd100_000_000) begin
41 | counter_nxt = '0;
42 | end else begin
43 | counter_nxt = counter_nxt + 1;
44 | end
45 | end
46 | assign clk_1hz = counter[26];
47 |
48 | endmodule
49 |
--------------------------------------------------------------------------------
/notes/00引言/00引言.md:
--------------------------------------------------------------------------------
1 | # 引言
2 |
3 | *本文档为.md格式,强烈推荐使用Typora软件打开哦
4 |
5 | ## 序
6 |
7 | 首先,恭喜大家进入复旦大学计算机专业继续接下来三年的学习!如果没有算错的话,这应该是你们进入大二以来的第一门课,不知道大家有什么感受呢?
8 |
9 | 且不论难易,我想大家在看到这门课的大纲,以及相关教材的目录之后,一定会感到奇怪,“怎么在进入计算机专业之后,还要学习这些跟硬件扯上关系的课程呢?”,“计算机专业难道不是只需要敲敲代码就好了吗?硬件应该交给微电子去做才对啊。“,“现在不都流行用Python,javascript之类的语言吗,Verilog又是什么东西?”,诸如此类的问题我相信肯定有同学在心底已经问过了。那么在此,我们给大家讲一讲,为什么我们需要这些知识吧。
10 |
11 | ## 为什么说数字逻辑”很重要“?
12 |
13 | 不知道大家是否听说过”数字化“,”数字时代“这些关键词,在大家眼中,这些词中的”数字“又代表什么意思呢?
14 |
15 | 或许大家并不能很好地解释这个词的含义,但是我想,大家的脑海中浮现的一定是有关”高科技“,”电子信息“,”智能设备“等方面的内容。而现实则是,在上述各词中,”数字“是由“数字电路”中的“数字”的含义引申而来的。从数字(集成)电路的出现到计算机到网络到今天的移动互联网,数字电路是所有现代信息技术的基础。从这个角度,“数字时代”就是“信息社会”的意思。
16 |
17 | 而数字电路的基础,便是数字逻辑,所有的数字系统都是基于数字逻辑来设计的。那么,什么是数字逻辑呢?简单概括来说,数字逻辑,是处理数字信号的逻辑,数字电路运作的原理;实质上是指基于二进制数学或布尔代数的逻辑。
18 |
19 | 大家都知道,计算机是0和1的世界,可是大家在自己写程序的时候似乎并没有一个直观的认知,毕竟,我只需告诉电脑,我想执行a=b+c的操作,其余的都交给电脑自己处理就行。而数字逻辑,恰恰是教会电脑a=b+c的这一类操作应该如何从底层,运用最基本的硬件去实现。我们要知道,计算机中的所有操作都是依靠无数个0,1以及”与或非“这三个操作来进行的,无论是多么强大的电脑元器件都遵循这一原则,而这,都离不开数字逻辑这一强大的基础。
20 |
21 | 当然,在大家没有系统地学习数字逻辑及更深入的课程之前,我们也很难讲明白数字逻辑有多么的重要,毕竟,这也都算是”纸上谈兵“,不过,我们还是想讨论一下我们对此的一些看法。
22 |
23 | 数字逻辑这门课程也是你们以后要学的部分专业课的一门基础课,比如计算机系统基础,计算机组成原理,或者计算机体系结构等等,相信这些孙老师在之前应该有所介绍,从学习的角度来说,如果学好了这门专业课,则为以后的专业课打下了一个牢固的基础。
24 |
25 | 相较于软件编程来说,数字逻辑的相关知识通常是为硬件编程,硬件设计服务的,这便涉及到我们通常说的“系统能力”。无论是处理器架构,还是从计算机底层进行一些优化,都离不开“系统能力”方面的人才。大家经常听到的x86,arm,risc指令集,都是由计算机方面的专家设计出来的,所以说,并不是说只有微电子专业的学生才能造CPU,计算机专业的学生对于一个CPU的设计有着不可小觑的贡献。而目前,市面上主流的CPU,指令集架构等,都是由国外进行设计开发的,除去”制造难“这一问题,这也体现了我国在设计这方面人才的匮乏。而以上的这些,需要的则是软硬件兼通的人才,这也体现了数字逻辑的重要性所在,毕竟,数字逻辑是一个坚实的地基,倘若没有它,所有牵扯到硬件方面的知识均是一片浮云。
26 |
27 | 或许有同学会想,我以后只想做做人工智能,学学数据科学,对这些并不感兴趣,但现实是,近年来,计算机界越来越重视系统能力的培养。
28 |
29 | 1. 大规模数据中心的建立和个人移动设备的普及,计算机人才培养强调的”程序性开发能力“也正在转化为更重要的”系统性设计能力“。
30 |
31 | 2. 为了应对各种复杂应用,编写出高效程序,应用开发人员必须了解系统平台的底层结构,并熟练掌握其中的技术和工具。
32 |
33 | 3. 要求在整体的系统层面综合设计,通过软硬件协同实现开发方案的最优化,以强大的底层技术来保证各项功能的高效实现。
34 |
35 | 数字逻辑的重要性,由此也不言而喻了。
36 |
37 | 最后,引用图灵奖得主David Patterson的一段话,来给这份引言画上一个句号。
38 |
39 | ”在异构计算的时代,程序员必须对于算法和硬件模型融会贯通,才能写出高质量的代码。因此,未来的程序员还必须懂硬件!“
40 |
41 | ## 实验课助教
42 |
43 |
--------------------------------------------------------------------------------
/notes/01开发流程(上)/01开发流程(上).md:
--------------------------------------------------------------------------------
1 | # 数字逻辑与部件设计 实验部分-01.开发流程(上)
2 |
3 | We will start with installing the software.
4 |
5 | ------
6 |
7 | [TOC]
8 |
9 | ## 安装Vivado 2018.3
10 |
11 | 以下为 `Vivado 2018.3`安装教程。
12 |
13 | ### Step0:安装环境
14 |
15 | Vivado支持Windows和Linux操作系统。如果你是Mac用户,需要在虚拟机上安装并使用Vivado。
16 |
17 | Vivado需要20GB左右的硬盘空间。
18 |
19 | ### Step1:注册Xilinx账户
20 |
21 | Xilinx是Vivado软件的开发商。安装Vivado需要Xilinx账户,这是[注册链接](https://china.xilinx.com/registration/create-account.html)
22 |
23 | 然后在[个人信息](https://www.xilinx.com/myprofile/edit-profile.html)里用英文填写所有必填项,维护个人信息。
24 |
25 | ### Step2:下载安装包
26 |
27 | Vivado的安装包有`在线安装`和`完整安装`两种,使用这两种安装包的安装步骤也有不同。
28 |
29 | 助教推荐使用 **在线安装**版本。
30 |
31 | 助教提供了在线安装包的钉盘下载链接,有效期至 `2020-10-12`:
32 |
33 | Windows版Vivado:[Windows版在线安装包](https://space.dingtalk.com/s/gwHOAlIvJwLOQ5TVLAPaACBlZGIxYWQyODMxMzY0Mzc0YWVkNTIxYzE1MTY3OTdmNA),提取码: `KCP2`
34 |
35 | Linux版Vivado:[Linux版在线安装包](https://space.dingtalk.com/s/gwHOAlIvKQLOQ5TVLAPaACAzOGQyN2JjYmJjMDQ0YjBkOWI5NTUyNWQ3ZDY2NmRmNQ),提取码: `xDsd`
36 |
37 | ### Step3:安装流程
38 |
39 | 以下为 `Windows在线安装版本`的安装流程演示。完整安装包、Linux系统安装流程类似。
40 |
41 | 打开安装包后,可能会跳出来`有新版本`的提示,我们不安装新版本,点`Next`。
42 |
43 | 接下来填写用户名和密码,再点`Next`。
44 |
45 |
46 |
47 | 接下来要点三个`I Agree`,然后点`Next`,如图:
48 |
49 |
50 |
51 | 接下来选择要安装的edition,我们选择 `Vivado HL Webpack`,然后点 `Next`,如图:
52 |
53 |
54 |
55 | 接下来选择安装内容。选择的内容如图所示,然后点 `Next`:
56 |
57 | 
58 |
59 | 接下来选择安装路径,然后点 `Next`(注:点这个 `Next`后,下个界面先别点 `install`按钮),如图:
60 |
61 | 
62 |
63 | 进入`Installation Summary`界面:
64 |
65 | 
66 |
67 | 下载内容大小`3.74GB(Windows)`、`4.31GB(Linux)` ,但通过这个安装包下载这些内容可能很慢,于是助教把需要下载的东西打包成 `zip压缩包` 放到钉盘上了,链接如下:
68 |
69 | Windows版:[Windows版下载内容](https://space.dingtalk.com/s/gwHOAlHhHwLOQ5TVLAPaACA1YjZkZDI0NWZhNGY0NzdiOTY4MDlhNDJlODkxZDhkZA) 提取码: `Wgwc`。
70 |
71 | Linux版:[Linux版下载内容](https://space.dingtalk.com/s/gwHOAlHhHQLOQ5TVLAPaACA2ZTUxNWFhNjAxNDQ0NzU0YmE1MWE3MWIxOWRmMWM0MA) 提取码: `12pF`。
72 |
73 | 把压缩包里的文件解压到 `你输入的安装路径/Downloads`里,解压后的文件夹层次应当是这样的:
74 |
75 | 
76 |
77 | 随后回到安装程序,点击 `Install`,程序会很快结束下载步骤,进行安装:
78 |
79 | 
80 |
81 | 慢慢等进度条走完即可。
82 |
83 | 在Linux系统上安装Vivado的,需要在terminal里执行以下指令:
84 |
85 | ```bash
86 | cd /data/xicom/cable_drivers/lin64/install_script/install_drivers/install_drivers
87 | sudo ./install_drivers
88 | ```
89 |
90 | 其中 ``为 `Vivado`安装路径,后缀为 `Vivado/版本号`,和上文`Installation Summary`图中 `Installation Location`一致。
91 |
92 | ## 体验上板
93 |
94 | 今后的课程中,我们会写一些硬件代码。Vivado帮我们把这些硬件代码转换成二进制文件,我们把二进制文件装载进实验板,就能观察我们写的代码在实验板上的行为了。
95 |
96 | 我们先不写代码,只需要将助教事先准备好的二进制文件装载进实验板即可。
97 |
98 | ### Step 1:把实验板连接到电脑上
99 |
100 | 用盒子里的数据线把实验板连到电脑上,打开开关。
101 |
102 | 按下实验板上的 `CPU_RESETN`按钮,数码管上会有动画,这是实验板自带的。
103 |
104 | ### Step 2:打开Hardware Manager
105 |
106 | 打开 `Vivado`软件,点击 `Open Hardware Manager`,然后点击 `Open Target`, `Auto Connect`。
107 |
108 | 如果 `Hardware`界面没有实验板信息,请检查如下几点:
109 |
110 | * 实验板是否已开机
111 | * 数据线两端接口是否松动
112 |
113 | ### Step 3:烧写bit文件
114 |
115 | 点击 `Program Device`,将elearning上的 `display.bit`文件加载进实验板。
116 |
117 | 这个 `.bit`文件是助教模仿实验板自带的演示工程实现的,右边八个开关可以调速度:开关全部拨下的速度和实验板自带的演示工程相近,拨上则加速。
118 |
119 | ## 附录
120 |
121 | ### 数逻实验课学什么?
122 |
123 | 树莓派开发板已配备了CPU和操作系统。树莓派的开发,是用高级语言(如 `Python`)写软件代码交给板上CPU和OS来控制板上外设。
124 |
125 | 通过本课程的学习,大家将掌握:
126 |
127 | * 如何实现**专用硬件**完成所需要的功能、完成对外设的控制
128 | * 如何用**硬件描述语言**实现所需要的硬件
129 | * 如何用**软件**来调试硬件
130 | * 对**通用硬件**有基本的认识
131 |
132 | 实验课发布包的主要内容为:
133 |
134 | #### SystemVerilog语法与应用
135 |
136 | **SystemVerilog**是一种**硬件描述语言**。它的一部分语法和**C语言**类似,所以比较容易上手。
137 |
138 | **SystemVerilog**以很少的语法为基础——掌握了这些语法,就可以实现所有硬件了。这部分语法是必修的。
139 |
140 | 在讲某些数字部件时,还会引入一些**SystemVerilog**的进阶语法,目的是让代码更简洁、清晰。
141 |
142 |
143 |
144 | 可能还会有一些拓展,比如:
145 |
146 | #### Chisel语法与应用
147 |
148 | **Chisel**, `Constructing Hardware In a Scala Embedded Language`,是嵌入在高级语言 `Scala`的一种硬件描述语言。相比 `SystemVerilog`,`Chisel`支持面向对象、类型推断等特性,不仅可以大大减少硬件的代码量,代码的可读性、可移植性也大大提高。 开发者不仅可以用`Chisel`设计电路,更可以设计**电路生成器**,让AI也可以进行硬件设计。
149 |
150 |
151 |
152 | 实验的拓展部分还在筹划当中,欢迎向助教们提出改进建议!
--------------------------------------------------------------------------------
/notes/01开发流程(上)/01开发流程(上).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/01开发流程(上)/01开发流程(上).pdf
--------------------------------------------------------------------------------
/notes/01开发流程(上)/assets/account.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/01开发流程(上)/assets/account.PNG
--------------------------------------------------------------------------------
/notes/01开发流程(上)/assets/agree.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/01开发流程(上)/assets/agree.PNG
--------------------------------------------------------------------------------
/notes/01开发流程(上)/assets/customize.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/01开发流程(上)/assets/customize.PNG
--------------------------------------------------------------------------------
/notes/01开发流程(上)/assets/directory.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/01开发流程(上)/assets/directory.PNG
--------------------------------------------------------------------------------
/notes/01开发流程(上)/assets/edition.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/01开发流程(上)/assets/edition.PNG
--------------------------------------------------------------------------------
/notes/01开发流程(上)/assets/progress.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/01开发流程(上)/assets/progress.PNG
--------------------------------------------------------------------------------
/notes/01开发流程(上)/assets/structure.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/01开发流程(上)/assets/structure.PNG
--------------------------------------------------------------------------------
/notes/01开发流程(上)/assets/summary.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/01开发流程(上)/assets/summary.PNG
--------------------------------------------------------------------------------
/notes/02开发流程(中)/02开发流程(中).md:
--------------------------------------------------------------------------------
1 | # 数字逻辑与部件设计 实验部分-02.开发流程(中)
2 |
3 | Convert code to circuit.
4 |
5 | [TOC]
6 |
7 | ## 将已有的代码生成bit文件
8 |
9 | 我们已经学会了如何将bit文件载入实验板。现在,我们来学一下,有了硬件代码,如何生成bit文件。
10 |
11 | ### Step 0:在Vivado安装目录中添加实验板信息
12 |
13 | 将 `board_files.zip`的两个文件夹解压至 `/data/boards/board_files/`。
14 |
15 | 解压后的目录应如图所示:
16 |
17 | 
18 |
19 | ### Step 1:新建项目
20 |
21 | 打开Vivado,点击 `Create Project`,新建一个项目。
22 |
23 | 选择项目路径后,点下一步选择 `RTL Project` ,然后一直点击下一步,直到 `Default Part` 这个界面:
24 |
25 | 
26 |
27 | 点击上方的 `Boards`,选择 `Nexys4 DDR`,然后一直点下一步,直到项目新建成功。
28 |
29 | 
30 |
31 | ### Step 2:运行tcl脚本添加源文件
32 |
33 | 运行 `source/`目录下的 `sources.tcl`,一键添加所有需要的源文件。
34 |
35 | `sources.tcl`的内容如下:
36 |
37 | ```tcl
38 | # 进入当前目录
39 | cd [file dirname [info script]]
40 |
41 | # 添加所需源文件
42 | add_files top.sv
43 | add_files controller.sv
44 |
45 | # 设置顶层文件
46 | set_property top top [current_fileset]
47 |
48 | cd [file dirname [info script]]
49 |
50 | # 添加引脚约束文件
51 | add_files -fileset constrs_1 -norecurse Nexys4DDR_Master.xdc
52 |
53 | # 设置仿真文件
54 | set_property SOURCE_SET sources_1 [get_filesets sim_1]
55 | # 添加仿真文件
56 | add_files -fileset sim_1 -norecurse sim.sv
57 | # 设置仿真顶层
58 | set_property top sim [get_filesets sim_1]
59 | set_property top_lib xil_defaultlib [get_filesets sim_1]
60 | ```
61 |
62 | 以上提到了几种文件:
63 |
64 | * `源文件`:模块设计文件。
65 | * `顶层文件`:也属于源文件,作用是将已经写好的数字模块与实验板的引脚相连。
66 | * `引脚约束文件`:实验板的配置文件。
67 | * `仿真文件`和 `仿真顶层` :仿真用的测试文件。仿真的有关部分在下节课会讲。
68 |
69 | 这些tcl代码对应的操作都有图形化界面的操作对应。
70 |
71 | ### Step 3:开启多线程(optional)
72 |
73 | 在 `Tcl Console`中输入 `set_param general.maxThreads 16`开启多线程模式,对接下来的Step 4有一定的加速效果。
74 |
75 | ### Step 4:生成bitstream
76 |
77 | 点击Vivado界面左下角的 `Generate Bitstream`,然后一直选 `Yes`,有默认框的就✔一下,减少今后操作的点击次数。
78 |
79 | 有一步是确认用多少个job,这个对速度影响不大。
80 |
81 | 也可在 `Tcl Console`中输入: `reset_run synth_1; launch_runs impl_1 -to_step write_bitstream`
82 |
83 | ### Step 5:上板
84 |
85 | 点击左下角的 `Open target` --> `Auto Connect` --> `Program Device`,把默认路径的bitstream(路径应包含 `impl_1/` )烧写到实验板上。
86 |
87 | 实验板的现象和上一节课提供的bit文件一样。
88 |
89 | ## 硬件描述语言简介
90 |
91 | **硬件描述语言**(**HDL**, `Hardware Description Language`),顾名思义,是用来**描述硬件**的语言。
92 |
93 | ### 硬件描述语言与实际硬件
94 |
95 | 我们画过很多电路图(那些电路就是硬件),但那些都是小规模的电路。我们需要借助计算机的力量去设计大规模电路,而**硬件描述语言**是我们和计算机通信的桥梁。
96 |
97 | 这就要求我们了解硬件描述语言与实际硬件之间的关系。
98 |
99 | 以下是助教的一些学习心得:
100 |
101 | * 先有电路(图),再写HDL。
102 | * 用基本元件生成新的部件。掌握新部件对应的HDL写法后,就可以把新部件当成基本元件来使用了。
103 |
104 | ### 硬件描述语言与C语言
105 |
106 | 我们将要学习的硬件描述语言**SystemVerilog**,其语法形式和我们已经学过的 **C语言**类似,但它们的本质完全不同。
107 |
108 | 有人说,硬件描述语言是**并行语言**,C语言是**串行语言**。这个说法是正确的,不过两者差别的内涵在于**程序**与**电路**的差别。
109 |
110 | C语言经编译、链接后生成**程序**,而程序是由**指令序列**构成的。
111 |
112 | 而**电路**(**硬件**)是一个整体,以一个系统的方式运作着。
113 |
114 | 
115 |
116 | 这是一个简单的并联电路。我们能硬改某个灯上通过的电流吗?我们只能改变元器件接入电路系统的方式。
117 |
118 | ## SystemVerilog基础语法:二进制位
119 |
120 | ### 变量声明
121 |
122 | 在数字世界中,万物皆为0和1。在SystemVerilog中,万物皆为**logic**。
123 |
124 | ```verilog
125 | logic a;
126 | logic b;
127 | ```
128 |
129 | SV的变量命名规则与C语言类似,比如 `避开关键字`、`区分大小写`等。每句语句也以分号结尾。
130 |
131 | 变量的实际意义是电路中的节点。
132 |
133 | 接下来是**向量**:
134 |
135 | ```verilog
136 | logic [15:0]c; // 一维向量
137 | logic [15:0][15:0]d, e; /* 二位向量 */
138 | ```
139 |
140 | SV的向量和C的数组有以下几点不同:
141 |
142 | * SV的向量在声明时需确定上下界。
143 | * `logic [15:0]c;`和`logic [0:15]c;`都是合法的,分别代表大端法和小端法。
144 | * `logic [15:0]c;`和`logic c[15:0];`都是合法的,但后者只能`一位一位`地接入电路系统中。
145 | * SV的多维数组没有C中的多维数组寻址模式。
146 |
147 |
148 |
149 | 其实,logic是四值逻辑:`0, 1, x, z`。`x`和`z`在真实的电路中不存在,仅在软件仿真时有用。
150 |
151 | ### 常量
152 |
153 | SV的常量形式为`位宽+单引号+数据进制+数据`。需注意:
154 |
155 | * 位宽代表常量有多少位二进制。位宽必须为常量。
156 | * 数据进制为一个字符,常用的有二进制(b),十进制(d),十六进制(h)。
157 |
158 | 例:
159 |
160 | ```
161 | 1'b1
162 | 1'b0
163 | 16'habcd
164 | 10'd100
165 | ```
166 |
167 | ### 接入电路系统:assign语句
168 |
169 | 将变量接入电路系统,有三种方式:
170 |
171 | * **assign**语句
172 | * 元件例化
173 | * **always**语句(**always_comb**, **always_ff**, **always_latch**)
174 |
175 | 先介绍assign语句。
176 |
177 | ```verilog
178 | logic a;
179 | assign a = 1'b1;
180 | ```
181 |
182 | SV中,大括号`{}`代表**位拼接**。(代码段用``begin end``)
183 |
184 | ```verilog
185 | logic [15:0] a, b, c, d;
186 | assign a = 16'b1; // 16'b1 is 0x0001
187 | assign b = {4'b1010, 4'b0101, 4'b1100, 4'b0011};
188 | assign {c, d} = {32'hdeadbeef}; // c is 32'hdead, d is 32'hbeef
189 | ```
190 |
191 | 可以将新变量接入已知变量中:
192 |
193 | ```verilog
194 | logic [15:0] a, b, c, d;
195 | assign a = 16'b1;
196 | assign b = a;
197 | assign {c, d} = {a, a};
198 | ```
199 |
200 | 大括号`{}`可以实现位扩展:
201 |
202 | ```verilog
203 | logic [15:0] a;
204 | logic [15:0][15:0] b;
205 | assign a = {16{1'b1}};
206 | assign b = {16{a}};
207 | ```
208 |
209 | ## SystemVerilog基础语法:模块与元件
210 |
211 | 模块是一个小型电路系统,是数字设计中很重要的一个思想。
212 |
213 | ### 模块的定义
214 |
215 | 模块定义的语法如下:
216 |
217 | ```verilog
218 | module ModuleName(
219 | // ports
220 | );
221 | // logics
222 | endmodule
223 | ```
224 |
225 | `module`和`endmodule`为模块定义的关键字
226 |
227 | `ModuleName`为模块名。
228 |
229 | `// ports`部分为输入输出接口的声明(一般只声明),会用到`input`和`output`关键字。
230 |
231 | `// logics`部分为模块内部电路。
232 |
233 | 以下为一个模块定义的例子:
234 |
235 | ```verilog
236 | module SignExtend(
237 | input logic [15:0]a,
238 | output logic [31:0]b
239 | );
240 | assign b = {{16{a[15]}}, a};
241 | endmodule
242 | ```
243 |
244 | ### 元件例化:模块接入电路系统
245 |
246 | 元件例化有几种语法形式:
247 |
248 | ```Verilog
249 | ModuleName InstanceName1(.ports1(variable1), ports2(variable2), ...); // 变量和端口对应
250 | ModuleName InstanceName2(.ports1, .ports2, ...); // 端口ports1接到同名变量
251 | ModuleName InstanceName3(.ports1(variable3), .*); // 端口ports1接到变量variable3,其他端口都接到同名变量
252 | ```
253 |
254 | 例:
255 |
256 | ```verilog
257 | module UseSignExtend(
258 |
259 | );
260 | logic [16:0] a;
261 | logic [31:0] b, c ,d;
262 | SignExtend signextend1(.a(a), .b(c));
263 | SignExtend signextend2(.a, .b(d));
264 | SignExtend signextend3(.a, .*);
265 | endmodule
266 |
267 | module SignExtend(
268 | input logic [15:0]a,
269 | output logic [31:0]b
270 | );
271 | assign b = {{16{a[15]}}, a};
272 | endmodule
273 | ```
274 |
275 | 有一些代码规范:
276 |
277 | * 元件名、模块名和变量名的大小写关系
278 | * 用哪种元件例化的语法形式
279 |
280 |
281 |
282 | 注:顶层模块通过约束文件接入实验板,没有例化。
283 |
284 | ### 更加简便的设计
285 |
286 | 模块设计和函数设计的初衷是类似的,把整体设计切成部分,简化设计步骤。
287 |
288 | 画电路图时,也可以把已经学过的电路元件放进电路图里。
289 |
290 | ### 黑盒
291 |
292 | 先定义接口,再想怎样设计
293 |
294 | ## SystemVerilog基础语法:运算符
295 |
296 | 我们已经学了数字电路的基本元件与门、或门和非门。它们在SV中分别用`&`、`|`、`~`表示。
297 |
298 | ```verilog
299 | logic [15:0] a, b, c, d, e;
300 | assign c = a & b;
301 | assign d = a | b;
302 | assign e = ~a;
303 | ```
304 |
305 | `&`和`|`还有另一种用法:
306 |
307 | ```verilog
308 | logic [3:0] a;
309 | logic b, c;
310 | assign b = |a; // b = a[0] | a[1] | a[2] | a[3]
311 | assign c = &a; // c = a[0] & a[1] & a[2] & a[3]
312 | ```
313 |
314 | 除了基本的逻辑门,SV还支持以下几种运算符:
315 |
316 | ```verilog
317 | logic [15:0] a, b, c, d, e, f, g, j, k;
318 | logic [15:0] h, i;
319 | assign c = a + b; // adder
320 | assign [15:0] d = a - b;
321 | assign [15:0] e = a << b[3:0]; // shifter
322 | assign [15:0] f = a >> b[3:0]; // shift right logically
323 | assign [15:0] g = a >>> b[3:0]; // shift right arithmetically
324 | assign [31:0] h = a * b; // multiplier
325 | assign [31:0] i = a / b; // divider
326 | assign [15:0] j = (a == b) ? a + 1 : b - 1; // a multiplexer
327 | assign [15:0] k = a ^ b; // XOR
328 | ```
329 |
330 | SV中运算符所代表的电路都可用`assign`语句接入电路系统中。
--------------------------------------------------------------------------------
/notes/02开发流程(中)/02开发流程(中).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/02开发流程(中)/02开发流程(中).pdf
--------------------------------------------------------------------------------
/notes/02开发流程(中)/assets/board_files.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/02开发流程(中)/assets/board_files.PNG
--------------------------------------------------------------------------------
/notes/02开发流程(中)/assets/circuit.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/02开发流程(中)/assets/circuit.jpg
--------------------------------------------------------------------------------
/notes/02开发流程(中)/assets/default_board.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/02开发流程(中)/assets/default_board.PNG
--------------------------------------------------------------------------------
/notes/02开发流程(中)/assets/default_part.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/02开发流程(中)/assets/default_part.PNG
--------------------------------------------------------------------------------
/notes/02开发流程(中)/board_files.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/02开发流程(中)/board_files.zip
--------------------------------------------------------------------------------
/notes/03开发流程(下)/03开发流程(下).md:
--------------------------------------------------------------------------------
1 | # 数字逻辑与部件设计 实验部分-03.开发流程(下):仿真
2 |
3 | `Software debug.`
4 |
5 | 大家在上一节课已经体验了从硬件代码到上板的流程,感受到了生成硬件的`bitstream`文件很慢。所以我们需要更高效的调试方法,也就是这节课的内容:仿真。
6 |
7 | 助教录了一个Vivado仿真流程的视频,[视频链接](https://www.bilibili.com/video/BV17T4y1c7PZ)
8 |
9 | 本文档主要介绍仿真专用的一些语法(写电路用的语法在仿真文件中都可以用)。**这些语法没有对应的电路,只能用于仿真!**
10 |
11 |
12 |
13 | ## 仿真文件架构
14 |
15 | 仿真文件以一个无输入输出端口的模块作为顶层(假设命名为`sim`):
16 |
17 | ```verilog
18 | module sim();
19 |
20 | endmodule
21 | ```
22 |
23 | 在这个模块里,例化一个(或很多个)我们待调试的模块,然后生成待调试模块的输入激励信号,检查模块内部信号和输出。
24 |
25 | ## #:延时
26 |
27 | 我们希望在各个时刻给我们写的数字模块不同的输入激励。`#`语法的作用是延时,可以满足我们的这个要求。
28 |
29 | `#`作用于verilog语句前。
30 |
31 | ## initial语句
32 |
33 | initial语句的语法:
34 |
35 | ```verilog
36 | initial begin
37 |
38 | end
39 | ```
40 |
41 | 在initial语句块中,软件会**顺序**地执行每一条语句。
42 |
43 | 不用`#`延时语法的语句被认为在同一时刻执行。
44 |
45 | 例:
46 |
47 | ```verilog
48 | logic b;
49 | initial begin
50 | b = 1'b1;
51 | #10 b = 1'b0; // delay 10 ns
52 | end
53 | ```
54 |
55 | 可以有多个initial block,用于不相关的信号集合的生成。
56 |
57 | ## 系统函数
58 |
59 | 常用的系统函数有三个:
60 |
61 | * `$display`,语法和c语言的`printf`一致,用于在`Tcl Console`输出信息,提供了一种波形图以外的调试方法。
62 | * `$time`,配合`$display`适用,获取当前时刻。
63 | * `$finish`,中止仿真。
64 |
65 | ## task
66 |
67 | 有些task可以映射到电路,但不推荐写电路时用task。
68 |
69 | task的语法和module类似:
70 |
71 | ```verilog
72 | task taskName();
73 |
74 | endtask
75 | ```
76 |
77 | task内部的语句会被顺序执行。
78 |
79 | 在仿真中,常用的task是比较答案与模块的实际信号:
80 |
81 | ```verilog
82 | task check(input logic ans, input logic get);
83 | #10
84 | if(ans != get) begin
85 | // do something
86 | end
87 | endtask
88 | ```
89 |
90 |
--------------------------------------------------------------------------------
/notes/03开发流程(下)/03开发流程(下).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/03开发流程(下)/03开发流程(下).pdf
--------------------------------------------------------------------------------
/notes/lab1/SV Syntax for lab1.md:
--------------------------------------------------------------------------------
1 | # SV语法:Decoder and Encoder
2 |
3 | ## always_comb
4 |
5 | `always_comb`用于描述复杂电路。
6 |
7 | ```verilog
8 | always_comb begin
9 |
10 | end
11 | ```
12 |
13 | `begin end`中的语句为串行执行。
14 |
15 | `always_comb`中的语句为`val1 = val2;`的形式。
16 |
17 | 把`always_comb`看成一个模块:所有`=`左边的变量为输出,`=`右边的(且没在`=`左边出现过)为输入。
18 |
19 | 各`always_comb`为并行关系。
20 |
21 | ## unique case
22 |
23 | ```verilog
24 | logic [3:0]a;
25 | logic b;
26 | always_comb begin
27 | unique case(a)
28 | 4'b1: begin
29 | b = 1'b1;
30 | end
31 | 4'b10: begin
32 | b = 1'b1;
33 | end
34 | default: begin
35 | b = 1'b0;
36 | end
37 | endcase
38 | end
39 | ```
40 |
41 | ## priority case
42 |
43 | ```verilog
44 | logic [3:0]a;
45 | always_comb begin
46 | priority case(1'b1)
47 | a[3]: begin
48 |
49 | end
50 | a[2]: begin
51 |
52 | end
53 | a[1]: begin
54 |
55 | end
56 | a[0]: begin
57 |
58 | end
59 |
60 | endcase
61 | end
62 | ```
63 |
64 |
--------------------------------------------------------------------------------
/notes/lab1/display.md:
--------------------------------------------------------------------------------
1 | # Lab1 译码器与编码器
2 |
3 | [TOC]
4 |
5 | ## 高电平有效/低电平有效
6 |
7 | 用二进制所表示的信息,`0`不一定表示`false`,`1`不一定表示`true`。
8 |
9 | 人们约定了一种表示信息的习惯,对于某类信息,大家都用`1`表示`true`(高电平有效)或都用`0`表示`true`(低电平有效)
10 |
11 | sv的`if`认为`1`是`true`,所以有两种写法:
12 |
13 | ```verilog
14 | // reset: high effective
15 | if (reset) begin
16 |
17 | end
18 |
19 | // resetn: low effective
20 | if (~resetn) begin
21 |
22 | end
23 | ```
24 |
25 | 本实验采用高电平有效的约定。
26 |
27 | ## 2-4 Decoder With Enable Bit
28 |
29 | $$
30 | n \ bits \ input; \
31 | 2^n \ bits \ output
32 | $$
33 |
34 | | en | in[1] | in[0] | out[3] | out[2] | out[1] | out[0] |
35 | | ---- | ----- | ----- | ------ | ------ | ------ | ------ |
36 | | 0 | x | x | 0 | 0 | 0 | 0 |
37 | | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
38 | | 1 | 0 | 1 | 0 | 0 | 1 | 0 |
39 | | 1 | 1 | 0 | 0 | 1 | 0 | 0 |
40 | | 1 | 1 | 1 | 1 | 0 | 0 | 0 |
41 |
42 | ### x
43 |
44 | | en | in[1] | in[0] | out[3] | out[2] | out[1] | out[0] |
45 | | ---- | ----- | ----- | ------ | ------ | ------ | ------ |
46 | | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
47 | | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
48 | | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
49 | | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
50 |
51 | ## 4-2 Encoder
52 |
53 | $$
54 | 2^n\ bits\ input;\ n\ bits\ output
55 | $$
56 |
57 | | in[3] | in[2] | in[1] | in[0] | out[1] | out[0] |
58 | | ------ | ----- | ----- | ----- | ------ | ------ |
59 | | 0 | 0 | 0 | 1 | 0 | 0 |
60 | | 0 | 0 | 1 | 0 | 0 | 1 |
61 | | 0 | 1 | 0 | 0 | 1 | 0 |
62 | | 1 | 0 | 0 | 0 | 1 | 1 |
63 | | others | | | | x | x |
64 |
65 | ## 4-2 Priority Encoder
66 |
67 | | in[3] | in[2] | in[1] | in[0] | out[1] | out[2] |
68 | | ----- | ----- | ----- | ----- | ------ | ------ |
69 | | 1 | x | x | x | 1 | 1 |
70 | | 0 | 1 | x | x | 1 | 0 |
71 | | 0 | 0 | 1 | x | 0 | 1 |
72 | | 0 | 0 | 0 | 1 | 0 | 0 |
73 | | 0 | 0 | 0 | 0 | x | x |
74 |
75 |
--------------------------------------------------------------------------------
/notes/systemverilog/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/systemverilog/1.jpg
--------------------------------------------------------------------------------
/notes/systemverilog/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/systemverilog/2.jpg
--------------------------------------------------------------------------------
/notes/systemverilog/systemverilog语法简介.md:
--------------------------------------------------------------------------------
1 | # SystemVerilog语法简介
2 |
3 | [TOC]
4 |
5 | ## 变量
6 |
7 | `SystemVerilog`基本变量为`logic`。万物皆为 `logic`。
8 |
9 | `SystemVerilog`的每个变量对应着电路中的一个节点。
10 |
11 | 变量有一位的,也有向量类型。
12 |
13 | ```verilog
14 | logic a;
15 | logic [15:0] b;
16 | ```
17 |
18 | ## 常量
19 |
20 | `SystemVerilog`的常量为若干位0和1的组合。
21 |
22 | ## 操作符
23 |
24 | 每个操作符对应一个逻辑门或数字模块。
25 |
26 | | 操作符 | 对应电路元件 | 备注 |
27 | | ------------------- | ------------------ | --------------------------------------- |
28 | | `&` | 与门 | 有缩位的用法 |
29 | | `|` | 或门 | 有缩位的用法 |
30 | | `~` | 非门 | |
31 | | `+` | 加法器 | |
32 | | `-` | 减法器 | |
33 | | `*` | 单周期乘法器 | 输出位数为输入的两倍 |
34 | | `/` | 单周期除法器 | |
35 | | `>`, `<`等比较符号 | 比较器 | 有一个操作数含`X`时,结果未知 |
36 | | `<<`,`>>>`,`>>` | 移位器(多种实现) | 右操作数的位数应为左操作数位数的对数 |
37 | | `? : ` | 二选一选择器 | |
38 | | `++` | | 几乎仅在`for`循环中使用,无对应电路元件 |
39 | | `{}` | 位绑定或扩位 | 位绑定或扩位 |
40 | | 无操作符 | 电路直接连线 | 等号左右两边对应同一节点 |
41 |
42 | ## assign语句
43 |
44 | `assign`语句用于描述可用操作符实现的电路元件,常用于描述已有电路图或简单逻辑。
45 |
46 | 写法举例:
47 |
48 | 
49 |
50 | ## 模块、元件例化
51 |
52 | `module`是电路设计中很重要的概念,可封装逻辑细节,只暴露接口。
53 |
54 | * 在多人协作中,每人写一些模块,可确保每个人写的逻辑独立,也方便拼接。
55 | * 想实现某个功能但写不出电路时,可以先放一个元件,把接口定好,等宏观的电路结构搭好后再实现细节。
56 |
57 | 模块和元件类似于c++中的类与对象的概念。
58 |
59 | 元件例化用于描述电路图中的抽象逻辑部件,常用于描述已有电路图。
60 |
61 | 写法举例:
62 |
63 | 
64 |
65 | ## always_comb block
66 |
67 | `always_comb`代码块用于描述组合逻辑,常用于描述已知逻辑功能、真值表而无法用门电路描述、难以拆分成模块的电路。
68 |
69 | `always_comb`可视为一个封闭的模块:其有一定的输入和输出,输出为块内所有语句等号左侧的变量;对模块内,所有语句顺序执行,交换语句顺序可能改变结果(`assign`语句、元件例化语句、各`always_comb`模块间顺序无关);对模块外,其行为相当于运行完最后一句语句后,一次性对外“展示”所有输出。
70 |
71 | `always_comb`描述的行为,由编译器转化为门电路。
72 |
73 | `always_comb`中的变量必须在各个情况下都有值,且不应将输出作为输入。(这条对应的电路是锁存器,应避免)
74 |
75 | 以下介绍一些仅用在`always_comb`或`always_ff`中的语句。
76 |
77 | ### unique/priority case
78 |
79 | `case`语句和C语言的`switch`类似,用于描述`对于某个信号的不同情况,做不同的事`。
80 |
81 | ```verilog
82 | always_comb begin
83 | unique case(a)
84 | // 各情况无优先级,unique可省略
85 | endcase
86 |
87 | priority case(1'b1)
88 | // 各情况有优先级,故priority case后经常跟着常量
89 | endcase
90 | end
91 | ```
92 |
93 | ### unique/priority if
94 |
95 | `if`和`case`的作用类似。
96 |
97 | ```verilog
98 | always_comb begin
99 | // 各情况无优先级,少用
100 | unique if(a == 1'b1) begin
101 |
102 | end else if (b == 1'b1) begin
103 |
104 | end else begin
105 |
106 | end
107 |
108 | // 各情况有优先级,priority可省略
109 | priority if(a == 1'b1) begin
110 |
111 | end else if (b == 1'b1) begin
112 |
113 | end else begin
114 |
115 | end
116 | end
117 | ```
118 |
119 | ### for循环
120 |
121 | `for`循环用于复制电路。循环次数必须显式指出(思考:`for`循环如何映射到电路?)。
122 |
123 | 和`for`循环相关的语法有`break`,`continue`,其意义和C语言中的一致。
124 |
125 | ## always_ff block
126 |
127 | `always_ff`适用于D触发器模型。
128 |
129 | 一个最基本的D触发器:
130 |
131 | ```verilog
132 | logic a, b;
133 | always_ff @(posedge clk) begin
134 | a <= b;
135 | end
136 | ```
137 |
138 | 同步复位的D触发器:
139 |
140 | ```verilog
141 | logic a, b;
142 | always_ff @(posedge clk) begin
143 | if (~resetn) begin
144 | a <= '0;
145 | end else begin
146 | a <= b;
147 | end
148 | end
149 | ```
150 |
151 | 异步复位的D触发器:
152 |
153 | ```verilog
154 | logic a, b;
155 | always_ff @(posedge clk, negedge resetn) begin
156 | if (~resetn) begin
157 | a <= '0;
158 | end else begin
159 | a <= b;
160 | end
161 | end
162 | ```
163 |
164 | 带时钟使能的D触发器:
165 |
166 | ```verilog
167 | logic a, b;
168 | always_ff @(posedge clk) begin
169 | if (~resetn) begin
170 | a <= '0;
171 | end else if(~stall) begin
172 | a <= b;
173 | end
174 | end
175 | ```
176 |
177 | 状态机、流水线寄存器写法:
178 |
179 | ```verilog
180 | logic [31:0]a, a_nxt;
181 |
182 | // Filp-flops
183 | always_ff @(posedge clk) begin
184 | if(~resetn) begin
185 | a <= '0;
186 | end else begin
187 | a <= a_nxt;
188 | end
189 | end
190 |
191 | // Next-state function
192 | always_comb begin
193 | a_nxt = a;
194 |
195 | // set the next state of a
196 | end
197 |
198 | // Output function
199 | assign out = |a;
200 | ```
201 |
202 | `always_ff`代码块内应只描述触发器的功能(可带上`clock enable`,`reset`),次态函数的其他逻辑应在`always_comb`中实现。
203 |
204 | ## 更多的类型
205 |
206 | 万物皆为`logic`,对编程者来说比较不友好。比如编码和信息,我们希望用不同的类型来标识它们。
207 |
208 | `SystemVerilog`提供了一些语法,使编程者可以拥有更多类型,但本质还是`logic`。
209 |
210 | ### typedef
211 |
212 | ```verilog
213 | typedef logic[31:0] uint32_t;
214 | typedef logic[31:0][31:0] cp0_regs_t;
215 |
216 | uint32_t a, b;
217 | ```
218 |
219 | ### struct
220 |
221 | ```verilog
222 | typedef struct packed {
223 | virtual_addr_t addr;
224 | logic en;
225 | } read_req_t;
226 |
227 | read_req_t read_req;
228 | assign read_req = {
229 | 32'h80000000,
230 | 1'b1
231 | };
232 |
233 | logic k;
234 | assign k = read_req.en;
235 | ```
236 |
237 | ### enum
238 |
239 | `enum`多用于编码。
240 |
241 | ```verilog
242 | typedef enum logic[1:0] {
243 | INIT, RED, BLUE
244 | } state_t;
245 |
246 | state_t state, state_nxt;
247 | ```
248 |
249 | ### union
250 |
251 | ```verilog
252 | typedef logic[7:0] byte_t;
253 | typedef union packed {
254 | logic [31:0]a;
255 | byte_t [3:0]b;
256 | } word_t;
257 | ```
258 |
259 | ## 参数
260 |
261 | 为了使模块的复用性更高,可以在模块定义时设置参数。
262 |
263 | 参数被视为常数。
264 |
265 | 参数可为数值或类型。
266 |
267 | ```verilog
268 | module #(
269 | parameter W = 32 // default value
270 | ) myAdder1 (
271 | input logic [W-1:0] a, b,
272 | output logic [W-1:0] c
273 | );
274 | assign c = a + b;
275 | endmodule
276 |
277 | module #(
278 | parameter type add_type = logic[31:0]
279 | ) myAdder2 (
280 | input add_type a, b,
281 | output add_type c
282 | );
283 | assign c = a + b;
284 | endmodule
285 |
286 | module top();
287 | logic [15:0] a, b, c, d;
288 | myAdder1 #(.W(16)) adder1(.a, .b, .c);
289 | myAdder2 #(.add_type(logic [15:0])) adder2(.a, .b, .c(d));
290 | endmodule
291 | ```
292 |
293 |
--------------------------------------------------------------------------------
/notes/systemverilog/systemverilog语法简介.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/systemverilog/systemverilog语法简介.pdf
--------------------------------------------------------------------------------
/notes/实验一/img/decoder:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/实验一/img/decoder
--------------------------------------------------------------------------------
/notes/实验一/img/encoder:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/实验一/img/encoder
--------------------------------------------------------------------------------
/notes/实验一/实验一 译码器与编码器.md:
--------------------------------------------------------------------------------
1 | # 实验一 译码器与编码器
2 |
3 | ## 实验背景
4 |
5 | ### 基础概念
6 |
7 | 译码器是计算机系统中最常用的逻辑部件之一,用来完成对操作码的译码。编码是把输入的高低电平信号编成一个对应的二进制码。实现编码操作的电路称作编码器;按是否有优先权编码,可分为普通编码器和优先编码器
8 |
9 |
10 |
11 | 
12 |
13 | 若输入的二进制码对应的十进制数为i,则输出数的第i位为1,其余位为0。(高电平有效)
14 |
15 |
16 |
17 | 
18 |
19 | ### 相关知识
20 |
21 | 3-8译码器有3个输入(s[2:0])和8个输出(y[7:0]),其真值表如下:(高电平有效)
22 |
23 | | s[2] | s[1] | s[0] | y[7] | y[6] | y[5] | y[4] | y[3] | y[2] | y[1] | y[0] |
24 | | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
25 | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
26 | | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
27 | | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
28 | | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
29 | | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
30 | | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
31 | | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
32 | | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
33 |
34 | ------
35 |
36 | 8-3编码器有8个输入(i[7:0])和3个输出(f[2:0]),其真值表如下:
37 |
38 | | i[7] | i[6] | i[5] | i[4] | i[3] | i[2] | i[1] | i[0] | f[2] | f[1] | f[0] |
39 | | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
40 | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
41 | | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
42 | | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 |
43 | | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 |
44 | | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
45 | | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
46 | | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
47 | | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 |
48 |
49 | ## 实验内容
50 |
51 | 1. 参考上述真值表,设计一个4-16译码器(可以使用case语句,或者直接使用简单的与或非门),增加使能en,当en=0时,输出全部为低电平,当en=1时,正常译码。
52 | 2. 利用实验内容1中设计的4-16译码器模块,设计一个5-32译码器(使用模块实例化)。
53 | 3. 设计一个16-4普通编码器(参考表格2)。
54 | 4. 设计一个16-4优先编码器(输入的第15位优先级最高,第0位优先级最低)。
55 |
56 | ## 实验需知
57 |
58 | 以下介绍一下本学期实验部分的安排:
59 |
60 | 1. 第n周的周一实验课的主要工作:
61 |
62 | - 将第n周的实验进行上板验证并进行一定的讲解。
63 | - 布置第n+1周的实验并讲解需用但未学的语法,在第n+1周的实验课之前完成仿真验证工作。
64 | - 在第n周的周二晚上23:59:59之前在elearning上提交本次实验内容,包含实验中所写的.sv文件以及实验报告。
65 |
66 | 2. 实验报告只需要大致总结该次实验即可,具体内容不限,格式为学号_姓名.pdf
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/notes/实验一/实验一 译码器与编码器.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/实验一/实验一 译码器与编码器.pdf
--------------------------------------------------------------------------------
/notes/实验三/实验三 加法器及快速进位电路的设计.md:
--------------------------------------------------------------------------------
1 | # 实验三 加法器及快速进位电路的设计
2 |
3 | ## 实验背景
4 |
5 | ### 基础知识
6 |
7 | 加法器是产生数的和的装置。加数和被加数为输入,和数与进位为输出的装置为半加器。若加数、被加数与低位的进位数为输入,而和数与进位为输出则为全加器。常用作计算机算术逻辑部件,执行逻辑操作、移位与指令调用。在电子学中,加法器是一种数位电路,其可进行数字的加法计算。(百度百科)
8 |
9 | ### 输入信号
10 |
11 | 一位全加器的输入信号为:本位输入A、B,低进位信号Cin
12 |
13 | ### 输出信号
14 |
15 | 一位全加器的输出信号为:本位输出C,进位输出Co
16 |
17 | ### 真值表
18 |
19 | | A | B | Cin | S | Co |
20 | | ---- | ---- | ---- | ---- | ---- |
21 | | 0 | 0 | 0 | 0 | 0 |
22 | | 0 | 0 | 1 | 1 | 0 |
23 | | 0 | 1 | 0 | 1 | 0 |
24 | | 0 | 1 | 1 | 0 | 1 |
25 | | 1 | 0 | 0 | 1 | 0 |
26 | | 1 | 0 | 1 | 0 | 1 |
27 | | 1 | 1 | 0 | 0 | 1 |
28 | | 1 | 1 | 1 | 1 | 1 |
29 |
30 | ## 实验内容
31 |
32 | 1、设计一个一位全加器,一个二位全加器(参考一位全加器的设计思想)。
33 |
34 | 2、以上述一位全加器为模块,设计一个4位行波进位加法器。
35 |
36 | 3、设计一个含超前进位电路的4位加法器。
37 |
38 |
--------------------------------------------------------------------------------
/notes/实验二/img_lab2/身份证.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/实验二/img_lab2/身份证.jpg
--------------------------------------------------------------------------------
/notes/实验二/实验二 译码与编码的应用.md:
--------------------------------------------------------------------------------
1 | # 实验二 译码与编码的应用
2 |
3 | ## 实验背景
4 |
5 | ### 日常应用
6 |
7 | 在上次实验课中,大家已经实现了一个简单的译码器和编码器,在这次实验课中,大家将会体会到译码和编码在实际中的应用。
8 |
9 | 首先我们要明确译码和编码的作用是什么。简单来讲,在生活中,编码就是将一系列的信息按照某个规则编写成一串数字,而译码就是将一串数字按照某个则翻译成对应的信息。例如下图是我国身份证的编码格式:
10 |
11 |
12 |
13 |
14 |
15 | 每个人都有自己对应的身份证号,在你出生的时候,会根据你的登记所在地,生日等信息,按照身份证的编码规则(在此不多赘述),编成一个属于你自己的身份证号。同样,根据一个人的身份证号和编码规则,你也能够很容易得知道这个人的出生地,生日,性别等各种信息。而这,便是编码和译码在生活中的应用。
16 |
17 | 当然,不仅如此,编码和译码在计算机领域之中还有很多其他的应用,例如各类指令集等。在本次实验中,我们将会着重锻炼大家对编码和译码知识的掌握和迁移。
18 |
19 | ### 编码规则
20 |
21 | 本次实验中,我们将会为大家提供一种新的编码的规则和各种编码,大家需要对其进行译码操作,并输出译码后相关的各种信号(由我们提供)的值。
22 |
23 | 以下是编码规则(参考了MIPS指令集),一条需要被译码的指令一共有32位,指令的运算方式由op和funct唯一决定,以下从左往右分别是从第31位到第0位,且以下所有运算均不需要考虑溢出的情况:
24 |
25 | | 指令 | op(6) | imm1(8) | imm2(8) | shamt(3) | (1) | funct(6) | 作用 |
26 | | ---- | ------- | --------- | --------- | ---------- | ---- | ---------- | -------------------------- |
27 | | ADD | 000000 | 8位操作数 | 8位操作数 | x | 0 | 100000 | imm1与imm2相加 |
28 | | SUB | 000000 | 8位操作数 | 8位操作数 | x | 0 | 100010 | imm1-imm2 |
29 | | SLT | 000000 | 8位操作数 | 8位操作数 | x | 0 | 101010 | if imm1 Q^(n+1) | D |
25 | | -------------- | ---- |
26 | | 0 0 | 0 |
27 | | 0 1 | 1 |
28 | | 1 0 | 0 |
29 | | 1 1 | 1 |
30 |
31 | +++
32 |
33 | 触发器除了同步输入端外,还有异步输入端(包括置1端SET和清零端CLR);不同的触发器可以通过加入组合电路来实现功能转换。触发器可以组合构成不同类型的寄存器。
34 |
35 | ### 寄存器
36 |
37 | 寄存器是用来暂时存放一组二进制代码的器件,主要分为数码寄存器和移位寄存器;数码寄存器在时钟脉冲的作用下,实现数据的并行接收、存储和传送;常用的数码寄存器器件有74LS175和74LS273等;74LS175的功能见表5-7.移位寄存器除了有存储功能外,还可以在时钟脉冲的作用下对数据实现移位功能,移位寄存器器件有74LS164和74LS194等;
38 |
39 | +++
40 |
41 | **74LS175的功能表:**
42 |
43 | | RD CP | 工作状态 |
44 | | ----------------- | -------- |
45 | | 0 X | 异步清零 |
46 | | 1 上升沿 | 数据存放 |
47 | | 1 0 | 数据保存 |
48 |
49 | **74LS194的功能表:**
50 |
51 | | RD | A1 A0 | 工作状态 |
52 | | ---- | ------------------------------------- | -------- |
53 | | 0 | X X | 异步清零 |
54 | | 1 | 0 0 | 数据保持 |
55 | | 1 | 0 1 | 右移 |
56 | | 1 | 1 0 | 左移 |
57 | | 1 | 1 1 | 并行置数 |
58 |
59 | ## 实验内容
60 |
61 | 1、用System Verilog语言描述带异步清零和异步置数的D触发器,编译并实现器件逻辑功能。
62 |
63 | 2、用输出分别为q1和q0的两个D触发器设计一个2位的加法计数器。其中,q1为高位。
64 |
65 | 3、用D触发器构成74LS175。
66 |
67 | 4、用System Verilog语言描述74LS194双向移位寄存器。
--------------------------------------------------------------------------------
/notes/实验六/light.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tan-YiFan/DigitalLogic-Autumn2020/16b01a6821442972196e63071d12f88b6bf98ea7/notes/实验六/light.jpg
--------------------------------------------------------------------------------
/notes/实验六/实验六 有限状态机_1.md:
--------------------------------------------------------------------------------
1 | # 实验六 有限状态机
2 |
3 | ## 实验背景
4 |
5 | 有限状态机是一种用来进行对象行为建模的工具,其作用主要是描述对象在它的生命周期内所经历的状态序列,以及如何响应来自外界的各种事件。在计算机科学中,有限状态机被广泛用于建模应用行为、硬件电路系统设计、软件工程,编译器、网络协议、和计算与语言的研究。
6 |
7 | ## 实验内容
8 |
9 | 1、用System Verilog语言设计一个摩尔状态机,使其可以检测序列“1101”。
10 |
11 | 2、用System Verilog语言设计一个交通灯控制器,要求实现的功能:
12 |
13 | - 交通灯位于四个方向(东、南、西、北)
14 |
15 | - 南北和东西向在同一时间亮相同的灯
16 |
17 | - 灯变化的次序为:绿-黄-红,循环
18 |
19 | - 南北和东西向灯不同时为绿灯或黄灯
20 |
21 | - 灯的持续时间:绿:45s,黄:15s,红:60s
22 |
23 | - 拥有reset按钮,按下后回到初始状态
24 |
25 | +++
26 |
27 | **功能流程图:**
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/notes/实验四/实验四 算数逻辑单元的设计.md:
--------------------------------------------------------------------------------
1 | # 实验四 算数逻辑单元的设计
2 |
3 | ## 实验背景
4 |
5 | 算数逻辑单元,简称ALU(Arithmetic & Logical Unit),是CPU的核心部件,能实现多组算术运算和逻辑运算的组合逻辑电路。
6 |
7 | ## 实验简介
8 |
9 | 本次实验是在实验二的基础上所做,用实验二的部分输出信号作为本次实验的输入信号,进而设计一个算数逻辑单元,所以需要用到实验二的模块。
10 |
11 | 算数逻辑单元模块共有四个输入,分别为实验二中输出的ALU相关的4位信号,8位的imm1,8位的imm2,以及3位的shamt,共有一个输出,为经ALU计算后的8位运算结果。在本次实验之中,不需要考虑类似加法溢出等各种特殊情况,正常计算即可。
12 |
13 | 下表为示例:
14 |
15 | | ALU相关4位信号 | 需要进行的操作 | 输出(8位) |
16 | | -------------- | ------------------------------------------------------------ | ----------------------------------------- |
17 | | 0000 | 利用imm1,imm2,shamt中的一个或几个进行A运算(即实验二中0000所编码的运算) | 运算后的结果,例如加法的结果则为imm1+imm2 |
18 |
19 | ## 实验内容
20 |
21 | 1、在实验二的基础上,利用System Verilog语言实现上述算数逻辑单元。
--------------------------------------------------------------------------------
/syntax/10interface/interface.md:
--------------------------------------------------------------------------------
1 | # 高级语法(4):抽象接口interface
2 |
3 | 电路图清晰地标明了元件的每位输入是从哪个元件的输出得到的,而元件例化语句无法做到这一点:
4 |
5 | * 元件例化语句不标出信号是作为输入还是输出
6 | * 信号相关模块的例化代码可能隔了很远
7 |
8 | 同时,模块接口部分的代码,在语法上也有可改进的地方:
9 |
10 | * 不同模块可能复用一部分接口
11 | * 添加一个接口,需要修改多处代码
12 |
13 | interface语法可以解决这一些问题,其语法形式与模块类似,具体为:
14 |
15 | ```verilog
16 | interface interface_name(input logic d, output logic e);
17 | // signals
18 | logic c;
19 |
20 | // modports
21 | modport modport_name1(input c, d, output e);
22 | modport modport_name2(output c);
23 | endinterface
24 |
25 | // module
26 | module module_name(
27 | interface_name.modport_name1 variable_name // input logic c, d, output logic e
28 | );
29 | // use `variable_name` like a struct
30 | logic d;
31 | assign d = variable_name.c;
32 |
33 | assign variable_name.e = d;
34 | endmodule
35 |
36 | module top();
37 | // instantiate an interface involves declaring the singals inside it
38 | interface_name intf_inst(.d(), .e());
39 | // logic c, d, e
40 | module_name instance_name(.variable_name(intf_inst.modport_name1));
41 |
42 | interface_name intf_inst2(.d(), .e());
43 | endmodule
44 | ```
45 |
46 | 把interface的声明放到头文件里,可以大幅减少源代码量。
47 |
48 | Verilator暂不支持interface语法。
49 |
50 |
--------------------------------------------------------------------------------
/syntax/1bits/bits.drawio:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/syntax/1bits/bits.md:
--------------------------------------------------------------------------------
1 | # 二进制
2 |
3 | 数字电路中,万物皆为二进制
4 |
5 | ## 常量
6 |
7 | ```verilog
8 | 1'b1
9 | 1'b0
10 | 16'habcd
11 | 4'd10
12 | ```
13 |
14 | ## 变量
15 |
16 | ```verilog
17 | logic a;
18 | logic [3:0]b;
19 | logic [31:0][31:0]c;
20 | ```
21 |
22 | ## 组合/位绑定
23 |
24 | ```verilog
25 | {a, 1'b1}
26 | {a, b}
27 | {16{1'b1}}
28 | {a, {16{b}}}
29 | ```
30 |
31 |
--------------------------------------------------------------------------------
/syntax/2oprators/oprator.md:
--------------------------------------------------------------------------------
1 | # 运算符
2 |
3 | ## 基本运算符
4 |
5 | | Operator | Description | Usage (a, b can be constants) | Output Value |
6 | | -------------------- | ------------------------ | ----------------------------- | ------------ |
7 | | & | 与运算 | a[x-1:0] & b[x-1:0] | c[x-1:0] |
8 | | \| | 或运算 | a[x-1:0] \| b[x-1:0] | c[x-1:0] |
9 | | ~ | 非运算 | ~a[x-1:0] | c[x-1:0] |
10 | | ^ | 异或运算 | a[x-1:0] ^ b[x-1 : 0] | c[x-1:0] |
11 | | ! | | !a[x-1:0] | ? |
12 | | +, - | 加运算,减运算 | a[x-1:0] + b[x-1:0] | ? |
13 | | ? : | 条件运算 | a[0:0] ? b[x-1:0] : c [x-1:0] | d[x-1:0] |
14 | | \>> | 逻辑右移 | a[$2^x-1$:0] >> b[x-1:0] | c[$2^x-1$:0] |
15 | | << | 左移 | a[$2^x-1$:0] << b[x-1:0] | c[$2^x-1$:0] |
16 | | \>>> | 算术右移 | a[$2^x-1$:0] >>> b[x-1:0] | c[$2^x-1$:0] |
17 | | *, /, % | 乘运算,除运算,取模运算 | 少用 | ? |
18 | | <, <=, !=, >, >=, == | 比较运算 | a[x-1:0] op b[x-1:0] | ? |
19 |
20 | ## 缩位运算符
21 |
22 | | Operator | Description | Usage | Output Value |
23 | | -------- | ------------------ | ---------- | ------------ |
24 | | & | 向量所有位相与运算 | &a[x-1:0] | b[0:0] |
25 | | \| | 向量所有位相或运算 | \|a[x-1:0] | b[0:0] |
26 |
27 | 运算符不能视作向量:
28 |
29 | ```
30 | (a + b)[3:0] is illegal!
31 | a[3:0]
32 | ```
33 |
34 | # 赋值语句
35 |
36 | `variable = expression`
37 |
38 | * 等号左边的variable,可以是单个变量,也可以是`{a, b}`, 但不能有常量或运算符
39 | * 等号右边的expression,可以是单个变量或常量,也可以是`{a + b, 1'b1}`,要注意位数
40 | * 等号左右两边位数不同,会发生什么?
41 |
42 | ```verilog
43 | a = 1;
44 | b = a;
45 | c = {a, b, a + b};
46 | {d, e} = {{16{a}}, b, c};
47 | ```
48 |
49 | # 电路语句(To be continued)
50 |
51 | **电路是由电路语句构成的,上述例子都不是电路语句!**
--------------------------------------------------------------------------------
/syntax/3assign/assign.md:
--------------------------------------------------------------------------------
1 | # 电路语句(一):assign
2 |
3 |
4 |
5 | 电路代码包括以下几部分:
6 |
7 | * 二进制信号声明
8 | * 数字元件
9 | * 电路连接
10 |
11 |
12 |
13 | `assign`语句是一种电路语句,可以描述一部分电路,这些电路的的作用是运算符的功能。
14 |
15 | assign语句的基本形式为:`assign 赋值语句;`
16 |
17 | ```verilog
18 | logic [31:0] a, b, c;
19 | assign c = a & b;
20 | ```
21 |
22 | 适用于简单组合电路;已有电路图(仅包含基本元件)或逻辑表达式的组合电路。
--------------------------------------------------------------------------------
/syntax/4module/module.md:
--------------------------------------------------------------------------------
1 | # 电路语句(二):元件例化语句
2 |
3 | 需求:
4 |
5 | * 层次化设计、功能区分
6 |
7 | * 代码复用
8 | * 黑盒
9 |
10 | ## 1 模块声明
11 |
12 | ```verilog
13 | module adder (
14 | // inputs and outputs declaration
15 | input logic [3:0] a, b,
16 | output logic [3:0] c
17 | );
18 | // circuit code
19 | assign c = a + b;
20 | endmodule
21 | ```
22 |
23 | ## 2 电路语句:元件例化
24 |
25 | ```verilog
26 | logic [3:0] b, c;
27 | //logic [4:0] c;
28 | adder adder_inst0(.a(4'b0010), .*); // assign c = b + 4'b0010;
29 | // modulename instancename(.portname1(value1), .portname2, .*);
30 | // adder adder_inst1(.a[0]());
31 | ```
32 |
33 |
--------------------------------------------------------------------------------
/syntax/5always_comb/always_comb.md:
--------------------------------------------------------------------------------
1 | # 电路语句(三):always_comb
2 |
3 | always_comb用于描述复杂电路
4 |
5 | ```verilog
6 | always_comb begin
7 | a = 1'b1;
8 | b = a;
9 | a = 1'b0;
10 | c = a;
11 | end
12 | ```
13 |
14 | always_comb内部每条语句都是赋值语句。不能出现电路语句。
15 |
16 | always_comb内部描述电路行为。
17 |
18 | always_comb有以下性质:
19 |
20 | * 内部覆盖性
21 |
22 | * 对外原子性
23 |
24 | ```verilog
25 | assign a = b;
26 | always_comb begin
27 | b = 1'b1;
28 | c = a; // c = b
29 | b = 1'b0;
30 | end
31 | ```
32 |
33 | * 阻塞赋值
34 |
35 | always_comb内部允许if,case等控制语句。
--------------------------------------------------------------------------------
/syntax/5always_comb/case.md:
--------------------------------------------------------------------------------
1 | # always_comb中的控制语句:case
2 |
3 | case语句常用于描述选择器和译码器。
4 |
5 | ## `unique case`
6 |
7 | ```verilog
8 | always_comb begin
9 | b = 1'b0;
10 | unique case (a[3:0])
11 | 4'd1: begin
12 | b = 1'b1;
13 | end
14 | 4'd0: begin
15 | b = 1'b0;
16 | end
17 | default: begin
18 |
19 | end
20 | endcase
21 | end
22 | ```
23 |
24 | 如果没列举所有情况且没有`default`,如何?
25 |
26 | ## `priority case`
27 |
28 | ```verilog
29 | always_comb begin
30 | priority case (1'b1)
31 | a[3]: begin
32 |
33 | end
34 | a[2]: begin
35 |
36 | end
37 | default: begin
38 |
39 | end
40 | endcase
41 | end
42 | ```
43 |
44 | ```verilog
45 | always_comb begin
46 | if(a[3]) begin
47 |
48 | end else if(a[2]) begin
49 |
50 | end else if() begin end //...
51 | end
52 | ```
53 |
54 |
--------------------------------------------------------------------------------
/syntax/5always_comb/if_for.md:
--------------------------------------------------------------------------------
1 | # **always_comb中的控制语句:if和for**
2 |
3 | `if`和`for`是`always_comb`中的常用语法。
4 |
5 | ## if
6 |
7 | `if`和`else`用于条件判断。
8 |
9 | ```verilog
10 | always_comb begin
11 | b = 1'b0;
12 | if (a[3]) begin
13 | b = 1'b1;
14 | end else if (a[2]) begin
15 | b = 1'b0;
16 | end else begin
17 |
18 | end
19 | end
20 | ```
21 |
22 | 和`case`要有`default`类似,在`always_comb`中,`if`也应有`else`。
23 |
24 | ## for
25 |
26 | `for`在always_comb中,会被解释为循环展开。
27 |
28 | `for`相关的语句:`break`,`continue`
29 |
30 | ```verilog
31 | logic [15:0]a;
32 | logic [3:0] b;
33 |
34 | always_comb begin
35 | b = '0;
36 | for (int i = 15; i >= 0; i--) begin
37 | if (a[i]) begin
38 | b = i[3:0];
39 | break;
40 | end
41 | end
42 | end
43 | ```
44 |
45 | 循环变量的上下界都应为常数。
46 |
47 | ```verilog
48 | always_comb begin
49 | for (int i = 0 ; i < 16; i ++) begin
50 | if (i >= n) break;
51 | end
52 | end
53 | ```
54 |
55 | `for`和`if`即可表示行为,也可生成电路。
56 |
57 | ```verilog
58 | always_comb begin
59 | for (int i = 0; i < 16; i++) begin
60 | a[i] = b[i] & (c[i] == d[i] | e[i]); // 编译器不认为i是常数,a[i:i+3]非法
61 | end
62 | end
63 |
64 | for (genvar i = 0; i < 16; i++) begin
65 | assign a[i] = b[i] & (c[i] == d[i] | e[i]); // 编译器认为i是常数,a[i:i+3]合法
66 | always_comb begin
67 |
68 | end
69 | end
70 | ```
71 |
72 |
--------------------------------------------------------------------------------
/syntax/6always_ff/always_ff.md:
--------------------------------------------------------------------------------
1 | # 电路语句(四):`always_ff`
2 |
3 | `always_ff`用于描述触发器。
4 |
5 | ```verilog
6 | always_ff @(posedge clk) begin
7 | if (~resetn) begin
8 | q <= '0;
9 | end else if (en) begin
10 | q <= d;
11 | end
12 | end
13 | ```
14 |
15 | `always_ff`里可以描述很复杂的逻辑,但那样写不直观。写代码时,也应该参考理论课上讲的**状态方程**。
16 |
17 | ```verilog
18 | logic [3:0] a, a_nxt;
19 |
20 | always_ff @(posedge clk) begin
21 | if (~resetn) begin
22 | a <= '0;
23 | end else if (en) begin
24 | {a, b} <= {a_nxt, b_nxt};
25 | end
26 | end
27 |
28 | always_comb begin
29 | a_nxt = a;
30 | // ...
31 | unique case(a)
32 | 4'd3: begin
33 | a_nxt = 4'd2;
34 | end
35 | default: begin
36 |
37 | end
38 | endcase
39 | end
40 | ```
41 |
42 |
--------------------------------------------------------------------------------
/syntax/7typedef/typedef.md:
--------------------------------------------------------------------------------
1 | # 高级语法(1):typedef
2 |
3 | 数字电路中,万物皆为二进制。
4 |
5 | 类型同一为`logic`,符合这一规律。但这对程序员,可能不太友好。
6 |
7 | * 需要管理变量的位数
8 | * 同一位数的信号,可能意义完全不同
9 |
10 | 对此,引入自定义类型语法`typedef`。
11 |
12 | ## 1 typedef基础
13 |
14 | 基本格式为:`typedef 已有类型 新类型;`
15 |
16 | ```verilog
17 | typedef logic[31:0] word_t;
18 | typedef logic[5:0] entry_t;
19 | typedef entry_t[31:0] table_t;
20 | ```
21 |
22 | 声明与使用变量的语法:
23 |
24 | ```verilog
25 | word_t a, b;
26 | assign b = {a[15:0], a[31:16]};
27 |
28 | table_t table1; // logic [31:0][5:0]
29 | assign table1[1] = '0;
30 | assign table1[0][1] = '0;
31 | ```
32 |
33 | 用途举例:
34 |
35 | ```verilog
36 | typedef logic[3:0] code_t;
37 | typedef logic[15:0] info_t;
38 |
39 | typedef logic[31:0] paddr_t; // physical address
40 | typedef logic[31:0] vaddr_t; // virtual address
41 | ```
42 |
43 |
44 |
45 | ## 2 struct
46 |
47 | 结构体struct可以描述一组相关的数据。
48 |
49 | 以译码器为例,按以前的写法,可能需要这样写:
50 |
51 | ```verilog
52 | alufunc_t alufunc;
53 | logic mem_read;
54 | logic mem_write;
55 | logic regwrite;
56 |
57 | logic [6:0] control;
58 | assign control = {alufunc, mem_read, mem_write, regwrite};
59 | ```
60 |
61 | 结构体类型相关的语法如下:
62 |
63 | ```verilog
64 | // type definition
65 | typedef struct packed {
66 | logic [3:0] alufunc;
67 | logic mem_read;
68 | logic mem_write;
69 | logic regwrite;
70 | logic [3:0] reg_addr;
71 | } control_t;
72 |
73 | // variable declaration
74 | control_t control;
75 |
76 | logic regwrite;
77 | assign regwrite = control.regwrite;
78 |
79 | // using structs without typedef
80 | struct packed {
81 | logic [3:0] alufunc;
82 | logic mem_read;
83 | logic mem_write;
84 | logic regwrite;
85 | } control_without_typedef;
86 | ```
87 |
88 | struct语法有很多好处,用途也很广。
89 |
90 | ```verilog
91 | typedef struct packed {
92 |
93 | } pipeline_decode_t;
94 |
95 | pipeline_decode_t p, p_nxt;
96 | always_ff @(posedge clk) begin
97 | p <= p_nxt;
98 | end
99 | ```
100 |
101 |
102 |
103 | ## 3 enum
104 |
105 | 枚举的语法形式为:
106 |
107 | ```verilog
108 | typedef enum {
109 | IDEN_1, IDEN_2
110 | } typename;
111 | ```
112 |
113 | 举例:
114 |
115 | ```verilog
116 | typedef enum logic [3:0] {
117 | ALU_ADD, ALU_AND, ALU_SUB
118 | } alufunc_t;
119 |
120 | alufunc_t alufunc;
121 |
122 | enum logic [3:0] {
123 | ALU_ADD, ALU_AND, ALU_SUB
124 | } alufunc_without_typedef;
125 | ```
126 |
127 | enum语法常用于编码(包括状态机的编码)。
128 |
129 | enum类型的变量,在Vivado仿真里会显示枚举项。(参考我的视频《编码和译码的应用》)
130 |
131 | 枚举项被视为常量,各枚举类型的枚举项名字不能冲突。
132 |
133 | enum类型的变量,赋值时只能用枚举项。
134 |
135 | ```verilog
136 | typedef enum logic [1:0] {
137 | STATE_0, STATE_1, STATE_2
138 | } state_t;
139 |
140 | state_t state, state_nxt;
141 | always_ff @(posedge clk) begin
142 | if (~resetn) begin
143 | // state <= '0;
144 | state <= state_t'(0);
145 | end else begin
146 | state <= state_nxt;
147 | end
148 | end
149 | ```
150 |
151 | ## 4 union
152 |
153 | 联合类型的语法:
154 |
155 | ```verilog
156 | typedef union packed {
157 | struct packed {
158 | logic zero;
159 | logic [31:0] aluout;
160 | } alu;
161 | struct packed {
162 | logic branch_taken;
163 | logic [31:0] pcbranch;
164 | } branch;
165 | struct packed {
166 | logic [31:0] addr;
167 | logic mem_read;
168 | } memory;
169 | } result_t;
170 |
171 | result_t res;
172 |
173 | logic [31:0] addr, aluout;
174 | assign addr = res.memory.addr; // assign addr = res[32:1]
175 | assign aluout = res.alu.aluout; // assign aluout = res[31:0]
176 |
177 | assign res.alu.aluout = '1;
178 | ```
179 |
180 | 对union类型的变量进行赋值时,要注意多驱动。
--------------------------------------------------------------------------------
/syntax/8parameter/parameter.md:
--------------------------------------------------------------------------------
1 | # 高级语法(2):parameter
2 |
3 | 引入**元件例化**的语法,有很多好处。
4 |
5 | 然而,已有的模块设计语法,缺乏flexibility。
6 |
7 | 适用同一算法`int`和`long long`的加法器,需要写两个。
8 |
9 | 为了使模块代码具有更高的复用性,引入参数`parameter`。
10 |
11 | ```verilog
12 | module adder #(
13 | parameter int N,
14 | parameter logic [31:0] W = 32'd100000,
15 | parameter type element_t = logic[31:0]
16 | )(
17 | input logic[N-1:0] a, b,
18 | output logic[N-1:0] c
19 | );
20 | assign c = a + b;
21 | endmodule
22 |
23 | module top #(
24 | parameter logic SIM = 1'b0
25 | )(input logic clk, resetn
26 | );
27 |
28 | logic [31:0] a, b, c;
29 |
30 | adder #(.N(32), .element_t(logic [63:0])) adder_inst1(.a, .b, .c);
31 |
32 | logic [15:0] d, e, f;
33 | adder adder_inst2(.a(d), .b(e), .c(f));
34 | endmodule
35 |
36 | module sim();
37 | top #(.SIM(1'b1)) top_inst (.clk, .resetn);
38 | // -DDEBUG
39 | endmodule
40 | ```
41 |
42 | `parameter`也可用于全局常量声明。作为一句语句,它以分号结尾。
43 |
44 | ```verilog
45 | parameter logic[5:0] OP_ADDI = 6'b000010;
46 |
47 | always_comb begin
48 | unique case(op)
49 | OP_ADDI: begin
50 |
51 | end
52 | endcase
53 | end
54 | ```
55 |
56 |
--------------------------------------------------------------------------------
/syntax/9precomplie/预编译.md:
--------------------------------------------------------------------------------
1 | # 高级语法(3):预编译命令
2 |
3 | C语言中的部分预编译命令:
4 |
5 | ```c
6 | #include
7 |
8 | #ifndef __SHARE_H
9 | #define __SHARE_H
10 |
11 | #endif
12 |
13 | #define N 1000000 + 3
14 |
15 | // int a[N];
16 | ```
17 |
18 | 有了预编译命令,就可以用利用头文件,提升代码易读性。
19 |
20 | sv中的预编译命令,和c语言基本一致,用`` ` ``(反引号)开头:
21 |
22 | ```verilog
23 | `include "mips.svh" // sv头文件后缀为svh
24 | // vivado把同一project的所有文件视为同一目录下,故include时无需加目录
25 | `ifndef __SHARE_SVH
26 | `define __SHARE_SVH
27 |
28 | `endif
29 |
30 | `define LINES 0x10
31 |
32 | logic a[`LINES-1:0]; // 使用宏时,也需要以`开头
33 | ```
34 |
35 | 预编译命令可以达到以下效果:
36 |
37 | * 配置一些参数。类似于`parameter`语句。
38 |
39 | * 根据不同的参数,生成不同的电路。不同于mux。
40 |
41 | * `generate if`语句的粒度为电路语句。而```ifdef``之类的预编译命令可以是任意粒度的。
42 |
43 | ```verilog
44 | assign a = b + c
45 | #ifdef D_INSIDE
46 | + d
47 | #endif
48 | ;
49 |
50 | generate if (D_INSIDE) begin
51 | assign a = b + c + d;
52 | end else begin
53 | assign a = b + c;
54 | end
55 | ```
56 |
57 | * 使用头文件。类似于`package`语句。
58 | * 使用宏来封装一些功能。部分情况下可用`function`语句代替。
59 |
60 |
--------------------------------------------------------------------------------