├── .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 | ![image-20200928180047576](C:\Users\JimmyTan\AppData\Roaming\Typora\typora-user-images\image-20200928180047576.png) 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`, 使仿真跑完:![image-20200928181318535](C:\Users\JimmyTan\AppData\Roaming\Typora\typora-user-images\image-20200928181318535.png) 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 | ![image-20200928180047576](C:\Users\JimmyTan\AppData\Roaming\Typora\typora-user-images\image-20200928180047576.png) 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`, 使仿真跑完:![image-20200928181318535](C:\Users\JimmyTan\AppData\Roaming\Typora\typora-user-images\image-20200928181318535.png) 69 | 70 | 当你修改过源文件后,点击`relaunch simulation`重新发起仿真。 71 | 72 | ![image-20201012092759280](C:\Users\JimmyTan\AppData\Roaming\Typora\typora-user-images\image-20201012092759280.png) 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 | ![image-20201104165010510](C:\Users\JimmyTan\AppData\Roaming\Typora\typora-user-images\image-20201104165010510.png) -------------------------------------------------------------------------------- /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 | ![ff](asset\ff.jpg) 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 | ![ff_reset](D:\2020Autumn\DigitalLogic\DigitalLogic-Autumn2020\experiment\lab5\asset\ff_reset.jpg) 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 | circuit 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 | image-20201203223159232 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 | ![image-20201129222132265](C:\Users\JimmyTan\AppData\Roaming\Typora\typora-user-images\image-20201129222132265.png) 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 | account 46 | 47 | 接下来要点三个`I Agree`,然后点`Next`,如图: 48 | 49 | agree 50 | 51 | 接下来选择要安装的edition,我们选择 `Vivado HL Webpack`,然后点 `Next`,如图: 52 | 53 | edition 54 | 55 | 接下来选择安装内容。选择的内容如图所示,然后点 `Next`: 56 | 57 | ![customize](assets/customize.PNG) 58 | 59 | 接下来选择安装路径,然后点 `Next`(注:点这个 `Next`后,下个界面先别点 `install`按钮),如图: 60 | 61 | ![directory](assets/directory.PNG) 62 | 63 | 进入`Installation Summary`界面: 64 | 65 | ![summary](assets/summary.PNG) 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 | ![structure](assets/structure.PNG) 76 | 77 | 随后回到安装程序,点击 `Install`,程序会很快结束下载步骤,进行安装: 78 | 79 | ![progress](assets/progress.PNG) 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 | ![board_files](assets/board_files.PNG) 18 | 19 | ### Step 1:新建项目 20 | 21 | 打开Vivado,点击 `Create Project`,新建一个项目。 22 | 23 | 选择项目路径后,点下一步选择 `RTL Project` ,然后一直点击下一步,直到 `Default Part` 这个界面: 24 | 25 | ![default_part](assets/default_part.PNG) 26 | 27 | 点击上方的 `Boards`,选择 `Nexys4 DDR`,然后一直点下一步,直到项目新建成功。 28 | 29 | ![default_board](assets/default_board.PNG) 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 | ![circuit](assets/circuit.jpg) 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 | ![1](1.jpg) 49 | 50 | ## 模块、元件例化 51 | 52 | `module`是电路设计中很重要的概念,可封装逻辑细节,只暴露接口。 53 | 54 | * 在多人协作中,每人写一些模块,可确保每个人写的逻辑独立,也方便拼接。 55 | * 想实现某个功能但写不出电路时,可以先放一个元件,把接口定好,等宏观的电路结构搭好后再实现细节。 56 | 57 | 模块和元件类似于c++中的类与对象的概念。 58 | 59 | 元件例化用于描述电路图中的抽象逻辑部件,常用于描述已有电路图。 60 | 61 | 写法举例: 62 | 63 | ![2](2.jpg) 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 | ![](./img/decoder) 12 | 13 | 若输入的二进制码对应的十进制数为i,则输出数的第i位为1,其余位为0。(高电平有效) 14 | 15 | 16 | 17 | ![](./img/encoder) 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 | --------------------------------------------------------------------------------