├── .gitignore ├── PROJECT.md ├── README.md ├── report.pdf ├── thinpad_top.srcs ├── constrs_1 │ └── new │ │ └── thinpad_top.xdc ├── sim_1 │ ├── imports │ │ ├── CFImemory64Mb_bottom.mem │ │ └── CFImemory64Mb_top.mem │ └── new │ │ ├── 28F640P30.v │ │ ├── clock.v │ │ ├── cpld_model.v │ │ ├── flag_sync_cpld.v │ │ ├── include │ │ ├── BankLib.h │ │ ├── CUIcommandData.h │ │ ├── TimingData.h │ │ ├── UserData.h │ │ ├── data.h │ │ └── def.h │ │ ├── sram_model.v │ │ ├── tb.sv │ │ ├── tb │ │ ├── lab2_tb.sv │ │ ├── lab3_tb.sv │ │ ├── lab4_tb.sv │ │ └── lab5_tb.sv │ │ └── uart_model.sv └── sources_1 │ ├── ip │ └── pll_example │ │ ├── pll_example.xci │ │ └── pll_example.xml │ └── new │ ├── SEG7_LUT.v │ ├── async.v │ ├── common │ ├── arbiter │ │ ├── arbiter.v │ │ ├── priority_encoder.v │ │ ├── wb_arbiter_2.v │ │ └── wb_arbiter_4.v │ ├── lfsr.v │ ├── lfsr_prng.sv │ ├── trigger.sv │ └── wb_mux_4.v │ ├── lab2 │ ├── counter.sv │ └── lab2_top.sv │ ├── lab3 │ └── lab3_top.sv │ ├── lab4 │ ├── lab4_top.sv │ ├── sram_controller.sv │ ├── sram_tester.sv │ └── wb_mux_2.v │ ├── lab5 │ ├── lab5_master.sv │ ├── lab5_top.sv │ ├── uart_controller.sv │ └── wb_mux_3.v │ ├── lab6 │ ├── alu_32.sv │ ├── btb.sv │ ├── csr_trap.sv │ ├── defines.sv │ ├── exe.sv │ ├── hazard.sv │ ├── inst_decode.sv │ ├── inst_fetch.sv │ ├── instr_cache.sv │ ├── mem_controller.sv │ ├── memory.sv │ ├── mmu.sv │ ├── mtime.sv │ └── reg_file_32.sv │ ├── thinpad_top.sv │ ├── vga.v │ ├── wb_arbiter.py │ └── wb_mux.py └── thinpad_top.xpr /.gitignore: -------------------------------------------------------------------------------- 1 | thinpad_top.cache/ 2 | thinpad_top.hw/ 3 | thinpad_top.runs/ 4 | thinpad_top.sim/ 5 | *.jou 6 | *.log 7 | *.str 8 | *.dcp 9 | /.lint/ 10 | /.Xil 11 | /.Xilinx 12 | -------------------------------------------------------------------------------- /PROJECT.md: -------------------------------------------------------------------------------- 1 | Thinpad 模板工程 2 | --------------- 3 | 4 | 工程包含示例代码和所有引脚约束,可以直接编译。 5 | 6 | 代码中包含中文注释,编码为utf-8,在Windows版Vivado下可能出现乱码问题。 7 | 请用别的代码编辑器打开文件,并将编码改为GBK。 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RISC-V CPU 2 | 3 | 清华大学《计算机组成原理》2022 秋大实验——五级流水线 RISC-V CPU. 4 | 5 | Course Project of *Computer Organization & Design*, 2022 Fall, THU. 6 | 7 | 实验由 [蒋昊迪](https://github.com/jhdjames37/) 和 [邢竞择](https://github.com/Simphoni) 完成。 8 | 9 | This project is made by [Jiang Haodi](https://github.com/jhdjames37/) and [Xing Jingze](https://github.com/Simphoni). 10 | 11 | ## 实现功能 12 | 13 | + RV32I 的基本指令 14 | + 基本的中断异常机制及 M,S,U 态切换 15 | + 页表及虚拟地址转换 16 | + 优化机制:分支预测、指令缓存、TLB 17 | + 能够运行三个版本的监控程序以及 uCore 操作系统 18 | 19 | 详情可参阅[实验报告](/report.pdf) 20 | -------------------------------------------------------------------------------- /report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhdjames37/RISC-V-CPU-simple/541eab50bffc770bc94741ccac8b4ec16b391806/report.pdf -------------------------------------------------------------------------------- /thinpad_top.srcs/sim_1/imports/CFImemory64Mb_bottom.mem: -------------------------------------------------------------------------------- 1 | // _/ _/_/ 2 | // _/_/ _/_/_/ 3 | // _/_/_/_/ _/_/_/ 4 | // _/_/_/_/_/ _/_/_/ ____________________________________________ 5 | // _/_/_/_/_/ _/_/_/ / / 6 | // _/_/_/_/_/ _/_/_/ / 28F640P30 / 7 | // _/_/_/_/_/ _/_/_/ / / 8 | // _/_/_/_/_/_/ _/_/_/ / 128Mbit / 9 | // _/_/_/_/_/_/ _/_/_/ / Single bit per Cell / 10 | // _/_/_/ _/_/_/ _/_/_/ / / 11 | // _/_/_/ _/_/_/ _/_/_/ / Verilog Behavioral Model / 12 | // _/_/_/ _/_/_/ _/_/_/ / Version 1.1 / 13 | // _/_/_/ _/_/_/ _/_/_/ / / 14 | // _/_/_/ _/_/_/_/_/_/ / Copyright (c) 2010 Numonyx B.V. / 15 | // _/_/_/ _/_/_/_/_/ /___________________________________________/ 16 | // _/_/_/ _/_/_/_/ 17 | // _/_/ _/_/_/ 18 | // 19 | // 20 | // NUMONYX 21 | @00010 22 | 23 | 0101_0001 24 | 25 | 0101_0010 26 | 27 | 0101_1001 28 | 29 | @00013 30 | 31 | 0000_0001 32 | 33 | 0000_0000 34 | 35 | @00015 36 | 37 | 0000_1010 38 | 39 | 0000_0001 40 | 41 | @00017 42 | 43 | 0000_0000 44 | 45 | 0000_0000 46 | 47 | @00019 48 | 49 | 0000_0000 50 | 51 | 52 | @0001A 53 | 54 | 0000_0000 55 | 56 | 57 | @0001B 58 | 0001_0111 59 | 60 | @0001C 61 | 0010_0000 62 | 63 | @0001D 64 | 65 | 1000_0101 66 | 67 | @0001E 68 | 1001_0101 69 | 70 | @0001F 71 | 0000_0110 72 | 73 | @00020 74 | 75 | 0000_1000 76 | 77 | @00021 78 | 0000_1001 79 | 80 | @00022 81 | 0000_0000 82 | 83 | @00023 84 | 0000_0010 85 | 86 | 87 | 88 | @00024 89 | 0000_0011 90 | 91 | @00025 92 | 0000_0011 93 | 94 | @00026 95 | 0000_0000 96 | 97 | @00027 98 | 0001_1000 99 | 100 | @00028 101 | 0000_0001 102 | 103 | @00029 104 | 0000_0000 105 | 106 | @0002A 107 | 0000_1001 108 | 109 | @0002B 110 | 0000_0000 111 | 112 | @0002C 113 | 0000_0010 114 | 115 | @0002D 116 | 0000_0011 //bottom 117 | 118 | @0002E 119 | 0000_0000 120 | 121 | @0002F 122 | 1000_0000 //bottom 123 | 124 | @00030 125 | 0000_0000 //bottom 126 | 127 | @00031 128 | 0011_1110 //bottom 129 | 130 | @00032 131 | 0000_0000 132 | 133 | @00033 134 | 0000_0000 //bottom 135 | 136 | @00034 137 | 0000_0010 //bottom 138 | 139 | @00035 140 | 0000_0000 141 | 142 | @00036 143 | 0000_0000 144 | 145 | @00037 146 | 0000_0000 147 | 148 | @00038 149 | 0000_0000 150 | 151 | @0010A 152 | 0101_0000 153 | 154 | @0010B 155 | 0101_0010 156 | 157 | @0010C 158 | 0010_1001 159 | 160 | @0010D 161 | 0011_0001 162 | 163 | @0010E 164 | 0011_0101 165 | 166 | @0010F 167 | 1110_0110 168 | 169 | @00110 170 | 0000_0001 171 | 172 | @00111 173 | 0000_0000 174 | 175 | @00112 176 | 0000_0000 177 | 178 | @00113 179 | 0000_0001 180 | 181 | @00114 182 | 0000_0011 183 | 184 | @00115 185 | 0000_0000 186 | 187 | @00116 188 | 0001_1000 189 | 190 | @00117 191 | 1001_0000 192 | 193 | @00118 194 | 0000_0010 195 | 196 | @00119 197 | 1000_0000 198 | 199 | @0011A 200 | 0000_0000 201 | 202 | @0011B 203 | 0000_0011 204 | 205 | @0011C 206 | 0000_0011 207 | 208 | @0011D 209 | 1000_1001 210 | 211 | @0011E 212 | 0000_0000 213 | 214 | @0011F 215 | 0000_0000 216 | 217 | @00120 218 | 0000_0000 219 | 220 | @00121 221 | 0000_0000 222 | 223 | @00122 224 | 0000_0000 225 | 226 | @00123 227 | 0000_0000 228 | 229 | @00124 230 | 0001_0000 231 | 232 | @00125 233 | 0000_0000 234 | 235 | @00126 236 | 0000_0100 237 | 238 | @00127 239 | 0000_0100 240 | 241 | @00128 242 | 0000_0100 243 | 244 | @00129 245 | 0000_0001 246 | 247 | @0012A 248 | 0000_0010 249 | 250 | @0012B 251 | 0000_0011 252 | 253 | @0012C 254 | 0000_0111 255 | 256 | @0012D 257 | 0000_0001 258 | 259 | @0012E 260 | 0010_0100 261 | 262 | @0012F 263 | 0000_0000 264 | 265 | @00130 266 | 0000_0001 267 | 268 | @00131 269 | 0000_0000 270 | 271 | @00132 272 | 0001_0001 273 | 274 | @00133 275 | 0000_0000 276 | 277 | @00134 278 | 0000_0000 279 | 280 | @00135 281 | 0000_0010 282 | 283 | @00136 284 | 0000_0011 //bottom 285 | 286 | @00137 287 | 0000_0000 288 | 289 | @00138 290 | 1000_0000 //bottom 291 | 292 | @00139 293 | 0000_0000 //bottom 294 | 295 | @0013A 296 | 0110_0100 297 | 298 | @0013B 299 | 0000_0000 300 | 301 | @0013C 302 | 0000_0010 303 | 304 | @0013D 305 | 0000_0011 306 | 307 | @0013E 308 | 0000_0000 309 | 310 | @0013F 311 | 1000_0000 312 | 313 | @00140 314 | 0000_0000 315 | 316 | @00141 317 | 0000_0000 318 | 319 | @00142 320 | 0000_0000 321 | 322 | @00143 323 | 1000_0000 324 | 325 | @00144 326 | 0111_1110 //bottom 327 | 328 | @00145 329 | 0000_0000 330 | 331 | @00146 332 | 0000_0000 //bottom 333 | 334 | @00147 335 | 0000_0010 //bottom 336 | 337 | @00148 338 | 0110_0100 339 | 340 | @00149 341 | 0000_0000 342 | 343 | @0014A 344 | 0000_0010 345 | 346 | @0014B 347 | 0000_0011 348 | 349 | @0014C 350 | 0000_0000 351 | 352 | @0014D 353 | 1000_0000 354 | 355 | @0014E 356 | 0000_0000 357 | 358 | @0014F 359 | 0000_0000 360 | 361 | @00150 362 | 0000_0000 363 | 364 | @00151 365 | 1000_0000 366 | 367 | @00152 368 | 1111_1111 369 | 370 | @00153 371 | 1111_1111 372 | 373 | @00154 374 | 1111_1111 375 | 376 | @00155 377 | 1111_1111 378 | 379 | @00156 380 | 1111_1111 381 | 382 | 383 | 384 | 385 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sim_1/imports/CFImemory64Mb_top.mem: -------------------------------------------------------------------------------- 1 | // _/ _/_/ 2 | // _/_/ _/_/_/ 3 | // _/_/_/_/ _/_/_/ 4 | // _/_/_/_/_/ _/_/_/ ____________________________________________ 5 | // _/_/_/_/_/ _/_/_/ / / 6 | // _/_/_/_/_/ _/_/_/ / 28F640P30 / 7 | // _/_/_/_/_/ _/_/_/ / / 8 | // _/_/_/_/_/_/ _/_/_/ / 128Mbit / 9 | // _/_/_/_/_/_/ _/_/_/ / Single bit per Cell / 10 | // _/_/_/ _/_/_/ _/_/_/ / / 11 | // _/_/_/ _/_/_/ _/_/_/ / Verilog Behavioral Model / 12 | // _/_/_/ _/_/_/ _/_/_/ / Version 1.1 / 13 | // _/_/_/ _/_/_/ _/_/_/ / / 14 | // _/_/_/ _/_/_/_/_/_/ / Copyright (c) 2010 Numonyx B.V. / 15 | // _/_/_/ _/_/_/_/_/ /___________________________________________/ 16 | // _/_/_/ _/_/_/_/ 17 | // _/_/ _/_/_/ 18 | // 19 | // 20 | // NUMONYX 21 | @00010 22 | 23 | 0101_0001 24 | 25 | 0101_0010 26 | 27 | 0101_1001 28 | 29 | @00013 30 | 31 | 0000_0001 32 | 33 | 0000_0000 34 | 35 | @00015 36 | 37 | 0000_1010 38 | 39 | 0000_0001 40 | 41 | @00017 42 | 43 | 0000_0000 44 | 45 | 0000_0000 46 | 47 | @00019 48 | 49 | 0000_0000 50 | 51 | 52 | @0001A 53 | 54 | 0000_0000 55 | 56 | @0001B 57 | 0001_0111 58 | 59 | @0001C 60 | 0010_0000 61 | 62 | @0001D 63 | 64 | 1000_0101 65 | 66 | @0001E 67 | 1001_0101 68 | 69 | @0001F 70 | 0000_0110 71 | 72 | @00020 73 | 74 | 0000_1000 75 | 76 | @00021 77 | 0000_1001 78 | 79 | @00022 80 | 0000_0000 81 | 82 | @00023 83 | 0000_0010 84 | 85 | 86 | 87 | @00024 88 | 0000_0011 89 | 90 | @00025 91 | 0000_0011 92 | 93 | @00026 94 | 0000_0000 95 | 96 | @00027 97 | 0001_1000 //top 98 | 99 | @00028 100 | 0000_0001 101 | 102 | @00029 103 | 0000_0000 104 | 105 | @0002A 106 | 0000_1001 107 | 108 | @0002B 109 | 0000_0000 110 | 111 | @0002C 112 | 0000_0010 113 | 114 | @0002D 115 | 0111_1110 //top 116 | 117 | @0002E 118 | 0000_0000 119 | 120 | @0002F 121 | 0000_0000 //top 122 | 123 | @00030 124 | 0000_0010 //top 125 | 126 | @00031 127 | 0000_0011 //top 128 | 129 | @00032 130 | 0000_0000 131 | 132 | @00033 133 | 1000_0000 //top 134 | 135 | @00034 136 | 0000_0000 //top 137 | 138 | @00035 139 | 0000_0000 140 | 141 | @00036 142 | 0000_0000 143 | 144 | @00037 145 | 0000_0000 146 | 147 | @00038 148 | 0000_0000 149 | 150 | @0010A 151 | 0101_0000 152 | 153 | @0010B 154 | 0101_0010 155 | 156 | @0010C 157 | 0100_1001 158 | 159 | @0010D 160 | 0011_0001 161 | 162 | @0010E 163 | 0011_0101 164 | 165 | @0010F 166 | 1110_0110 167 | 168 | @00110 169 | 0000_0001 170 | 171 | @00111 172 | 0000_0000 173 | 174 | @00112 175 | 0000_0000 176 | 177 | @00113 178 | 0000_0001 179 | 180 | @00114 181 | 0000_0011 182 | 183 | @00115 184 | 0000_0000 185 | 186 | @00116 187 | 0001_1000 188 | 189 | @00117 190 | 1001_0000 191 | 192 | @00118 193 | 0000_0010 194 | 195 | @00119 196 | 1000_0000 197 | 198 | @0011A 199 | 0000_0000 200 | 201 | @0011B 202 | 0000_0011 203 | 204 | @0011C 205 | 0000_0011 206 | 207 | @0011D 208 | 1000_1001 209 | 210 | @0011E 211 | 0000_0000 212 | 213 | @0011F 214 | 0000_0000 215 | 216 | @00120 217 | 0000_0000 218 | 219 | @00121 220 | 0000_0000 221 | 222 | @00122 223 | 0000_0000 224 | 225 | @00123 226 | 0000_0000 227 | 228 | @00124 229 | 0001_0000 230 | 231 | @00125 232 | 0000_0000 233 | 234 | @00126 235 | 0000_0100 236 | 237 | @00127 238 | 0000_0100 239 | 240 | @00128 241 | 0000_0100 242 | 243 | @00129 244 | 0000_0001 245 | 246 | @0012A 247 | 0000_0010 248 | 249 | @0012B 250 | 0000_0011 251 | 252 | @0012C 253 | 0000_0111 254 | 255 | @0012D 256 | 0000_0001 257 | 258 | @0012E 259 | 0010_0100 260 | 261 | @0012F 262 | 0000_0000 263 | 264 | @00130 265 | 0000_0001 266 | 267 | @00131 268 | 0000_0000 269 | 270 | @00132 271 | 0001_0001 272 | 273 | @00133 274 | 0000_0000 275 | 276 | @00134 277 | 0000_0000 278 | 279 | @00135 280 | 0000_0010 281 | 282 | @00136 283 | 0111_1110 //top 284 | 285 | @00137 286 | 0000_0000 287 | 288 | @00138 289 | 0000_0000 //top 290 | 291 | @00139 292 | 0000_0010 //top 293 | 294 | @0013A 295 | 0110_0100 296 | 297 | @0013B 298 | 0000_0000 299 | 300 | @0013C 301 | 0000_0010 302 | 303 | @0013D 304 | 0000_0011 305 | 306 | @0013E 307 | 0000_0000 308 | 309 | @0013F 310 | 1000_0000 311 | 312 | @00140 313 | 0000_0000 314 | 315 | @00141 316 | 0000_0000 317 | 318 | @00142 319 | 0000_0000 320 | 321 | @00143 322 | 1000_0000 323 | 324 | @00144 325 | 0000_0011 //top 326 | 327 | @00145 328 | 0000_0000 329 | 330 | @00146 331 | 1000_0000 //top 332 | 333 | @00147 334 | 0000_0000 //top 335 | 336 | @00148 337 | 0110_0100 338 | 339 | @00149 340 | 0000_0000 341 | 342 | @0014A 343 | 0000_0010 344 | 345 | @0014B 346 | 0000_0011 347 | 348 | @0014C 349 | 0000_0000 350 | 351 | @0014D 352 | 1000_0000 353 | 354 | @0014E 355 | 0000_0000 356 | 357 | @0014F 358 | 0000_0000 359 | 360 | @00150 361 | 0000_0000 362 | 363 | @00151 364 | 1000_0000 365 | 366 | @00152 367 | 1111_1111 368 | 369 | @00153 370 | 1111_1111 371 | 372 | @00154 373 | 1111_1111 374 | 375 | @00155 376 | 1111_1111 377 | 378 | @00156 379 | 1111_1111 380 | 381 | 382 | 383 | 384 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sim_1/new/clock.v: -------------------------------------------------------------------------------- 1 | `timescale 1ps / 1ps 2 | 3 | module clock ( 4 | output reg clk_50M, 5 | output reg clk_11M0592 6 | ); 7 | 8 | initial begin 9 | clk_50M = 0; 10 | clk_11M0592 = 0; 11 | end 12 | 13 | always #(90422/2) clk_11M0592 = ~clk_11M0592; 14 | always #(20000/2) clk_50M = ~clk_50M; 15 | 16 | endmodule 17 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sim_1/new/cpld_model.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module cpld_model( 3 | input wire clk_uart, //内部串口时钟 4 | input wire uart_rdn, //读串口信号,低有效 5 | input wire uart_wrn, //写串口信号,低有效 6 | output reg uart_dataready, //串口数据准备好 7 | output reg uart_tbre, //发送数据标志 8 | output reg uart_tsre, //数据发送完毕标志 9 | inout wire [7:0]data 10 | ); 11 | reg bus_analyze_clk = 0; 12 | reg clk_out2_rst_n = 0, bus_analyze_clk_rst_n = 0; 13 | wire clk_out2; 14 | 15 | reg [7:0] TxD_data,TxD_data0,TxD_data1; 16 | reg [2:0] cpld_emu_wrn_sync; 17 | reg [2:0] cpld_emu_rdn_sync; 18 | reg [7:0] uart_rx_data; 19 | wire uart_rx_flag; 20 | reg wrn_rise; 21 | 22 | assign data = uart_rdn ? 8'bz : uart_rx_data; 23 | assign #3 clk_out2 = clk_uart; 24 | 25 | initial begin 26 | uart_tsre = 1; 27 | uart_tbre = 1; 28 | uart_dataready = 0; 29 | repeat(2) @(negedge clk_out2); 30 | clk_out2_rst_n = 1; 31 | @(negedge bus_analyze_clk); 32 | bus_analyze_clk_rst_n = 1; 33 | end 34 | 35 | always #2 bus_analyze_clk = ~bus_analyze_clk; 36 | 37 | always @(posedge bus_analyze_clk) begin : proc_Tx 38 | TxD_data0 <= data[7:0]; 39 | TxD_data1 <= TxD_data0; 40 | 41 | cpld_emu_rdn_sync <= {cpld_emu_rdn_sync[1:0],uart_rdn}; 42 | cpld_emu_wrn_sync <= {cpld_emu_wrn_sync[1:0],uart_wrn}; 43 | 44 | if(~cpld_emu_wrn_sync[1] & cpld_emu_wrn_sync[2]) 45 | TxD_data <= TxD_data1; 46 | wrn_rise <= cpld_emu_wrn_sync[1] & ~cpld_emu_wrn_sync[2]; 47 | 48 | if(~cpld_emu_rdn_sync[1] & cpld_emu_rdn_sync[2]) //rdn_fall 49 | uart_dataready <= 1'b0; 50 | else if(uart_rx_flag) 51 | uart_dataready <= 1'b1; 52 | end 53 | 54 | reg [7:0] TxD_data_sync; 55 | wire tx_en; 56 | reg rx_ack = 0; 57 | 58 | always @(posedge clk_out2) begin 59 | TxD_data_sync <= TxD_data; 60 | end 61 | 62 | always @(posedge clk_out2 or negedge uart_wrn) begin : proc_tbre 63 | if(~uart_wrn) begin 64 | uart_tbre <= 0; 65 | end else if(!uart_tsre) begin 66 | uart_tbre <= 1; 67 | end 68 | end 69 | 70 | flag_sync_cpld tx_flag( 71 | .clkA (bus_analyze_clk), 72 | .clkB (clk_out2), 73 | .FlagIn_clkA (wrn_rise), 74 | .FlagOut_clkB(tx_en), 75 | .a_rst_n (bus_analyze_clk_rst_n), 76 | .b_rst_n (clk_out2_rst_n) 77 | ); 78 | 79 | flag_sync_cpld rx_flag( 80 | .clkA (clk_out2), 81 | .clkB (bus_analyze_clk), 82 | .FlagIn_clkA (rx_ack), 83 | .FlagOut_clkB(uart_rx_flag), 84 | .a_rst_n (bus_analyze_clk_rst_n), 85 | .b_rst_n (clk_out2_rst_n) 86 | ); 87 | 88 | always begin 89 | wait(tx_en == 1); 90 | repeat(2) 91 | @(posedge clk_out2); 92 | uart_tsre = 0; 93 | #10000 // 实际串口发送时间更长,为了加快仿真,等待时间较短 94 | $display("send: 0x%02x", TxD_data_sync); 95 | uart_tsre = 1; 96 | end 97 | 98 | task pc_send_byte; 99 | input [7:0] arg; 100 | begin 101 | uart_rx_data = arg; 102 | @(negedge clk_out2); 103 | rx_ack = 1; 104 | @(negedge clk_out2); 105 | rx_ack = 0; 106 | end 107 | endtask 108 | endmodule -------------------------------------------------------------------------------- /thinpad_top.srcs/sim_1/new/flag_sync_cpld.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ps 2 | module flag_sync_cpld(/*autoport*/ 3 | //output 4 | FlagOut_clkB, 5 | //input 6 | a_rst_n, 7 | b_rst_n, 8 | clkA, 9 | FlagIn_clkA, 10 | clkB); 11 | 12 | input wire a_rst_n; 13 | input wire b_rst_n; 14 | input wire clkA; 15 | input wire FlagIn_clkA; 16 | input wire clkB; 17 | output wire FlagOut_clkB; 18 | 19 | // this changes level when the FlagIn_clkA is seen in clkA 20 | reg FlagToggle_clkA; 21 | always @(posedge clkA or negedge a_rst_n) 22 | begin 23 | if(!a_rst_n) 24 | FlagToggle_clkA <= 1'b0; 25 | else 26 | FlagToggle_clkA <= FlagToggle_clkA ^ FlagIn_clkA; 27 | end 28 | 29 | // which can then be sync-ed to clkB 30 | reg [2:0] SyncA_clkB; 31 | always @(posedge clkB or negedge b_rst_n) 32 | begin 33 | if(!b_rst_n) 34 | SyncA_clkB <= 3'b0; 35 | else 36 | SyncA_clkB <= {SyncA_clkB[1:0], FlagToggle_clkA}; 37 | end 38 | 39 | // and recreate the flag in clkB 40 | assign FlagOut_clkB = (SyncA_clkB[2] ^ SyncA_clkB[1]); 41 | /* 42 | 43 | always #20 clkA = ~clkA; 44 | always #3 clkB = ~clkB; 45 | initial begin 46 | clkB=0; 47 | clkA=0; 48 | FlagToggle_clkA=0; 49 | SyncA_clkB=0; 50 | FlagIn_clkA=0; 51 | @(negedge clkA); 52 | FlagIn_clkA=1; 53 | @(negedge clkA); 54 | FlagIn_clkA=0; 55 | 56 | repeat(5) 57 | @(negedge clkA); 58 | FlagIn_clkA=1; 59 | @(negedge clkA); 60 | FlagIn_clkA=0; 61 | end 62 | 63 | */ 64 | 65 | endmodule 66 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sim_1/new/include/CUIcommandData.h: -------------------------------------------------------------------------------- 1 | // _/ _/_/ 2 | // _/_/ _/_/_/ 3 | // _/_/_/_/ _/_/_/ 4 | // _/_/_/_/_/ _/_/_/ ____________________________________________ 5 | // _/_/_/_/_/ _/_/_/ / / 6 | // _/_/_/_/_/ _/_/_/ / 28F640P30 / 7 | // _/_/_/_/_/ _/_/_/ / / 8 | // _/_/_/_/_/_/ _/_/_/ / 128Mbit / 9 | // _/_/_/_/_/_/ _/_/_/ / Single bit per Cell / 10 | // _/_/_/ _/_/_/ _/_/_/ / / 11 | // _/_/_/ _/_/_/ _/_/_/ / Verilog Behavioral Model / 12 | // _/_/_/ _/_/_/ _/_/_/ / Version 1.1 / 13 | // _/_/_/ _/_/_/ _/_/_/ / / 14 | // _/_/_/ _/_/_/_/_/_/ / Copyright (c) 2010 Numonyx B.V. / 15 | // _/_/_/ _/_/_/_/_/ /___________________________________________/ 16 | // _/_/_/ _/_/_/_/ 17 | // _/_/ _/_/_/ 18 | // 19 | // 20 | // NUMONYX 21 | 22 | // ********************** 23 | // 24 | // COMMAND USER INTERFACE 25 | // 26 | // ********************** 27 | 28 | // Read Commands 29 | 30 | `define RD_cmd 8'hFF // Read Memory Array 31 | `define RSR_cmd 8'h70 // Read Status Register 32 | `define RSIG_cmd 8'h90 // Read Electronic Signature 33 | `define RCFI_cmd 8'h98 // Read CFI 34 | 35 | 36 | // Program/Erase Commands 37 | 38 | `define PG_cmd 8'h40 // Program 39 | `define PES_cmd 8'hB0 // Program/Erase Suspend 40 | `define PER_cmd 8'hD0 // Program/Erase Resume 41 | `define BLKEE_cmd 8'h20 // Block Erase 42 | `define BLKEEconfirm_cmd 8'hD0 // Block Erase Confirm 43 | `define CLRSR_cmd 8'h50 // Clear Status Register 44 | `define PRREG_cmd 8'hC0 // Protection Register Program //verificare se va bene x OTP register program setup 45 | 46 | 47 | // Protect Commands 48 | 49 | `define BL_cmd 8'h60 // Block Lock //setup?? 50 | `define BUL_cmd 8'h60 // Block UnLock 51 | `define BLD_cmd 8'h60 // Block lock-down 52 | `define BLDconfirm_cmd 8'h2F // Block Lock-down confirm 53 | `define BLconfirm_cmd 8'h01 // Block Lock Confirm 54 | `define BULconfirm_cmd 8'hD0 // Block unLock Confirm 55 | 56 | 57 | // Additional Features Commands 58 | 59 | `define PB_cmd 8'hE8 // Program Buffer 60 | `define PBcfm_cmd 8'hD0 // Close Sequence of Program Buffer Command 61 | 62 | 63 | // Configuration Register 64 | 65 | `define SCR_cmd 8'h60 // Set Configuration Register 66 | `define SCRconfirm_cmd 8'h03 // Set Configuration Register confirm 67 | 68 | // Additional Features Commands //aggiunto 69 | `define BLNKCHK_cmd 8'hBC // Blank Check Command 70 | `define BLNKCHKconfirm_cmd 8'hD0 // Blank Check Confirm 71 | 72 | 73 | // Factory Program Commands 74 | `define BuffEnhProgram_cmd 8'h80 // Enhanced Setup Command 75 | `define BuffEnhProgramCfrm_cmd 8'hD0 // Enhanced Setup confirm 76 | 77 | `define EnhSetup_cmd 8'h80 // Enhanced Setup Command 78 | `define EnhSetup_cfrm 8'hD0 // Enhanced Setup confirm 79 | 80 | 81 | // CUI Status 82 | 83 | // Read Bus Status Operation 84 | 85 | `define ReadArray_bus 2'b00 // Read Memory Array 86 | `define ReadSignature_bus 2'b01 // Read Electronic Signature 87 | `define ReadStatusReg_bus 2'b10 // Read Status Register 88 | `define ReadCFI_bus 2'b11 // Read CFI 89 | 90 | 91 | // Program/Erase Controller Status 92 | 93 | `define Free_pes 0 // No Operation 94 | `define Program_pes 1 // Programming 95 | `define BlockErase_pes 2 // Erasing Block 96 | `define ChipErase_pes 3 // Chip Erasing 97 | `define BlockEraseSuspend_pes 4 // Block Erase Suspend 98 | `define ProgramEraseSuspend_pes 5 // Program/Erase Resume 99 | `define ProgramEraseWait_pes 6 // Program/Erase Wait 100 | `define Reset_pes 10 // Reset status 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sim_1/new/include/UserData.h: -------------------------------------------------------------------------------- 1 | // _/ _/_/ 2 | // _/_/ _/_/_/ 3 | // _/_/_/_/ _/_/_/ 4 | // _/_/_/_/_/ _/_/_/ ____________________________________________ 5 | // _/_/_/_/_/ _/_/_/ / / 6 | // _/_/_/_/_/ _/_/_/ / 28F640P30 / 7 | // _/_/_/_/_/ _/_/_/ / / 8 | // _/_/_/_/_/_/ _/_/_/ / 128Mbit / 9 | // _/_/_/_/_/_/ _/_/_/ / Single bit per Cell / 10 | // _/_/_/ _/_/_/ _/_/_/ / / 11 | // _/_/_/ _/_/_/ _/_/_/ / Verilog Behavioral Model / 12 | // _/_/_/ _/_/_/ _/_/_/ / Version 1.1 / 13 | // _/_/_/ _/_/_/ _/_/_/ / / 14 | // _/_/_/ _/_/_/_/_/_/ / Copyright (c) 2010 Numonyx B.V. / 15 | // _/_/_/ _/_/_/_/_/ /___________________________________________/ 16 | // _/_/_/ _/_/_/_/ 17 | // _/_/ _/_/_/ 18 | // 19 | // 20 | // NUMONYX 21 | 22 | // ************************************ 23 | // 24 | // User Data definition file : 25 | // 26 | // here are defined all parameters 27 | // that the user can change 28 | // 29 | // ************************************ 30 | 31 | //`define x128P30T // Select the device. Possible value are: x128P30B, x128P30T 32 | `define x64P30T // x64P30B, x64P30T 33 | 34 | 35 | //!`define organization "top" // top or bottom 36 | `define BLOCKPROTECT "on" // if on the blocks are locked at power-up 37 | `define TimingChecks "on" // on for checking timing constraints 38 | `define t_access 65 // Access Time 65 ns, 75 ns 39 | `define FILENAME_mem "flash_content.mem" // Memory File Name 40 | 41 | 42 | 43 | 44 | `ifdef x128P30B 45 | `define organization "bottom" 46 | `elsif x128P30T 47 | `define organization "top" // top, bottom 48 | `elsif x64P30B 49 | `define organization "bottom" 50 | `elsif x64P30T 51 | `define organization "top" 52 | `else 53 | `define organization "bottom" 54 | `endif 55 | 56 | 57 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sim_1/new/include/data.h: -------------------------------------------------------------------------------- 1 | // _/ _/_/ 2 | // _/_/ _/_/_/ 3 | // _/_/_/_/ _/_/_/ 4 | // _/_/_/_/_/ _/_/_/ ____________________________________________ 5 | // _/_/_/_/_/ _/_/_/ / / 6 | // _/_/_/_/_/ _/_/_/ / 28F640P30 / 7 | // _/_/_/_/_/ _/_/_/ / / 8 | // _/_/_/_/_/_/ _/_/_/ / 128Mbit / 9 | // _/_/_/_/_/_/ _/_/_/ / Single bit per Cell / 10 | // _/_/_/ _/_/_/ _/_/_/ / / 11 | // _/_/_/ _/_/_/ _/_/_/ / Verilog Behavioral Model / 12 | // _/_/_/ _/_/_/ _/_/_/ / Version 1.1 / 13 | // _/_/_/ _/_/_/ _/_/_/ / / 14 | // _/_/_/ _/_/_/_/_/_/ / Copyright (c) 2010 Numonyx B.V. / 15 | // _/_/_/ _/_/_/_/_/ /___________________________________________/ 16 | // _/_/_/ _/_/_/_/ 17 | // _/_/ _/_/_/ 18 | // 19 | // 20 | // NUMONYX 21 | `include "UserData.h" 22 | // ****** 23 | // 24 | // data.h 25 | // 26 | // ****** 27 | 28 | // ******************** 29 | // 30 | // Main Characteristics 31 | // 32 | // ******************** 33 | 34 | `ifdef x128P30B 35 | 36 | `define ADDRBUS_dim 23 // - Address Bus pin numbers 37 | 38 | `elsif x128P30T 39 | 40 | `define ADDRBUS_dim 23 41 | 42 | `else 43 | 44 | `define ADDRBUS_dim 22 45 | 46 | `endif 47 | 48 | `define DATABUS_dim 16 // - Data Bus pin numbers 49 | `define MEMORY_dim 1 << `ADDRBUS_dim // - Memory Dimension 50 | `define LAST_ADDR (`MEMORY_dim) - 1 // - Last Address 51 | 52 | // ******************** 53 | // 54 | // Address & Data range 55 | // 56 | // ******************** 57 | 58 | `define ADDRBUS_range `ADDRBUS_dim - 1 : 0 59 | `define DATABUS_range `DATABUS_dim - 1 : 0 60 | 61 | // ***************** 62 | // 63 | // Init Memory Files 64 | // 65 | // ***************** 66 | 67 | `define CFI_dim 9'h157 68 | `define CFI_range `CFI_dim - 1:9'h10 69 | // ******************* 70 | // 71 | // Protection Register 72 | // 73 | // ******************* 74 | 75 | 76 | `define REG_addrStart 16'h0 77 | `define REG_addrEnd 16'h15 78 | 79 | `define REGSTART_addr 9'h80 // Protection Register Start Address 80 | `define REGEND_addr 9'h109 // Protection Register End Address 81 | `define REG_dim `REGEND_addr - `REGSTART_addr + 1 82 | 83 | `define REG_addrRange `REG_addrEnd:`REG_addrStart 84 | 85 | `define REG_addrbitStart 8'd0 86 | `define REG_addrbitEnd 8'd8 87 | `define REG_addrbitRange `REG_addrbitEnd:`REG_addrbitStart 88 | 89 | `define PROTECTREGLOCK_addr 9'h80 // Protection Register Lock Address 90 | 91 | 92 | `define UDNREGSTART_addr 9'h81 93 | `define UDNREGEND_addr 9'h84 94 | `define UDNprotect_bit 8'hFE 95 | 96 | `define UPREGSTART_addr 9'h85 97 | `define UPREGEND_addr 9'h88 98 | `define UPprotect_bit 8'hFD // serve ad indentificare quale bit deve essere 0 nel lock regi 99 | `define PRL_default 16'h0002 // Protection Register Lock default definito anche in def 100 | 101 | // ***************************** 102 | // 103 | // Extended User OTP 104 | // 105 | // ***************************** 106 | 107 | `define ExtREG_dim 8'h20 108 | 109 | 110 | `define ExtREG_regiondim 8'h8 111 | `define ExtREGSTART_regionaddr 9'h8A // Ext Protection Register Start Address 112 | `define ExtREGEND_regionaddr 9'h109 // Ext Protection Register End Address 113 | 114 | `define ExtPROTECTREGLOCK_addr 9'h89 // Ext Protection Register Lock Address 115 | `define ExtPRL_default 16'hFFFF // Protection Register Lock default 116 | 117 | 118 | 119 | // *********************** 120 | // 121 | // Voltage Characteristics 122 | // 123 | // *********************** 124 | `define Voltage_range 35:0 125 | `define VDDmin 36'd02300 126 | `define VDDmax 36'd03600 127 | `define VDDQmin 36'd02300 128 | `define VDDQmax 36'd03600 129 | `define VPPmin 36'd00900 130 | `define VPPmax 36'd03600 131 | `define VPPHmin 36'd08500 132 | `define VPPHmax 36'd09500 133 | 134 | // ********************** 135 | // 136 | // Configuration Register 137 | // 138 | // ********************** 139 | 140 | `define ConfigurationReg_dim 16 141 | `define ConfigReg_default 16'hBBCF 142 | 143 | // ******************** 144 | // 145 | // Electronic Signature 146 | // 147 | // ******************** 148 | 149 | `define ManufacturerCode 8'h89 150 | 151 | `ifdef x128P30B 152 | 153 | `define TopDeviceCode 8'h18 154 | `define BottomDeviceCode 8'h1B 155 | 156 | `elsif x128P30T 157 | `define TopDeviceCode 8'h18 158 | `define BottomDeviceCode 8'h1B 159 | 160 | `else 161 | `define TopDeviceCode 8'h17 162 | `define BottomDeviceCode 8'h1A 163 | 164 | `endif 165 | 166 | 167 | 168 | `define SignAddress_dim 9 169 | `define SignAddress_range `SignAddress_dim - 1 : 0 170 | 171 | 172 | 173 | // ********************* 174 | // 175 | // Write Buffer constant 176 | // 177 | // ********************* 178 | 179 | 180 | `define ProgramBuffer_addrDim 8 // Program Buffer address dimension 181 | `define ProgramBuffer_addrRange `ProgramBuffer_addrDim - 1:0 182 | `define ProgramBuffer_dim 256 // Buffer Size= 2 ^ ProgramBuffer_addrDim 183 | `define ProgramBuffer_range `ProgramBuffer_dim - 1:0 184 | 185 | // ********************* 186 | // 187 | // Buffer Enhanced Program constant 188 | // 189 | // ********************* 190 | 191 | `define BuffEnhProgramBuffer_dim 256 192 | `define BuffEnhProgramBuffer_range `BuffEnhProgramBuffer_dim - 1 : 0 193 | `define BuffEnhProgramBuffer_addrDim 8 194 | `define BuffEnhProgramBuffer_addrRange `BuffEnhProgramBuffer_addrDim - 1:0 195 | 196 | 197 | // Warning and Error Messages 198 | 199 | `define NoError_msg 0 // No Error Found 200 | `define CmdSeq_msg 1 // Sequence Command Unknown 201 | `define SuspCmd_msg 2 // Cannot execute this command during suspend 202 | `define SuspAcc_msg 3 // Cannot access this address due to suspend 203 | `define AddrRange_msg 4 // Address out of range 204 | `define AddrTog_msg 5 // Cannot change block address during command sequence 205 | `define SuspAccWarn_msg 6 // It isn't possible access this address due to suspend 206 | `define InvVDD_msg 7 // Voltage Supply must be: VDD>VDDmin or VDDVDDmin or VDD= 8'h21 && rxd_data <= 8'h7E) 67 | $write(", ASCII: %c\n", rxd_data); 68 | else 69 | $write("\n"); 70 | 71 | @(posedge uart_clk); 72 | rxd_clear = 1; 73 | @(posedge uart_clk); 74 | rxd_clear = 0; 75 | 76 | wait(rxd_data_ready == 0); 77 | end 78 | 79 | endmodule 80 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/SEG7_LUT.v: -------------------------------------------------------------------------------- 1 | module SEG7_LUT ( 2 | oSEG1, 3 | iDIG 4 | ); 5 | input wire [3:0] iDIG; 6 | output wire [7:0] oSEG1; 7 | reg [6:0] oSEG; 8 | 9 | always @(iDIG) begin 10 | case (iDIG) 11 | 4'h1: oSEG = 7'b1110110; // ---t---- 12 | 4'h2: oSEG = 7'b0100001; // | | 13 | 4'h3: oSEG = 7'b0100100; // lt rt 14 | 4'h4: oSEG = 7'b0010110; // | | 15 | 4'h5: oSEG = 7'b0001100; // ---m---- 16 | 4'h6: oSEG = 7'b0001000; // | | 17 | 4'h7: oSEG = 7'b1100110; // lb rb 18 | 4'h8: oSEG = 7'b0000000; // | | 19 | 4'h9: oSEG = 7'b0000110; // ---b---- 20 | 4'ha: oSEG = 7'b0000010; 21 | 4'hb: oSEG = 7'b0011000; 22 | 4'hc: oSEG = 7'b1001001; 23 | 4'hd: oSEG = 7'b0110000; 24 | 4'he: oSEG = 7'b0001001; 25 | 4'hf: oSEG = 7'b0001011; 26 | 4'h0: oSEG = 7'b1000000; 27 | endcase 28 | end 29 | 30 | assign oSEG1 = {~oSEG, 1'b0}; 31 | endmodule 32 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/async.v: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////// 2 | // RS-232 RX and TX module 3 | // (c) fpga4fun.com & KNJN LLC - 2003 to 2016 4 | 5 | // The RS-232 settings are fixed 6 | // TX: 8-bit data, 2 stop, no-parity 7 | // RX: 8-bit data, 1 stop, no-parity (the receiver can accept more stop bits of course) 8 | 9 | //`define SIMULATION // in this mode, TX outputs one bit per clock cycle 10 | // and RX receives one bit per clock cycle (for fast simulations) 11 | 12 | //////////////////////////////////////////////////////// 13 | 14 | module async_transmitter( 15 | input wire clk, 16 | input wire TxD_start, 17 | input wire [7:0] TxD_data, 18 | output wire TxD, 19 | output wire TxD_busy 20 | ); 21 | 22 | // Assert TxD_start for (at least) one clock cycle to start transmission of TxD_data 23 | // TxD_data is latched so that it doesn't have to stay valid while it is being sent 24 | 25 | parameter ClkFrequency = 25000000; // 25MHz 26 | parameter Baud = 115200; 27 | 28 | // generate 29 | // if(ClkFrequency> 1); 52 | 53 | case(TxD_state) 54 | 4'b0000: if(TxD_start) TxD_state <= 4'b0100; 55 | 4'b0100: if(BitTick) TxD_state <= 4'b1000; // start bit 56 | 4'b1000: if(BitTick) TxD_state <= 4'b1001; // bit 0 57 | 4'b1001: if(BitTick) TxD_state <= 4'b1010; // bit 1 58 | 4'b1010: if(BitTick) TxD_state <= 4'b1011; // bit 2 59 | 4'b1011: if(BitTick) TxD_state <= 4'b1100; // bit 3 60 | 4'b1100: if(BitTick) TxD_state <= 4'b1101; // bit 4 61 | 4'b1101: if(BitTick) TxD_state <= 4'b1110; // bit 5 62 | 4'b1110: if(BitTick) TxD_state <= 4'b1111; // bit 6 63 | 4'b1111: if(BitTick) TxD_state <= 4'b0010; // bit 7 64 | 4'b0010: if(BitTick) TxD_state <= 4'b0000; // stop1 65 | //4'b0011: if(BitTick) TxD_state <= 4'b0000; // stop2 66 | default: if(BitTick) TxD_state <= 4'b0000; 67 | endcase 68 | end 69 | 70 | assign TxD = (TxD_state<4) | (TxD_state[3] & TxD_shift[0]); // put together the start, data and stop bits 71 | endmodule 72 | 73 | 74 | //////////////////////////////////////////////////////// 75 | module async_receiver( 76 | input wire clk, 77 | input wire RxD, 78 | output reg RxD_data_ready, 79 | input wire RxD_clear, 80 | output reg [7:0] RxD_data // data received, valid only (for one clock cycle) when RxD_data_ready is asserted 81 | ); 82 | 83 | parameter ClkFrequency = 25000000; // 25MHz 84 | parameter Baud = 115200; 85 | 86 | parameter Oversampling = 8; // needs to be a power of 2 87 | // we oversample the RxD line at a fixed rate to capture each RxD data bit at the "right" time 88 | // 8 times oversampling by default, use 16 for higher quality reception 89 | 90 | // generate 91 | // if(ClkFrequency>log2) log2=log2+1; end endfunction 136 | localparam l2o = log2(Oversampling); 137 | reg [l2o-2:0] OversamplingCnt = 0; 138 | always @(posedge clk) if(OversamplingTick) OversamplingCnt <= (RxD_state==0) ? 1'd0 : OversamplingCnt + 1'd1; 139 | wire sampleNow = OversamplingTick && (OversamplingCnt==Oversampling/2-1); 140 | `endif 141 | 142 | // now we can accumulate the RxD bits in a shift-register 143 | always @(posedge clk) 144 | case(RxD_state) 145 | 4'b0000: if(~RxD_bit) RxD_state <= `ifdef SIMULATION 4'b1000 `else 4'b0001 `endif; // start bit found? 146 | 4'b0001: if(sampleNow) RxD_state <= 4'b1000; // sync start bit to sampleNow 147 | 4'b1000: if(sampleNow) RxD_state <= 4'b1001; // bit 0 148 | 4'b1001: if(sampleNow) RxD_state <= 4'b1010; // bit 1 149 | 4'b1010: if(sampleNow) RxD_state <= 4'b1011; // bit 2 150 | 4'b1011: if(sampleNow) RxD_state <= 4'b1100; // bit 3 151 | 4'b1100: if(sampleNow) RxD_state <= 4'b1101; // bit 4 152 | 4'b1101: if(sampleNow) RxD_state <= 4'b1110; // bit 5 153 | 4'b1110: if(sampleNow) RxD_state <= 4'b1111; // bit 6 154 | 4'b1111: if(sampleNow) RxD_state <= 4'b0010; // bit 7 155 | 4'b0010: if(sampleNow) RxD_state <= 4'b0000; // stop bit 156 | default: RxD_state <= 4'b0000; 157 | endcase 158 | 159 | always @(posedge clk) 160 | if(sampleNow && RxD_state[3]) RxD_data <= {RxD_bit, RxD_data[7:1]}; 161 | 162 | //reg RxD_data_error = 0; 163 | always @(posedge clk) 164 | begin 165 | if(RxD_clear) 166 | RxD_data_ready <= 0; 167 | else 168 | RxD_data_ready <= RxD_data_ready | (sampleNow && RxD_state==4'b0010 && RxD_bit); // make sure a stop bit is received 169 | //RxD_data_error <= (sampleNow && RxD_state==4'b0010 && ~RxD_bit); // error if a stop bit is not received 170 | end 171 | 172 | `ifdef SIMULATION 173 | assign RxD_idle = 0; 174 | `else 175 | reg [l2o+1:0] GapCnt = 0; 176 | always @(posedge clk) if (RxD_state!=0) GapCnt<=0; else if(OversamplingTick & ~GapCnt[log2(Oversampling)+1]) GapCnt <= GapCnt + 1'h1; 177 | assign RxD_idle = GapCnt[l2o+1]; 178 | always @(posedge clk) RxD_endofpacket <= OversamplingTick & ~GapCnt[l2o+1] & &GapCnt[l2o:0]; 179 | `endif 180 | 181 | endmodule 182 | 183 | 184 | //////////////////////////////////////////////////////// 185 | // dummy module used to be able to raise an assertion in Verilog 186 | //module ASSERTION_ERROR(); 187 | //endmodule 188 | 189 | 190 | //////////////////////////////////////////////////////// 191 | module BaudTickGen( 192 | input wire clk, enable, 193 | output wire tick // generate a tick at the specified baud rate * oversampling 194 | ); 195 | parameter ClkFrequency = 25000000; 196 | parameter Baud = 115200; 197 | parameter Oversampling = 1; 198 | 199 | function integer log2(input integer v); begin log2=0; while(v>>log2) log2=log2+1; end endfunction 200 | localparam AccWidth = log2(ClkFrequency/Baud)+8; // +/- 2% max timing error over a byte 201 | reg [AccWidth:0] Acc = 0; 202 | localparam ShiftLimiter = log2(Baud*Oversampling >> (31-AccWidth)); // this makes sure Inc calculation doesn't overflow 203 | localparam Inc = ((Baud*Oversampling << (AccWidth-ShiftLimiter))+(ClkFrequency>>(ShiftLimiter+1)))/(ClkFrequency>>ShiftLimiter); 204 | always @(posedge clk) if(enable) Acc <= Acc[AccWidth-1:0] + Inc[AccWidth:0]; else Acc <= Inc[AccWidth:0]; 205 | assign tick = Acc[AccWidth]; 206 | endmodule 207 | 208 | 209 | //////////////////////////////////////////////////////// 210 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/common/arbiter/arbiter.v: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014-2021 Alex Forencich 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | The above copyright notice and this permission notice shall be included in 10 | all copies or substantial portions of the Software. 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 17 | THE SOFTWARE. 18 | */ 19 | 20 | // Language: Verilog 2001 21 | 22 | `timescale 1ns / 1ps 23 | 24 | /* 25 | * Arbiter module 26 | */ 27 | module arbiter # 28 | ( 29 | parameter PORTS = 4, 30 | // select round robin arbitration 31 | parameter ARB_TYPE_ROUND_ROBIN = 0, 32 | // blocking arbiter enable 33 | parameter ARB_BLOCK = 0, 34 | // block on acknowledge assert when nonzero, request deassert when 0 35 | parameter ARB_BLOCK_ACK = 1, 36 | // LSB priority selection 37 | parameter ARB_LSB_HIGH_PRIORITY = 0 38 | ) 39 | ( 40 | input wire clk, 41 | input wire rst, 42 | 43 | input wire [PORTS-1:0] request, 44 | input wire [PORTS-1:0] acknowledge, 45 | 46 | output wire [PORTS-1:0] grant, 47 | output wire grant_valid, 48 | output wire [$clog2(PORTS)-1:0] grant_encoded 49 | ); 50 | 51 | reg [PORTS-1:0] grant_reg = 0, grant_next; 52 | reg grant_valid_reg = 0, grant_valid_next; 53 | reg [$clog2(PORTS)-1:0] grant_encoded_reg = 0, grant_encoded_next; 54 | 55 | assign grant_valid = grant_valid_reg; 56 | assign grant = grant_reg; 57 | assign grant_encoded = grant_encoded_reg; 58 | 59 | wire request_valid; 60 | wire [$clog2(PORTS)-1:0] request_index; 61 | wire [PORTS-1:0] request_mask; 62 | 63 | priority_encoder #( 64 | .WIDTH(PORTS), 65 | .LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY) 66 | ) 67 | priority_encoder_inst ( 68 | .input_unencoded(request), 69 | .output_valid(request_valid), 70 | .output_encoded(request_index), 71 | .output_unencoded(request_mask) 72 | ); 73 | 74 | reg [PORTS-1:0] mask_reg = 0, mask_next; 75 | 76 | wire masked_request_valid; 77 | wire [$clog2(PORTS)-1:0] masked_request_index; 78 | wire [PORTS-1:0] masked_request_mask; 79 | 80 | priority_encoder #( 81 | .WIDTH(PORTS), 82 | .LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY) 83 | ) 84 | priority_encoder_masked ( 85 | .input_unencoded(request & mask_reg), 86 | .output_valid(masked_request_valid), 87 | .output_encoded(masked_request_index), 88 | .output_unencoded(masked_request_mask) 89 | ); 90 | 91 | always @* begin 92 | grant_next = 0; 93 | grant_valid_next = 0; 94 | grant_encoded_next = 0; 95 | mask_next = mask_reg; 96 | 97 | if (ARB_BLOCK && !ARB_BLOCK_ACK && grant_reg & request) begin 98 | // granted request still asserted; hold it 99 | grant_valid_next = grant_valid_reg; 100 | grant_next = grant_reg; 101 | grant_encoded_next = grant_encoded_reg; 102 | end else if (ARB_BLOCK && ARB_BLOCK_ACK && grant_valid && !(grant_reg & acknowledge)) begin 103 | // granted request not yet acknowledged; hold it 104 | grant_valid_next = grant_valid_reg; 105 | grant_next = grant_reg; 106 | grant_encoded_next = grant_encoded_reg; 107 | end else if (request_valid) begin 108 | if (ARB_TYPE_ROUND_ROBIN) begin 109 | if (masked_request_valid) begin 110 | grant_valid_next = 1; 111 | grant_next = masked_request_mask; 112 | grant_encoded_next = masked_request_index; 113 | if (ARB_LSB_HIGH_PRIORITY) begin 114 | mask_next = {PORTS{1'b1}} << (masked_request_index + 1); 115 | end else begin 116 | mask_next = {PORTS{1'b1}} >> (PORTS - masked_request_index); 117 | end 118 | end else begin 119 | grant_valid_next = 1; 120 | grant_next = request_mask; 121 | grant_encoded_next = request_index; 122 | if (ARB_LSB_HIGH_PRIORITY) begin 123 | mask_next = {PORTS{1'b1}} << (request_index + 1); 124 | end else begin 125 | mask_next = {PORTS{1'b1}} >> (PORTS - request_index); 126 | end 127 | end 128 | end else begin 129 | grant_valid_next = 1; 130 | grant_next = request_mask; 131 | grant_encoded_next = request_index; 132 | end 133 | end 134 | end 135 | 136 | always @(posedge clk) begin 137 | if (rst) begin 138 | grant_reg <= 0; 139 | grant_valid_reg <= 0; 140 | grant_encoded_reg <= 0; 141 | mask_reg <= 0; 142 | end else begin 143 | grant_reg <= grant_next; 144 | grant_valid_reg <= grant_valid_next; 145 | grant_encoded_reg <= grant_encoded_next; 146 | mask_reg <= mask_next; 147 | end 148 | end 149 | 150 | endmodule 151 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/common/arbiter/priority_encoder.v: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014-2021 Alex Forencich 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | The above copyright notice and this permission notice shall be included in 10 | all copies or substantial portions of the Software. 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 17 | THE SOFTWARE. 18 | */ 19 | 20 | // Language: Verilog 2001 21 | 22 | `timescale 1ns / 1ps 23 | 24 | /* 25 | * Priority encoder module 26 | */ 27 | module priority_encoder # 28 | ( 29 | parameter WIDTH = 4, 30 | // LSB priority selection 31 | parameter LSB_HIGH_PRIORITY = 0 32 | ) 33 | ( 34 | input wire [WIDTH-1:0] input_unencoded, 35 | output wire output_valid, 36 | output wire [$clog2(WIDTH)-1:0] output_encoded, 37 | output wire [WIDTH-1:0] output_unencoded 38 | ); 39 | 40 | parameter LEVELS = WIDTH > 2 ? $clog2(WIDTH) : 1; 41 | parameter W = 2**LEVELS; 42 | 43 | // pad input to even power of two 44 | wire [W-1:0] input_padded = {{W-WIDTH{1'b0}}, input_unencoded}; 45 | 46 | wire [W/2-1:0] stage_valid[LEVELS-1:0]; 47 | wire [W/2-1:0] stage_enc[LEVELS-1:0]; 48 | 49 | generate 50 | genvar l, n; 51 | 52 | // process input bits; generate valid bit and encoded bit for each pair 53 | for (n = 0; n < W/2; n = n + 1) begin : loop_in 54 | assign stage_valid[0][n] = |input_padded[n*2+1:n*2]; 55 | if (LSB_HIGH_PRIORITY) begin 56 | // bit 0 is highest priority 57 | assign stage_enc[0][n] = !input_padded[n*2+0]; 58 | end else begin 59 | // bit 0 is lowest priority 60 | assign stage_enc[0][n] = input_padded[n*2+1]; 61 | end 62 | end 63 | 64 | // compress down to single valid bit and encoded bus 65 | for (l = 1; l < LEVELS; l = l + 1) begin : loop_levels 66 | for (n = 0; n < W/(2*2**l); n = n + 1) begin : loop_compress 67 | assign stage_valid[l][n] = |stage_valid[l-1][n*2+1:n*2]; 68 | if (LSB_HIGH_PRIORITY) begin 69 | // bit 0 is highest priority 70 | assign stage_enc[l][(n+1)*(l+1)-1:n*(l+1)] = stage_valid[l-1][n*2+0] ? {1'b0, stage_enc[l-1][(n*2+1)*l-1:(n*2+0)*l]} : {1'b1, stage_enc[l-1][(n*2+2)*l-1:(n*2+1)*l]}; 71 | end else begin 72 | // bit 0 is lowest priority 73 | assign stage_enc[l][(n+1)*(l+1)-1:n*(l+1)] = stage_valid[l-1][n*2+1] ? {1'b1, stage_enc[l-1][(n*2+2)*l-1:(n*2+1)*l]} : {1'b0, stage_enc[l-1][(n*2+1)*l-1:(n*2+0)*l]}; 74 | end 75 | end 76 | end 77 | endgenerate 78 | 79 | assign output_valid = stage_valid[LEVELS-1]; 80 | assign output_encoded = stage_enc[LEVELS-1]; 81 | assign output_unencoded = 1 << output_encoded; 82 | 83 | endmodule 84 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/common/arbiter/wb_arbiter_2.v: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015-2016 Alex Forencich 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | The above copyright notice and this permission notice shall be included in 10 | all copies or substantial portions of the Software. 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 17 | THE SOFTWARE. 18 | */ 19 | 20 | // Language: Verilog 2001 21 | 22 | `timescale 1 ns / 1 ps 23 | 24 | /* 25 | * Wishbone 2 port arbiter 26 | */ 27 | module wb_arbiter_2 # 28 | ( 29 | parameter DATA_WIDTH = 32, // width of data bus in bits (8, 16, 32, or 64) 30 | parameter ADDR_WIDTH = 32, // width of address bus in bits 31 | parameter SELECT_WIDTH = (DATA_WIDTH/8), // width of word select bus (1, 2, 4, or 8) 32 | parameter ARB_TYPE_ROUND_ROBIN = 0, // select round robin arbitration 33 | parameter ARB_LSB_HIGH_PRIORITY = 1 // LSB priority selection 34 | ) 35 | ( 36 | input wire clk, 37 | input wire rst, 38 | 39 | /* 40 | * Wishbone master 0 input 41 | */ 42 | input wire [ADDR_WIDTH-1:0] wbm0_adr_i, // ADR_I() address input 43 | input wire [DATA_WIDTH-1:0] wbm0_dat_i, // DAT_I() data in 44 | output wire [DATA_WIDTH-1:0] wbm0_dat_o, // DAT_O() data out 45 | input wire wbm0_we_i, // WE_I write enable input 46 | input wire [SELECT_WIDTH-1:0] wbm0_sel_i, // SEL_I() select input 47 | input wire wbm0_stb_i, // STB_I strobe input 48 | output wire wbm0_ack_o, // ACK_O acknowledge output 49 | output wire wbm0_err_o, // ERR_O error output 50 | output wire wbm0_rty_o, // RTY_O retry output 51 | input wire wbm0_cyc_i, // CYC_I cycle input 52 | 53 | /* 54 | * Wishbone master 1 input 55 | */ 56 | input wire [ADDR_WIDTH-1:0] wbm1_adr_i, // ADR_I() address input 57 | input wire [DATA_WIDTH-1:0] wbm1_dat_i, // DAT_I() data in 58 | output wire [DATA_WIDTH-1:0] wbm1_dat_o, // DAT_O() data out 59 | input wire wbm1_we_i, // WE_I write enable input 60 | input wire [SELECT_WIDTH-1:0] wbm1_sel_i, // SEL_I() select input 61 | input wire wbm1_stb_i, // STB_I strobe input 62 | output wire wbm1_ack_o, // ACK_O acknowledge output 63 | output wire wbm1_err_o, // ERR_O error output 64 | output wire wbm1_rty_o, // RTY_O retry output 65 | input wire wbm1_cyc_i, // CYC_I cycle input 66 | 67 | /* 68 | * Wishbone slave output 69 | */ 70 | output wire [ADDR_WIDTH-1:0] wbs_adr_o, // ADR_O() address output 71 | input wire [DATA_WIDTH-1:0] wbs_dat_i, // DAT_I() data in 72 | output wire [DATA_WIDTH-1:0] wbs_dat_o, // DAT_O() data out 73 | output wire wbs_we_o, // WE_O write enable output 74 | output wire [SELECT_WIDTH-1:0] wbs_sel_o, // SEL_O() select output 75 | output wire wbs_stb_o, // STB_O strobe output 76 | input wire wbs_ack_i, // ACK_I acknowledge input 77 | input wire wbs_err_i, // ERR_I error input 78 | input wire wbs_rty_i, // RTY_I retry input 79 | output wire wbs_cyc_o // CYC_O cycle output 80 | ); 81 | 82 | wire [1:0] request; 83 | wire [1:0] grant; 84 | 85 | assign request[0] = wbm0_cyc_i; 86 | assign request[1] = wbm1_cyc_i; 87 | 88 | wire wbm0_sel = grant[0] & grant_valid; 89 | wire wbm1_sel = grant[1] & grant_valid; 90 | 91 | // master 0 92 | assign wbm0_dat_o = wbs_dat_i; 93 | assign wbm0_ack_o = wbs_ack_i & wbm0_sel; 94 | assign wbm0_err_o = wbs_err_i & wbm0_sel; 95 | assign wbm0_rty_o = wbs_rty_i & wbm0_sel; 96 | 97 | // master 1 98 | assign wbm1_dat_o = wbs_dat_i; 99 | assign wbm1_ack_o = wbs_ack_i & wbm1_sel; 100 | assign wbm1_err_o = wbs_err_i & wbm1_sel; 101 | assign wbm1_rty_o = wbs_rty_i & wbm1_sel; 102 | 103 | // slave 104 | assign wbs_adr_o = wbm0_sel ? wbm0_adr_i : 105 | wbm1_sel ? wbm1_adr_i : 106 | {ADDR_WIDTH{1'b0}}; 107 | 108 | assign wbs_dat_o = wbm0_sel ? wbm0_dat_i : 109 | wbm1_sel ? wbm1_dat_i : 110 | {DATA_WIDTH{1'b0}}; 111 | 112 | assign wbs_we_o = wbm0_sel ? wbm0_we_i : 113 | wbm1_sel ? wbm1_we_i : 114 | 1'b0; 115 | 116 | assign wbs_sel_o = wbm0_sel ? wbm0_sel_i : 117 | wbm1_sel ? wbm1_sel_i : 118 | {SELECT_WIDTH{1'b0}}; 119 | 120 | assign wbs_stb_o = wbm0_sel ? wbm0_stb_i : 121 | wbm1_sel ? wbm1_stb_i : 122 | 1'b0; 123 | 124 | assign wbs_cyc_o = wbm0_sel ? 1'b1 : 125 | wbm1_sel ? 1'b1 : 126 | 1'b0; 127 | 128 | // arbiter instance 129 | arbiter #( 130 | .PORTS(2), 131 | .ARB_TYPE_ROUND_ROBIN(ARB_TYPE_ROUND_ROBIN), 132 | .ARB_BLOCK(1), 133 | .ARB_BLOCK_ACK(0), 134 | .ARB_LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY) 135 | ) 136 | arb_inst ( 137 | .clk(clk), 138 | .rst(rst), 139 | .request(request), 140 | .acknowledge(), 141 | .grant(grant), 142 | .grant_valid(grant_valid), 143 | .grant_encoded() 144 | ); 145 | 146 | endmodule 147 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/common/arbiter/wb_arbiter_4.v: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015-2016 Alex Forencich 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | The above copyright notice and this permission notice shall be included in 10 | all copies or substantial portions of the Software. 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 17 | THE SOFTWARE. 18 | */ 19 | // Language: Verilog 2001 20 | `timescale 1 ns / 1 ps 21 | /* 22 | * Wishbone 4 port arbiter 23 | */ 24 | module wb_arbiter_4 # 25 | ( 26 | parameter DATA_WIDTH = 32, // width of data bus in bits (8, 16, 32, or 64) 27 | parameter ADDR_WIDTH = 32, // width of address bus in bits 28 | parameter SELECT_WIDTH = (DATA_WIDTH/8), // width of word select bus (1, 2, 4, or 8) 29 | parameter ARB_TYPE_ROUND_ROBIN = 0, // select round robin arbitration 30 | parameter ARB_LSB_HIGH_PRIORITY = 1 // LSB priority selection 31 | ) 32 | ( 33 | input wire clk, 34 | input wire rst, 35 | /* 36 | * Wishbone master 0 input 37 | */ 38 | input wire [ADDR_WIDTH-1:0] wbm0_adr_i, // ADR_I() address input 39 | input wire [DATA_WIDTH-1:0] wbm0_dat_i, // DAT_I() data in 40 | output wire [DATA_WIDTH-1:0] wbm0_dat_o, // DAT_O() data out 41 | input wire wbm0_we_i, // WE_I write enable input 42 | input wire [SELECT_WIDTH-1:0] wbm0_sel_i, // SEL_I() select input 43 | input wire wbm0_stb_i, // STB_I strobe input 44 | output wire wbm0_ack_o, // ACK_O acknowledge output 45 | output wire wbm0_err_o, // ERR_O error output 46 | output wire wbm0_rty_o, // RTY_O retry output 47 | input wire wbm0_cyc_i, // CYC_I cycle input 48 | /* 49 | * Wishbone master 1 input 50 | */ 51 | input wire [ADDR_WIDTH-1:0] wbm1_adr_i, // ADR_I() address input 52 | input wire [DATA_WIDTH-1:0] wbm1_dat_i, // DAT_I() data in 53 | output wire [DATA_WIDTH-1:0] wbm1_dat_o, // DAT_O() data out 54 | input wire wbm1_we_i, // WE_I write enable input 55 | input wire [SELECT_WIDTH-1:0] wbm1_sel_i, // SEL_I() select input 56 | input wire wbm1_stb_i, // STB_I strobe input 57 | output wire wbm1_ack_o, // ACK_O acknowledge output 58 | output wire wbm1_err_o, // ERR_O error output 59 | output wire wbm1_rty_o, // RTY_O retry output 60 | input wire wbm1_cyc_i, // CYC_I cycle input 61 | /* 62 | * Wishbone master 2 input 63 | */ 64 | input wire [ADDR_WIDTH-1:0] wbm2_adr_i, // ADR_I() address input 65 | input wire [DATA_WIDTH-1:0] wbm2_dat_i, // DAT_I() data in 66 | output wire [DATA_WIDTH-1:0] wbm2_dat_o, // DAT_O() data out 67 | input wire wbm2_we_i, // WE_I write enable input 68 | input wire [SELECT_WIDTH-1:0] wbm2_sel_i, // SEL_I() select input 69 | input wire wbm2_stb_i, // STB_I strobe input 70 | output wire wbm2_ack_o, // ACK_O acknowledge output 71 | output wire wbm2_err_o, // ERR_O error output 72 | output wire wbm2_rty_o, // RTY_O retry output 73 | input wire wbm2_cyc_i, // CYC_I cycle input 74 | /* 75 | * Wishbone master 3 input 76 | */ 77 | input wire [ADDR_WIDTH-1:0] wbm3_adr_i, // ADR_I() address input 78 | input wire [DATA_WIDTH-1:0] wbm3_dat_i, // DAT_I() data in 79 | output wire [DATA_WIDTH-1:0] wbm3_dat_o, // DAT_O() data out 80 | input wire wbm3_we_i, // WE_I write enable input 81 | input wire [SELECT_WIDTH-1:0] wbm3_sel_i, // SEL_I() select input 82 | input wire wbm3_stb_i, // STB_I strobe input 83 | output wire wbm3_ack_o, // ACK_O acknowledge output 84 | output wire wbm3_err_o, // ERR_O error output 85 | output wire wbm3_rty_o, // RTY_O retry output 86 | input wire wbm3_cyc_i, // CYC_I cycle input 87 | /* 88 | * Wishbone slave output 89 | */ 90 | output wire [ADDR_WIDTH-1:0] wbs_adr_o, // ADR_O() address output 91 | input wire [DATA_WIDTH-1:0] wbs_dat_i, // DAT_I() data in 92 | output wire [DATA_WIDTH-1:0] wbs_dat_o, // DAT_O() data out 93 | output wire wbs_we_o, // WE_O write enable output 94 | output wire [SELECT_WIDTH-1:0] wbs_sel_o, // SEL_O() select output 95 | output wire wbs_stb_o, // STB_O strobe output 96 | input wire wbs_ack_i, // ACK_I acknowledge input 97 | input wire wbs_err_i, // ERR_I error input 98 | input wire wbs_rty_i, // RTY_I retry input 99 | output wire wbs_cyc_o // CYC_O cycle output 100 | ); 101 | wire [3:0] request; 102 | wire [3:0] grant; 103 | 104 | assign request[0] = wbm0_cyc_i; 105 | assign request[1] = wbm1_cyc_i; 106 | assign request[2] = wbm2_cyc_i; 107 | assign request[3] = wbm3_cyc_i; 108 | 109 | wire wbm0_sel = grant[0] & grant_valid; 110 | wire wbm1_sel = grant[1] & grant_valid; 111 | wire wbm2_sel = grant[2] & grant_valid; 112 | wire wbm3_sel = grant[3] & grant_valid; 113 | // master 0 114 | assign wbm0_dat_o = wbs_dat_i; 115 | assign wbm0_ack_o = wbs_ack_i & wbm0_sel; 116 | assign wbm0_err_o = wbs_err_i & wbm0_sel; 117 | assign wbm0_rty_o = wbs_rty_i & wbm0_sel; 118 | // master 1 119 | assign wbm1_dat_o = wbs_dat_i; 120 | assign wbm1_ack_o = wbs_ack_i & wbm1_sel; 121 | assign wbm1_err_o = wbs_err_i & wbm1_sel; 122 | assign wbm1_rty_o = wbs_rty_i & wbm1_sel; 123 | // master 2 124 | assign wbm2_dat_o = wbs_dat_i; 125 | assign wbm2_ack_o = wbs_ack_i & wbm2_sel; 126 | assign wbm2_err_o = wbs_err_i & wbm2_sel; 127 | assign wbm2_rty_o = wbs_rty_i & wbm2_sel; 128 | // master 3 129 | assign wbm3_dat_o = wbs_dat_i; 130 | assign wbm3_ack_o = wbs_ack_i & wbm3_sel; 131 | assign wbm3_err_o = wbs_err_i & wbm3_sel; 132 | assign wbm3_rty_o = wbs_rty_i & wbm3_sel; 133 | // slave 134 | assign wbs_adr_o = wbm0_sel ? wbm0_adr_i : 135 | wbm1_sel ? wbm1_adr_i : 136 | wbm2_sel ? wbm2_adr_i : 137 | wbm3_sel ? wbm3_adr_i : 138 | {ADDR_WIDTH{1'b0}}; 139 | assign wbs_dat_o = wbm0_sel ? wbm0_dat_i : 140 | wbm1_sel ? wbm1_dat_i : 141 | wbm2_sel ? wbm2_dat_i : 142 | wbm3_sel ? wbm3_dat_i : 143 | {DATA_WIDTH{1'b0}}; 144 | assign wbs_we_o = wbm0_sel ? wbm0_we_i : 145 | wbm1_sel ? wbm1_we_i : 146 | wbm2_sel ? wbm2_we_i : 147 | wbm3_sel ? wbm3_we_i : 148 | 1'b0; 149 | assign wbs_sel_o = wbm0_sel ? wbm0_sel_i : 150 | wbm1_sel ? wbm1_sel_i : 151 | wbm2_sel ? wbm2_sel_i : 152 | wbm3_sel ? wbm3_sel_i : 153 | {SELECT_WIDTH{1'b0}}; 154 | assign wbs_stb_o = wbm0_sel ? wbm0_stb_i : 155 | wbm1_sel ? wbm1_stb_i : 156 | wbm2_sel ? wbm2_stb_i : 157 | wbm3_sel ? wbm3_stb_i : 158 | 1'b0; 159 | assign wbs_cyc_o = wbm0_sel ? 1'b1 : 160 | wbm1_sel ? 1'b1 : 161 | wbm2_sel ? 1'b1 : 162 | wbm3_sel ? 1'b1 : 163 | 1'b0; 164 | // arbiter instance 165 | arbiter #( 166 | .PORTS(4), 167 | .ARB_TYPE_ROUND_ROBIN(ARB_TYPE_ROUND_ROBIN), 168 | .ARB_BLOCK(1), 169 | .ARB_BLOCK_ACK(0), 170 | .ARB_LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY) 171 | ) 172 | arb_inst ( 173 | .clk(clk), 174 | .rst(rst), 175 | .request(request), 176 | .acknowledge(), 177 | .grant(grant), 178 | .grant_valid(grant_valid), 179 | .grant_encoded() 180 | ); 181 | endmodule -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/common/lfsr_prng.sv: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2016 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1ns / 1ps 28 | 29 | /* 30 | * LFSR PRNG 31 | */ 32 | module lfsr_prng #( 33 | // width of data output 34 | parameter DATA_WIDTH = 32, 35 | 36 | // invert output 37 | parameter INVERT = 0 38 | ) ( 39 | input wire clk, 40 | input wire load, 41 | input wire [DATA_WIDTH-1:0] seed, 42 | 43 | input wire enable, 44 | output wire [DATA_WIDTH-1:0] data_out 45 | ); 46 | 47 | /* 48 | Ports: 49 | clk Clock input 50 | load Load input, set state to seed 51 | seed Seed input 52 | enable Generate new output data 53 | data_out LFSR output (DATA_WIDTH bits) 54 | 55 | Parameters: 56 | INVERT Bitwise invert PRBS output. 57 | DATA_WIDTH Specify width of output data bus. 58 | */ 59 | 60 | reg [DATA_WIDTH-1:0] state_reg; 61 | reg [DATA_WIDTH-1:0] output_reg; 62 | 63 | wire [DATA_WIDTH-1:0] lfsr_data; 64 | wire [DATA_WIDTH-1:0] lfsr_state; 65 | 66 | assign data_out = output_reg; 67 | 68 | // Maximal Length LFSR Feedback Terms 69 | // Taken from https://users.ece.cmu.edu/~koopman/lfsr/ 70 | // MSB is suppressed for lfsr module 71 | parameter [63:0] MAX_POLY_TABLE[0:63] = { 72 | 'h0, 73 | 'h0, 74 | 'h0, 75 | 4'h9, 76 | 5'h9, 77 | 6'h21, 78 | 7'h41, 79 | 8'h71, 80 | 9'h21, 81 | 10'h81, 82 | 11'h201, 83 | 12'h941, 84 | 13'h1601, 85 | 14'h2a01, 86 | 15'h4001, 87 | 16'h6801, 88 | 17'h4001, 89 | 18'h32001, 90 | 19'h64001, 91 | 20'h20001, 92 | 21'h80001, 93 | 22'h200001, 94 | 23'h40001, 95 | 24'hb00001, 96 | 25'h400001, 97 | 26'h3100001, 98 | 27'h6400001, 99 | 28'h2000001, 100 | 29'h8000001, 101 | 30'h25000001, 102 | 31'h10000001, 103 | 32'hea000001, 104 | 33'h128000001, 105 | 34'h338000001, 106 | 35'h200000001, 107 | 36'hdc0000001, 108 | 37'h1f00000001, 109 | 38'h2300000001, 110 | 39'h800000001, 111 | 40'h3800000001, 112 | 41'h4000000001, 113 | 42'h3e000000001, 114 | 43'h1a000000001, 115 | 44'h4c000000001, 116 | 45'h160000000001, 117 | 46'h3a4000000001, 118 | 47'h40000000001, 119 | 48'hda0000000001, 120 | 49'h380000000001, 121 | 50'h1c00000000001, 122 | 51'h5200000000001, 123 | 52'h2000000000001, 124 | 53'h18800000000001, 125 | 54'h1f000000000001, 126 | 55'h62000000000001, 127 | 56'h52000000000001, 128 | 57'hd0000000000001, 129 | 58'h230000000000001, 130 | 59'h5e0000000000001, 131 | 60'h800000000000001, 132 | 61'h1900000000000001, 133 | 62'hb00000000000001, 134 | 63'h4000000000000001, 135 | 64'hb000000000000001 136 | }; 137 | 138 | lfsr #( 139 | .LFSR_WIDTH(DATA_WIDTH), 140 | .LFSR_POLY(MAX_POLY_TABLE[DATA_WIDTH-1]), 141 | .LFSR_CONFIG("FIBONACCI"), 142 | .LFSR_FEED_FORWARD(0), 143 | .REVERSE(1), 144 | .DATA_WIDTH(DATA_WIDTH) 145 | ) lfsr_inst ( 146 | .data_in ({DATA_WIDTH{1'b0}}), 147 | .state_in (state_reg), 148 | .data_out (lfsr_data), 149 | .state_out(lfsr_state) 150 | ); 151 | 152 | always @* begin 153 | if (INVERT) begin 154 | output_reg <= ~lfsr_data; 155 | end else begin 156 | output_reg <= lfsr_data; 157 | end 158 | end 159 | 160 | always @(posedge clk) begin 161 | if (load) begin 162 | state_reg <= seed; 163 | end else begin 164 | if (enable) begin 165 | state_reg <= lfsr_state; 166 | end 167 | end 168 | end 169 | 170 | `ifdef SIMULATION 171 | initial begin 172 | $display("LFSR PRNG"); 173 | $display(" DATA_WIDTH: %d", DATA_WIDTH); 174 | $display(" INVERT: %d", INVERT); 175 | $display(" POLY: %x", MAX_POLY_TABLE[DATA_WIDTH-1]); 176 | end 177 | `endif 178 | 179 | endmodule 180 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/common/trigger.sv: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | 3 | module trigger ( 4 | input wire clk, 5 | input wire push_btn, 6 | output wire trigger 7 | ); 8 | 9 | reg btn_last_reg; 10 | reg trigger_reg; 11 | 12 | 13 | always_ff @ (posedge clk) begin 14 | btn_last_reg <= push_btn; 15 | if (btn_last_reg == 1'b0 && push_btn == 1'b1) 16 | trigger_reg <= 1'b1; 17 | else 18 | trigger_reg <= 1'b0; 19 | end 20 | 21 | assign trigger = trigger_reg; 22 | 23 | endmodule // trigger 24 | 25 | 26 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/common/wb_mux_4.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2015-2016 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Wishbone 4 port multiplexer 31 | */ 32 | module wb_mux_4 # 33 | ( 34 | parameter DATA_WIDTH = 32, // width of data bus in bits (8, 16, 32, or 64) 35 | parameter ADDR_WIDTH = 32, // width of address bus in bits 36 | parameter SELECT_WIDTH = (DATA_WIDTH/8) // width of word select bus (1, 2, 4, or 8) 37 | ) 38 | ( 39 | input wire clk, 40 | input wire rst, 41 | 42 | /* 43 | * Wishbone master input 44 | */ 45 | input wire [ADDR_WIDTH-1:0] wbm_adr_i, // ADR_I() address input 46 | input wire [DATA_WIDTH-1:0] wbm_dat_i, // DAT_I() data in 47 | output wire [DATA_WIDTH-1:0] wbm_dat_o, // DAT_O() data out 48 | input wire wbm_we_i, // WE_I write enable input 49 | input wire [SELECT_WIDTH-1:0] wbm_sel_i, // SEL_I() select input 50 | input wire wbm_stb_i, // STB_I strobe input 51 | output wire wbm_ack_o, // ACK_O acknowledge output 52 | output wire wbm_err_o, // ERR_O error output 53 | output wire wbm_rty_o, // RTY_O retry output 54 | input wire wbm_cyc_i, // CYC_I cycle input 55 | 56 | /* 57 | * Wishbone slave 0 output 58 | */ 59 | output wire [ADDR_WIDTH-1:0] wbs0_adr_o, // ADR_O() address output 60 | input wire [DATA_WIDTH-1:0] wbs0_dat_i, // DAT_I() data in 61 | output wire [DATA_WIDTH-1:0] wbs0_dat_o, // DAT_O() data out 62 | output wire wbs0_we_o, // WE_O write enable output 63 | output wire [SELECT_WIDTH-1:0] wbs0_sel_o, // SEL_O() select output 64 | output wire wbs0_stb_o, // STB_O strobe output 65 | input wire wbs0_ack_i, // ACK_I acknowledge input 66 | input wire wbs0_err_i, // ERR_I error input 67 | input wire wbs0_rty_i, // RTY_I retry input 68 | output wire wbs0_cyc_o, // CYC_O cycle output 69 | 70 | /* 71 | * Wishbone slave 0 address configuration 72 | */ 73 | input wire [ADDR_WIDTH-1:0] wbs0_addr, // Slave address prefix 74 | input wire [ADDR_WIDTH-1:0] wbs0_addr_msk, // Slave address prefix mask 75 | 76 | /* 77 | * Wishbone slave 1 output 78 | */ 79 | output wire [ADDR_WIDTH-1:0] wbs1_adr_o, // ADR_O() address output 80 | input wire [DATA_WIDTH-1:0] wbs1_dat_i, // DAT_I() data in 81 | output wire [DATA_WIDTH-1:0] wbs1_dat_o, // DAT_O() data out 82 | output wire wbs1_we_o, // WE_O write enable output 83 | output wire [SELECT_WIDTH-1:0] wbs1_sel_o, // SEL_O() select output 84 | output wire wbs1_stb_o, // STB_O strobe output 85 | input wire wbs1_ack_i, // ACK_I acknowledge input 86 | input wire wbs1_err_i, // ERR_I error input 87 | input wire wbs1_rty_i, // RTY_I retry input 88 | output wire wbs1_cyc_o, // CYC_O cycle output 89 | 90 | /* 91 | * Wishbone slave 1 address configuration 92 | */ 93 | input wire [ADDR_WIDTH-1:0] wbs1_addr, // Slave address prefix 94 | input wire [ADDR_WIDTH-1:0] wbs1_addr_msk, // Slave address prefix mask 95 | 96 | /* 97 | * Wishbone slave 2 output 98 | */ 99 | output wire [ADDR_WIDTH-1:0] wbs2_adr_o, // ADR_O() address output 100 | input wire [DATA_WIDTH-1:0] wbs2_dat_i, // DAT_I() data in 101 | output wire [DATA_WIDTH-1:0] wbs2_dat_o, // DAT_O() data out 102 | output wire wbs2_we_o, // WE_O write enable output 103 | output wire [SELECT_WIDTH-1:0] wbs2_sel_o, // SEL_O() select output 104 | output wire wbs2_stb_o, // STB_O strobe output 105 | input wire wbs2_ack_i, // ACK_I acknowledge input 106 | input wire wbs2_err_i, // ERR_I error input 107 | input wire wbs2_rty_i, // RTY_I retry input 108 | output wire wbs2_cyc_o, // CYC_O cycle output 109 | 110 | /* 111 | * Wishbone slave 2 address configuration 112 | */ 113 | input wire [ADDR_WIDTH-1:0] wbs2_addr, // Slave address prefix 114 | input wire [ADDR_WIDTH-1:0] wbs2_addr_msk, // Slave address prefix mask 115 | 116 | /* 117 | * Wishbone slave 3 output 118 | */ 119 | output wire [ADDR_WIDTH-1:0] wbs3_adr_o, // ADR_O() address output 120 | input wire [DATA_WIDTH-1:0] wbs3_dat_i, // DAT_I() data in 121 | output wire [DATA_WIDTH-1:0] wbs3_dat_o, // DAT_O() data out 122 | output wire wbs3_we_o, // WE_O write enable output 123 | output wire [SELECT_WIDTH-1:0] wbs3_sel_o, // SEL_O() select output 124 | output wire wbs3_stb_o, // STB_O strobe output 125 | input wire wbs3_ack_i, // ACK_I acknowledge input 126 | input wire wbs3_err_i, // ERR_I error input 127 | input wire wbs3_rty_i, // RTY_I retry input 128 | output wire wbs3_cyc_o, // CYC_O cycle output 129 | 130 | /* 131 | * Wishbone slave 3 address configuration 132 | */ 133 | input wire [ADDR_WIDTH-1:0] wbs3_addr, // Slave address prefix 134 | input wire [ADDR_WIDTH-1:0] wbs3_addr_msk // Slave address prefix mask 135 | ); 136 | 137 | wire wbs0_match = ~|((wbm_adr_i ^ wbs0_addr) & wbs0_addr_msk); 138 | wire wbs1_match = ~|((wbm_adr_i ^ wbs1_addr) & wbs1_addr_msk); 139 | wire wbs2_match = ~|((wbm_adr_i ^ wbs2_addr) & wbs2_addr_msk); 140 | wire wbs3_match = ~|((wbm_adr_i ^ wbs3_addr) & wbs3_addr_msk); 141 | 142 | wire wbs0_sel = wbs0_match; 143 | wire wbs1_sel = wbs1_match & ~(wbs0_match); 144 | wire wbs2_sel = wbs2_match & ~(wbs0_match | wbs1_match); 145 | wire wbs3_sel = wbs3_match & ~(wbs0_match | wbs1_match | wbs2_match); 146 | 147 | wire master_cycle = wbm_cyc_i & wbm_stb_i; 148 | 149 | wire select_error = ~(wbs0_sel | wbs1_sel | wbs2_sel | wbs3_sel) & master_cycle; 150 | 151 | // master 152 | assign wbm_dat_o = wbs0_sel ? wbs0_dat_i : 153 | wbs1_sel ? wbs1_dat_i : 154 | wbs2_sel ? wbs2_dat_i : 155 | wbs3_sel ? wbs3_dat_i : 156 | {DATA_WIDTH{1'b0}}; 157 | 158 | assign wbm_ack_o = wbs0_ack_i | 159 | wbs1_ack_i | 160 | wbs2_ack_i | 161 | wbs3_ack_i; 162 | 163 | assign wbm_err_o = wbs0_err_i | 164 | wbs1_err_i | 165 | wbs2_err_i | 166 | wbs3_err_i | 167 | select_error; 168 | 169 | assign wbm_rty_o = wbs0_rty_i | 170 | wbs1_rty_i | 171 | wbs2_rty_i | 172 | wbs3_rty_i; 173 | 174 | // slave 0 175 | assign wbs0_adr_o = wbm_adr_i; 176 | assign wbs0_dat_o = wbm_dat_i; 177 | assign wbs0_we_o = wbm_we_i & wbs0_sel; 178 | assign wbs0_sel_o = wbm_sel_i; 179 | assign wbs0_stb_o = wbm_stb_i & wbs0_sel; 180 | assign wbs0_cyc_o = wbm_cyc_i & wbs0_sel; 181 | 182 | // slave 1 183 | assign wbs1_adr_o = wbm_adr_i; 184 | assign wbs1_dat_o = wbm_dat_i; 185 | assign wbs1_we_o = wbm_we_i & wbs1_sel; 186 | assign wbs1_sel_o = wbm_sel_i; 187 | assign wbs1_stb_o = wbm_stb_i & wbs1_sel; 188 | assign wbs1_cyc_o = wbm_cyc_i & wbs1_sel; 189 | 190 | // slave 2 191 | assign wbs2_adr_o = wbm_adr_i; 192 | assign wbs2_dat_o = wbm_dat_i; 193 | assign wbs2_we_o = wbm_we_i & wbs2_sel; 194 | assign wbs2_sel_o = wbm_sel_i; 195 | assign wbs2_stb_o = wbm_stb_i & wbs2_sel; 196 | assign wbs2_cyc_o = wbm_cyc_i & wbs2_sel; 197 | 198 | // slave 3 199 | assign wbs3_adr_o = wbm_adr_i; 200 | assign wbs3_dat_o = wbm_dat_i; 201 | assign wbs3_we_o = wbm_we_i & wbs3_sel; 202 | assign wbs3_sel_o = wbm_sel_i; 203 | assign wbs3_stb_o = wbm_stb_i & wbs3_sel; 204 | assign wbs3_cyc_o = wbm_cyc_i & wbs3_sel; 205 | 206 | 207 | endmodule 208 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab2/counter.sv: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | 3 | module counter( 4 | input wire clk, 5 | input wire reset, 6 | 7 | input wire trigger, 8 | output wire [3:0] count 9 | ); 10 | 11 | reg [3:0] count_reg; 12 | 13 | always_ff @ (posedge clk or posedge reset) begin 14 | if (reset) begin 15 | count_reg <= 4'b0000; 16 | end else begin 17 | if (trigger) 18 | if (count_reg == 4'b1111) 19 | count_reg <= count_reg; 20 | else 21 | count_reg <= count_reg + 4'b0001; 22 | 23 | end 24 | end 25 | 26 | assign count = count_reg; 27 | 28 | 29 | endmodule // counter 30 | 31 | 32 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab2/lab2_top.sv: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | 3 | module lab2_top ( 4 | input wire clk_50M, // 50MHz 时钟输入 5 | input wire clk_11M0592, // 11.0592MHz 时钟输入(备用,可不用) 6 | 7 | input wire push_btn, // BTN5 按钮开关,带消抖电路,按下时为 1 8 | input wire reset_btn, // BTN6 复位按钮,带消抖电路,按下时为 1 9 | 10 | input wire [ 3:0] touch_btn, // BTN1~BTN4,按钮开关,按下时为 1 11 | input wire [31:0] dip_sw, // 32 位拨码开关,拨到“ON”时为 1 12 | output wire [15:0] leds, // 16 位 LED,输出时 1 点亮 13 | output wire [ 7:0] dpy0, // 数码管低位信号,包括小数点,输出 1 点亮 14 | output wire [ 7:0] dpy1, // 数码管高位信号,包括小数点,输出 1 点亮 15 | 16 | // CPLD 串口控制器信号 17 | output wire uart_rdn, // 读串口信号,低有效 18 | output wire uart_wrn, // 写串口信号,低有效 19 | input wire uart_dataready, // 串口数据准备好 20 | input wire uart_tbre, // 发送数据标志 21 | input wire uart_tsre, // 数据发送完毕标志 22 | 23 | // BaseRAM 信号 24 | inout wire [31:0] base_ram_data, // BaseRAM 数据,低 8 位与 CPLD 串口控制器共享 25 | output wire [19:0] base_ram_addr, // BaseRAM 地址 26 | output wire [3:0] base_ram_be_n, // BaseRAM 字节使能,低有效。如果不使用字节使能,请保持为 0 27 | output wire base_ram_ce_n, // BaseRAM 片选,低有效 28 | output wire base_ram_oe_n, // BaseRAM 读使能,低有效 29 | output wire base_ram_we_n, // BaseRAM 写使能,低有效 30 | 31 | // ExtRAM 信号 32 | inout wire [31:0] ext_ram_data, // ExtRAM 数据 33 | output wire [19:0] ext_ram_addr, // ExtRAM 地址 34 | output wire [3:0] ext_ram_be_n, // ExtRAM 字节使能,低有效。如果不使用字节使能,请保持为 0 35 | output wire ext_ram_ce_n, // ExtRAM 片选,低有效 36 | output wire ext_ram_oe_n, // ExtRAM 读使能,低有效 37 | output wire ext_ram_we_n, // ExtRAM 写使能,低有效 38 | 39 | // 直连串口信号 40 | output wire txd, // 直连串口发送端 41 | input wire rxd, // 直连串口接收端 42 | 43 | // Flash 存储器信号,参考 JS28F640 芯片手册 44 | output wire [22:0] flash_a, // Flash 地址,a0 仅在 8bit 模式有效,16bit 模式无意义 45 | inout wire [15:0] flash_d, // Flash 数据 46 | output wire flash_rp_n, // Flash 复位信号,低有效 47 | output wire flash_vpen, // Flash 写保护信号,低电平时不能擦除、烧写 48 | output wire flash_ce_n, // Flash 片选信号,低有效 49 | output wire flash_oe_n, // Flash 读使能信号,低有效 50 | output wire flash_we_n, // Flash 写使能信号,低有效 51 | output wire flash_byte_n, // Flash 8bit 模式选择,低有效。在使用 flash 的 16 位模式时请设为 1 52 | 53 | // USB 控制器信号,参考 SL811 芯片手册 54 | output wire sl811_a0, 55 | // inout wire [7:0] sl811_d, // USB 数据线与网络控制器的 dm9k_sd[7:0] 共享 56 | output wire sl811_wr_n, 57 | output wire sl811_rd_n, 58 | output wire sl811_cs_n, 59 | output wire sl811_rst_n, 60 | output wire sl811_dack_n, 61 | input wire sl811_intrq, 62 | input wire sl811_drq_n, 63 | 64 | // 网络控制器信号,参考 DM9000A 芯片手册 65 | output wire dm9k_cmd, 66 | inout wire [15:0] dm9k_sd, 67 | output wire dm9k_iow_n, 68 | output wire dm9k_ior_n, 69 | output wire dm9k_cs_n, 70 | output wire dm9k_pwrst_n, 71 | input wire dm9k_int, 72 | 73 | // 图像输出信号 74 | output wire [2:0] video_red, // 红色像素,3 位 75 | output wire [2:0] video_green, // 绿色像素,3 位 76 | output wire [1:0] video_blue, // 蓝色像素,2 位 77 | output wire video_hsync, // 行同步(水平同步)信号 78 | output wire video_vsync, // 场同步(垂直同步)信号 79 | output wire video_clk, // 像素时钟输出 80 | output wire video_de // 行数据有效信号,用于区分消隐区 81 | ); 82 | 83 | /* =========== Demo code begin =========== */ 84 | 85 | // PLL 分频示例 86 | logic locked, clk_10M, clk_20M; 87 | pll_example clock_gen ( 88 | // Clock in ports 89 | .clk_in1(clk_50M), // 外部时钟输入 90 | // Clock out ports 91 | .clk_out1(clk_10M), // 时钟输出 1,频率在 IP 配置界面中设置 92 | .clk_out2(clk_20M), // 时钟输出 2,频率在 IP 配置界面中设置 93 | // Status and control signals 94 | .reset(reset_btn), // PLL 复位输入 95 | .locked(locked) // PLL 锁定指示输出,"1"表示时钟稳定, 96 | // 后级电路复位信号应当由它生成(见下) 97 | ); 98 | 99 | logic reset_of_clk10M; 100 | // 异步复位,同步释放,将 locked 信号转为后级电路的复位 reset_of_clk10M 101 | always_ff @(posedge clk_10M or negedge locked) begin 102 | if (~locked) reset_of_clk10M <= 1'b1; 103 | else reset_of_clk10M <= 1'b0; 104 | end 105 | 106 | /* =========== Demo code end =========== */ 107 | 108 | // 内部信号声明 109 | logic trigger; 110 | logic [3:0] count; 111 | 112 | // 计数器模块 113 | // TODO: 在 lab2 目录中新建 counter.sv,实现该模块 114 | counter u_counter ( 115 | .clk (clk_10M), 116 | .reset (reset_of_clk10M), 117 | .trigger(trigger), 118 | .count (count) 119 | ); 120 | 121 | // 按键检测模块,在按键上升沿(按下)后输出高电平脉冲 122 | // TODO: 同上,实现 trigger 模块,并例化 123 | trigger u_trigger ( 124 | .clk (clk_10M), 125 | .push_btn (push_btn), 126 | .trigger (trigger) 127 | ); 128 | 129 | 130 | // 低位数码管译码器 131 | // TODO: 例化模板中的 SEG7_LUT 模块 132 | SEG7_LUT u_seg7 ( 133 | .iDIG (count), 134 | .oSEG1(dpy0) 135 | ); 136 | 137 | endmodule 138 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab3/lab3_top.sv: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | 3 | module lab3_top ( 4 | input wire clk_50M, // 50MHz 时钟输入 5 | input wire clk_11M0592, // 11.0592MHz 时钟输入(备用,可不用) 6 | 7 | input wire push_btn, // BTN5 按钮开关,带消抖电路,按下时为 1 8 | input wire reset_btn, // BTN6 复位按钮,带消抖电路,按下时为 1 9 | 10 | input wire [ 3:0] touch_btn, // BTN1~BTN4,按钮开关,按下时为 1 11 | input wire [31:0] dip_sw, // 32 位拨码开关,拨到“ON”时为 1 12 | output wire [15:0] leds, // 16 位 LED,输出时 1 点亮 13 | output wire [ 7:0] dpy0, // 数码管低位信号,包括小数点,输出 1 点亮 14 | output wire [ 7:0] dpy1, // 数码管高位信号,包括小数点,输出 1 点亮 15 | 16 | // CPLD 串口控制器信号 17 | output wire uart_rdn, // 读串口信号,低有效 18 | output wire uart_wrn, // 写串口信号,低有效 19 | input wire uart_dataready, // 串口数据准备好 20 | input wire uart_tbre, // 发送数据标志 21 | input wire uart_tsre, // 数据发送完毕标志 22 | 23 | // BaseRAM 信号 24 | inout wire [31:0] base_ram_data, // BaseRAM 数据,低 8 位与 CPLD 串口控制器共享 25 | output wire [19:0] base_ram_addr, // BaseRAM 地址 26 | output wire [3:0] base_ram_be_n, // BaseRAM 字节使能,低有效。如果不使用字节使能,请保持为 0 27 | output wire base_ram_ce_n, // BaseRAM 片选,低有效 28 | output wire base_ram_oe_n, // BaseRAM 读使能,低有效 29 | output wire base_ram_we_n, // BaseRAM 写使能,低有效 30 | 31 | // ExtRAM 信号 32 | inout wire [31:0] ext_ram_data, // ExtRAM 数据 33 | output wire [19:0] ext_ram_addr, // ExtRAM 地址 34 | output wire [3:0] ext_ram_be_n, // ExtRAM 字节使能,低有效。如果不使用字节使能,请保持为 0 35 | output wire ext_ram_ce_n, // ExtRAM 片选,低有效 36 | output wire ext_ram_oe_n, // ExtRAM 读使能,低有效 37 | output wire ext_ram_we_n, // ExtRAM 写使能,低有效 38 | 39 | // 直连串口信号 40 | output wire txd, // 直连串口发送端 41 | input wire rxd, // 直连串口接收端 42 | 43 | // Flash 存储器信号,参考 JS28F640 芯片手册 44 | output wire [22:0] flash_a, // Flash 地址,a0 仅在 8bit 模式有效,16bit 模式无意义 45 | inout wire [15:0] flash_d, // Flash 数据 46 | output wire flash_rp_n, // Flash 复位信号,低有效 47 | output wire flash_vpen, // Flash 写保护信号,低电平时不能擦除、烧写 48 | output wire flash_ce_n, // Flash 片选信号,低有效 49 | output wire flash_oe_n, // Flash 读使能信号,低有效 50 | output wire flash_we_n, // Flash 写使能信号,低有效 51 | output wire flash_byte_n, // Flash 8bit 模式选择,低有效。在使用 flash 的 16 位模式时请设为 1 52 | 53 | // USB 控制器信号,参考 SL811 芯片手册 54 | output wire sl811_a0, 55 | // inout wire [7:0] sl811_d, // USB 数据线与网络控制器的 dm9k_sd[7:0] 共享 56 | output wire sl811_wr_n, 57 | output wire sl811_rd_n, 58 | output wire sl811_cs_n, 59 | output wire sl811_rst_n, 60 | output wire sl811_dack_n, 61 | input wire sl811_intrq, 62 | input wire sl811_drq_n, 63 | 64 | // 网络控制器信号,参考 DM9000A 芯片手册 65 | output wire dm9k_cmd, 66 | inout wire [15:0] dm9k_sd, 67 | output wire dm9k_iow_n, 68 | output wire dm9k_ior_n, 69 | output wire dm9k_cs_n, 70 | output wire dm9k_pwrst_n, 71 | input wire dm9k_int, 72 | 73 | // 图像输出信号 74 | output wire [2:0] video_red, // 红色像素,3 位 75 | output wire [2:0] video_green, // 绿色像素,3 位 76 | output wire [1:0] video_blue, // 蓝色像素,2 位 77 | output wire video_hsync, // 行同步(水平同步)信号 78 | output wire video_vsync, // 场同步(垂直同步)信号 79 | output wire video_clk, // 像素时钟输出 80 | output wire video_de // 行数据有效信号,用于区分消隐区 81 | ); 82 | 83 | /* =========== Demo code begin =========== */ 84 | 85 | // PLL 分频示例 86 | logic locked, clk_10M, clk_20M; 87 | pll_example clock_gen ( 88 | // Clock in ports 89 | .clk_in1(clk_50M), // 外部时钟输入 90 | // Clock out ports 91 | .clk_out1(clk_10M), // 时钟输出 1,频率在 IP 配置界面中设置 92 | .clk_out2(clk_20M), // 时钟输出 2,频率在 IP 配置界面中设置 93 | // Status and control signals 94 | .reset(reset_btn), // PLL 复位输入 95 | .locked(locked) // PLL 锁定指示输出,"1"表示时钟稳定, 96 | // 后级电路复位信号应当由它生成(见下) 97 | ); 98 | 99 | logic reset_of_clk10M; 100 | // 异步复位,同步释放,将 locked 信号转为后级电路的复位 reset_of_clk10M 101 | always_ff @(posedge clk_10M or negedge locked) begin 102 | if (~locked) reset_of_clk10M <= 1'b1; 103 | else reset_of_clk10M <= 1'b0; 104 | end 105 | 106 | /* =========== Demo code end =========== */ 107 | 108 | // TODO: 内部信号声明 109 | 110 | // TODO: 实验模块例化 111 | 112 | 113 | endmodule 114 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab4/lab4_top.sv: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | 3 | module lab4_top ( 4 | input wire clk_50M, // 50MHz 时钟输入 5 | input wire clk_11M0592, // 11.0592MHz 时钟输入(备用,可不用) 6 | 7 | input wire push_btn, // BTN5 按钮开关,带消抖电路,按下时为 1 8 | input wire reset_btn, // BTN6 复位按钮,带消抖电路,按下时为 1 9 | 10 | input wire [ 3:0] touch_btn, // BTN1~BTN4,按钮开关,按下时为 1 11 | input wire [31:0] dip_sw, // 32 位拨码开关,拨到“ON”时为 1 12 | output wire [15:0] leds, // 16 位 LED,输出时 1 点亮 13 | output wire [ 7:0] dpy0, // 数码管低位信号,包括小数点,输出 1 点亮 14 | output wire [ 7:0] dpy1, // 数码管高位信号,包括小数点,输出 1 点亮 15 | 16 | // CPLD 串口控制器信号 17 | output wire uart_rdn, // 读串口信号,低有效 18 | output wire uart_wrn, // 写串口信号,低有效 19 | input wire uart_dataready, // 串口数据准备好 20 | input wire uart_tbre, // 发送数据标志 21 | input wire uart_tsre, // 数据发送完毕标志 22 | 23 | // BaseRAM 信号 24 | inout wire [31:0] base_ram_data, // BaseRAM 数据,低 8 位与 CPLD 串口控制器共享 25 | output wire [19:0] base_ram_addr, // BaseRAM 地址 26 | output wire [3:0] base_ram_be_n, // BaseRAM 字节使能,低有效。如果不使用字节使能,请保持为 0 27 | output wire base_ram_ce_n, // BaseRAM 片选,低有效 28 | output wire base_ram_oe_n, // BaseRAM 读使能,低有效 29 | output wire base_ram_we_n, // BaseRAM 写使能,低有效 30 | 31 | // ExtRAM 信号 32 | inout wire [31:0] ext_ram_data, // ExtRAM 数据 33 | output wire [19:0] ext_ram_addr, // ExtRAM 地址 34 | output wire [3:0] ext_ram_be_n, // ExtRAM 字节使能,低有效。如果不使用字节使能,请保持为 0 35 | output wire ext_ram_ce_n, // ExtRAM 片选,低有效 36 | output wire ext_ram_oe_n, // ExtRAM 读使能,低有效 37 | output wire ext_ram_we_n, // ExtRAM 写使能,低有效 38 | 39 | // 直连串口信号 40 | output wire txd, // 直连串口发送端 41 | input wire rxd, // 直连串口接收端 42 | 43 | // Flash 存储器信号,参考 JS28F640 芯片手册 44 | output wire [22:0] flash_a, // Flash 地址,a0 仅在 8bit 模式有效,16bit 模式无意义 45 | inout wire [15:0] flash_d, // Flash 数据 46 | output wire flash_rp_n, // Flash 复位信号,低有效 47 | output wire flash_vpen, // Flash 写保护信号,低电平时不能擦除、烧写 48 | output wire flash_ce_n, // Flash 片选信号,低有效 49 | output wire flash_oe_n, // Flash 读使能信号,低有效 50 | output wire flash_we_n, // Flash 写使能信号,低有效 51 | output wire flash_byte_n, // Flash 8bit 模式选择,低有效。在使用 flash 的 16 位模式时请设为 1 52 | 53 | // USB 控制器信号,参考 SL811 芯片手册 54 | output wire sl811_a0, 55 | // inout wire [7:0] sl811_d, // USB 数据线与网络控制器的 dm9k_sd[7:0] 共享 56 | output wire sl811_wr_n, 57 | output wire sl811_rd_n, 58 | output wire sl811_cs_n, 59 | output wire sl811_rst_n, 60 | output wire sl811_dack_n, 61 | input wire sl811_intrq, 62 | input wire sl811_drq_n, 63 | 64 | // 网络控制器信号,参考 DM9000A 芯片手册 65 | output wire dm9k_cmd, 66 | inout wire [15:0] dm9k_sd, 67 | output wire dm9k_iow_n, 68 | output wire dm9k_ior_n, 69 | output wire dm9k_cs_n, 70 | output wire dm9k_pwrst_n, 71 | input wire dm9k_int, 72 | 73 | // 图像输出信号 74 | output wire [2:0] video_red, // 红色像素,3 位 75 | output wire [2:0] video_green, // 绿色像素,3 位 76 | output wire [1:0] video_blue, // 蓝色像素,2 位 77 | output wire video_hsync, // 行同步(水平同步)信号 78 | output wire video_vsync, // 场同步(垂直同步)信号 79 | output wire video_clk, // 像素时钟输出 80 | output wire video_de // 行数据有效信号,用于区分消隐区 81 | ); 82 | 83 | /* =========== Demo code begin =========== */ 84 | 85 | // PLL 分频示例 86 | logic locked, clk_10M, clk_20M; 87 | pll_example clock_gen ( 88 | // Clock in ports 89 | .clk_in1(clk_50M), // 外部时钟输入 90 | // Clock out ports 91 | .clk_out1(clk_10M), // 时钟输出 1,频率在 IP 配置界面中设置 92 | .clk_out2(clk_20M), // 时钟输出 2,频率在 IP 配置界面中设置 93 | // Status and control signals 94 | .reset(reset_btn), // PLL 复位输入 95 | .locked(locked) // PLL 锁定指示输出,"1"表示时钟稳定, 96 | // 后级电路复位信号应当由它生成(见下) 97 | ); 98 | 99 | logic reset_of_clk10M; 100 | // 异步复位,同步释放,将 locked 信号转为后级电路的复位 reset_of_clk10M 101 | always_ff @(posedge clk_10M or negedge locked) begin 102 | if (~locked) reset_of_clk10M <= 1'b1; 103 | else reset_of_clk10M <= 1'b0; 104 | end 105 | 106 | /* =========== Demo code end =========== */ 107 | 108 | logic sys_clk; 109 | logic sys_rst; 110 | 111 | assign sys_clk = clk_10M; 112 | assign sys_rst = reset_of_clk10M; 113 | 114 | // 本实验不使用 CPLD 串口,禁用防止总线冲突 115 | assign uart_rdn = 1'b1; 116 | assign uart_wrn = 1'b1; 117 | 118 | /* =========== Lab4 Master begin =========== */ 119 | // SRAM Tester (Master) => Wishbone MUX (Slave) 120 | logic wbm_cyc_o; 121 | logic wbm_stb_o; 122 | logic wbm_ack_i; 123 | logic [31:0] wbm_adr_o; 124 | logic [31:0] wbm_dat_o; 125 | logic [31:0] wbm_dat_i; 126 | logic [ 3:0] wbm_sel_o; 127 | logic wbm_we_o; 128 | 129 | // 测试控制信号 130 | logic test_start; 131 | logic [31:0] random_seed; 132 | 133 | assign test_start = push_btn; // 按钮开关开始测试 134 | assign random_seed = dip_sw; // 拨码开关输入随机数种子 135 | 136 | // 测试结果输出到 LED 137 | logic test_done, test_error; 138 | assign leds[0] = test_done; 139 | assign leds[1] = test_error; 140 | assign leds[15:2] = '0; 141 | 142 | // 详细结果信息,信号仅用于仿真查看,不连接外部硬件 143 | logic [31:0] test_error_round; // 数据错误轮次 144 | logic [31:0] test_error_addr; // 数据错误地址 145 | logic [31:0] test_error_read_data; // 错误地址读出的数据 146 | logic [31:0] test_error_expected_data; // 错误地址预期的数据 147 | 148 | sram_tester #( 149 | .ADDR_BASE(32'h8000_0000), 150 | .ADDR_MASK(32'h007F_FFFF) 151 | ) u_sram_tester ( 152 | .clk_i(sys_clk), 153 | .rst_i(sys_rst), 154 | 155 | // wishbone master 156 | .wb_cyc_o(wbm_cyc_o), 157 | .wb_stb_o(wbm_stb_o), 158 | .wb_ack_i(wbm_ack_i), 159 | .wb_adr_o(wbm_adr_o), 160 | .wb_dat_o(wbm_dat_o), 161 | .wb_dat_i(wbm_dat_i), 162 | .wb_sel_o(wbm_sel_o), 163 | .wb_we_o (wbm_we_o), 164 | 165 | // control input 166 | .start (test_start), 167 | .random_seed(random_seed), 168 | 169 | // status output 170 | .done (test_done), 171 | .error(test_error), 172 | 173 | // detailed status for simulation 174 | .error_round (test_error_round), 175 | .error_addr (test_error_addr), 176 | .error_read_data (test_error_read_data), 177 | .error_expected_data(test_error_expected_data) 178 | ); 179 | 180 | /* =========== Lab4 Master end =========== */ 181 | 182 | /* =========== Lab4 MUX begin =========== */ 183 | // Wishbone MUX (Masters) => SRAM controllers 184 | logic wbs0_cyc_o; 185 | logic wbs0_stb_o; 186 | logic wbs0_ack_i; 187 | logic [31:0] wbs0_adr_o; 188 | logic [31:0] wbs0_dat_o; 189 | logic [31:0] wbs0_dat_i; 190 | logic [3:0] wbs0_sel_o; 191 | logic wbs0_we_o; 192 | 193 | logic wbs1_cyc_o; 194 | logic wbs1_stb_o; 195 | logic wbs1_ack_i; 196 | logic [31:0] wbs1_adr_o; 197 | logic [31:0] wbs1_dat_o; 198 | logic [31:0] wbs1_dat_i; 199 | logic [3:0] wbs1_sel_o; 200 | logic wbs1_we_o; 201 | 202 | wb_mux_2 wb_mux ( 203 | .clk(sys_clk), 204 | .rst(sys_rst), 205 | 206 | // Master interface (to SRAM Tester) 207 | .wbm_adr_i(wbm_adr_o), 208 | .wbm_dat_i(wbm_dat_o), 209 | .wbm_dat_o(wbm_dat_i), 210 | .wbm_we_i (wbm_we_o), 211 | .wbm_sel_i(wbm_sel_o), 212 | .wbm_stb_i(wbm_stb_o), 213 | .wbm_ack_o(wbm_ack_i), 214 | .wbm_err_o(), 215 | .wbm_rty_o(), 216 | .wbm_cyc_i(wbm_cyc_o), 217 | 218 | // Slave interface 0 (to BaseRAM controller) 219 | // Address range: 0x8000_0000 ~ 0x803F_FFFF 220 | .wbs0_addr (32'h8000_0000), 221 | .wbs0_addr_msk(32'hFFC0_0000), 222 | 223 | .wbs0_adr_o(wbs0_adr_o), 224 | .wbs0_dat_i(wbs0_dat_i), 225 | .wbs0_dat_o(wbs0_dat_o), 226 | .wbs0_we_o (wbs0_we_o), 227 | .wbs0_sel_o(wbs0_sel_o), 228 | .wbs0_stb_o(wbs0_stb_o), 229 | .wbs0_ack_i(wbs0_ack_i), 230 | .wbs0_err_i('0), 231 | .wbs0_rty_i('0), 232 | .wbs0_cyc_o(wbs0_cyc_o), 233 | 234 | // Slave interface 1 (to ExtRAM controller) 235 | // Address range: 0x8040_0000 ~ 0x807F_FFFF 236 | .wbs1_addr (32'h8040_0000), 237 | .wbs1_addr_msk(32'hFFC0_0000), 238 | 239 | .wbs1_adr_o(wbs1_adr_o), 240 | .wbs1_dat_i(wbs1_dat_i), 241 | .wbs1_dat_o(wbs1_dat_o), 242 | .wbs1_we_o (wbs1_we_o), 243 | .wbs1_sel_o(wbs1_sel_o), 244 | .wbs1_stb_o(wbs1_stb_o), 245 | .wbs1_ack_i(wbs1_ack_i), 246 | .wbs1_err_i('0), 247 | .wbs1_rty_i('0), 248 | .wbs1_cyc_o(wbs1_cyc_o) 249 | ); 250 | 251 | /* =========== Lab4 MUX end =========== */ 252 | 253 | /* =========== Lab4 Slaves begin =========== */ 254 | sram_controller #( 255 | .SRAM_ADDR_WIDTH(20), 256 | .SRAM_DATA_WIDTH(32) 257 | ) sram_controller_base ( 258 | .clk_i (sys_clk), 259 | .rst_i (sys_rst), 260 | 261 | // Wishbone slave (to MUX) 262 | .wb_cyc_i (wbs0_cyc_o), 263 | .wb_stb_i (wbs0_stb_o), 264 | .wb_ack_o (wbs0_ack_i), 265 | .wb_adr_i (wbs0_adr_o), 266 | .wb_dat_i (wbs0_dat_o), 267 | .wb_dat_o (wbs0_dat_i), 268 | .wb_sel_i (wbs0_sel_o), 269 | .wb_we_i (wbs0_we_o), 270 | 271 | // To SRAM chip 272 | .sram_addr(base_ram_addr), 273 | .sram_data(base_ram_data), 274 | .sram_ce_n(base_ram_ce_n), 275 | .sram_oe_n(base_ram_oe_n), 276 | .sram_we_n(base_ram_we_n), 277 | .sram_be_n(base_ram_be_n) 278 | ); 279 | 280 | sram_controller #( 281 | .SRAM_ADDR_WIDTH(20), 282 | .SRAM_DATA_WIDTH(32) 283 | ) sram_controller_ext ( 284 | .clk_i (sys_clk), 285 | .rst_i (sys_rst), 286 | 287 | // Wishbone slave (to MUX) 288 | .wb_cyc_i (wbs1_cyc_o), 289 | .wb_stb_i (wbs1_stb_o), 290 | .wb_ack_o (wbs1_ack_i), 291 | .wb_adr_i (wbs1_adr_o), 292 | .wb_dat_i (wbs1_dat_o), 293 | .wb_dat_o (wbs1_dat_i), 294 | .wb_sel_i (wbs1_sel_o), 295 | .wb_we_i (wbs1_we_o), 296 | 297 | // To SRAM chip 298 | .sram_addr(ext_ram_addr), 299 | .sram_data(ext_ram_data), 300 | .sram_ce_n(ext_ram_ce_n), 301 | .sram_oe_n(ext_ram_oe_n), 302 | .sram_we_n(ext_ram_we_n), 303 | .sram_be_n(ext_ram_be_n) 304 | ); 305 | /* =========== Lab4 Slaves end =========== */ 306 | 307 | endmodule 308 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab4/sram_controller.sv: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | 3 | module sram_controller #( 4 | parameter DATA_WIDTH = 32, 5 | parameter ADDR_WIDTH = 32, 6 | 7 | parameter SRAM_ADDR_WIDTH = 20, 8 | parameter SRAM_DATA_WIDTH = 32, 9 | 10 | localparam SRAM_BYTES = SRAM_DATA_WIDTH / 8, 11 | localparam SRAM_BYTE_WIDTH = $clog2(SRAM_BYTES) 12 | ) ( 13 | // clk and reset 14 | input wire clk_i, 15 | input wire rst_i, 16 | 17 | // wishbone slave interface 18 | input wire wb_cyc_i, 19 | input wire wb_stb_i, 20 | output reg wb_ack_o, 21 | input wire [ADDR_WIDTH-1:0] wb_adr_i, 22 | input wire [DATA_WIDTH-1:0] wb_dat_i, 23 | output reg [DATA_WIDTH-1:0] wb_dat_o, 24 | input wire [DATA_WIDTH/8-1:0] wb_sel_i, 25 | input wire wb_we_i, 26 | 27 | // sram interface 28 | output reg [SRAM_ADDR_WIDTH-1:0] sram_addr, 29 | inout wire [SRAM_DATA_WIDTH-1:0] sram_data, 30 | output reg sram_ce_n, 31 | output reg sram_oe_n, 32 | output reg sram_we_n, 33 | output reg [SRAM_BYTES-1:0] sram_be_n 34 | ); 35 | 36 | typedef enum logic [3:0]{ 37 | IDLE, 38 | READ1, 39 | WRITE1, 40 | WRITE2 41 | } controller_state_t; 42 | controller_state_t state, nxt_state; 43 | 44 | 45 | // check whether data comes in 46 | wire data_in; 47 | assign data_in = wb_cyc_i & wb_stb_i; 48 | 49 | 50 | // flip-flop 51 | always_ff @ (posedge clk_i) begin 52 | if (rst_i) begin 53 | state <= IDLE; 54 | end else begin 55 | state <= nxt_state; 56 | end 57 | end 58 | 59 | // state trans 60 | always_comb begin 61 | nxt_state = state; 62 | 63 | case (state) 64 | IDLE: begin 65 | if (data_in) begin 66 | if (wb_we_i) nxt_state = WRITE1; 67 | else nxt_state = READ1; 68 | end 69 | end 70 | READ1: nxt_state = IDLE; 71 | WRITE1: nxt_state = WRITE2; 72 | WRITE2: nxt_state = IDLE; 73 | default: nxt_state = IDLE; 74 | endcase // case (state) 75 | end // always_comb 76 | 77 | // sram tri-state config 78 | // using lab's doc approach 79 | 80 | logic [SRAM_DATA_WIDTH-1:0] sram_i; 81 | logic [SRAM_DATA_WIDTH-1:0] sram_o; 82 | logic sram_writing; 83 | 84 | 85 | // we_n ? disable : enable 86 | 87 | assign sram_data = sram_writing ? sram_o : {SRAM_DATA_WIDTH{1'bz}} ; 88 | assign sram_i = sram_data; 89 | 90 | 91 | // output item 92 | always_comb begin 93 | wb_ack_o = 1'b0; 94 | wb_dat_o = {DATA_WIDTH{1'b0}}; 95 | sram_oe_n = 1'b1; 96 | sram_we_n = 1'b1; 97 | sram_ce_n = 1'b1; 98 | sram_writing = 1'b0; 99 | 100 | sram_o = wb_dat_i; // for convience 101 | sram_addr = wb_adr_i[SRAM_ADDR_WIDTH+1:2]; // for convience 102 | sram_be_n = ~wb_sel_i; // for convience 103 | 104 | case (state) 105 | IDLE: begin 106 | if (data_in) begin 107 | if (wb_we_i) begin // WRITE0 108 | sram_writing = 1'b1; 109 | sram_ce_n = 1'b0; 110 | end else begin // READ0 111 | sram_oe_n = 1'b0; 112 | sram_ce_n = 1'b0; 113 | end 114 | end 115 | end // case: IDLE 116 | READ1: begin 117 | sram_oe_n = 1'b0; 118 | sram_ce_n = 1'b0; 119 | wb_ack_o = 1'b1; 120 | wb_dat_o = sram_i; 121 | end 122 | WRITE1: begin 123 | sram_writing = 1'b1; 124 | sram_we_n = 1'b0; 125 | sram_ce_n = 1'b0; 126 | end 127 | WRITE2: begin 128 | sram_writing = 1'b1; 129 | sram_ce_n = 1'b0; 130 | wb_ack_o = 1'b1; 131 | end 132 | endcase // case (state) 133 | end // always_comb 134 | 135 | endmodule 136 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab4/sram_tester.sv: -------------------------------------------------------------------------------- 1 | module sram_tester #( 2 | parameter ADDR_WIDTH = 32, 3 | parameter DATA_WIDTH = 32, 4 | 5 | parameter ADDR_BASE = 32'h8000_0000, 6 | parameter ADDR_MASK = 32'h007F_FFFF, 7 | parameter TEST_ROUNDS = 1000 8 | ) ( 9 | input wire clk_i, 10 | input wire rst_i, 11 | 12 | input wire start, 13 | input wire [31:0] random_seed, 14 | 15 | // wishbone master 16 | output reg wb_cyc_o, 17 | output reg wb_stb_o, 18 | input wire wb_ack_i, 19 | output reg [ADDR_WIDTH-1:0] wb_adr_o, 20 | output reg [DATA_WIDTH-1:0] wb_dat_o, 21 | input wire [DATA_WIDTH-1:0] wb_dat_i, 22 | output reg [DATA_WIDTH/8-1:0] wb_sel_o, 23 | output reg wb_we_o, 24 | 25 | // status signals 26 | output reg done, 27 | output reg error, 28 | output reg [31:0] error_round, 29 | output reg [ADDR_WIDTH-1:0] error_addr, 30 | output reg [DATA_WIDTH-1:0] error_read_data, 31 | output reg [DATA_WIDTH-1:0] error_expected_data 32 | ); 33 | 34 | localparam RAM_ADDR_WIDTH = $clog2(ADDR_MASK); // ceil to correct bits 35 | localparam ADDR_ZEROS = ADDR_WIDTH - RAM_ADDR_WIDTH; 36 | 37 | typedef enum logic [3:0] { 38 | ST_IDLE, 39 | 40 | ST_WRITE, 41 | ST_WRITE_ACTION, 42 | 43 | ST_READ, 44 | ST_READ_ACTION, 45 | 46 | ST_ERROR, 47 | ST_DONE 48 | } state_t; 49 | 50 | logic [31:0] count; 51 | logic [DATA_WIDTH-1:0] data_expected; 52 | logic [DATA_WIDTH-1:0] data_mask; // mask out rng for write 53 | logic [DATA_WIDTH/8-1:0] read_compare; // byte read compare result 54 | 55 | state_t state, state_n; 56 | 57 | always_comb begin 58 | state_n = state; 59 | case (state) 60 | ST_IDLE: begin 61 | // start test sequence 62 | if (start) state_n = ST_WRITE; 63 | end 64 | 65 | ST_WRITE: begin 66 | if (count == TEST_ROUNDS) state_n = ST_READ; 67 | else state_n = ST_WRITE_ACTION; 68 | end 69 | 70 | ST_WRITE_ACTION: begin 71 | // wait for ack 72 | if (wb_ack_i) state_n = ST_WRITE; 73 | end 74 | 75 | ST_READ: begin 76 | if (count == TEST_ROUNDS) state_n = ST_DONE; 77 | else state_n = ST_READ_ACTION; 78 | end 79 | 80 | ST_READ_ACTION: begin 81 | if (wb_ack_i) begin 82 | if (!(&read_compare)) state_n = ST_ERROR; 83 | else state_n = ST_READ; 84 | end 85 | end 86 | 87 | ST_ERROR: begin 88 | state_n = ST_ERROR; 89 | end 90 | 91 | ST_DONE: begin 92 | state_n = ST_DONE; 93 | end 94 | 95 | default: begin 96 | state_n = ST_IDLE; 97 | end 98 | endcase 99 | end 100 | 101 | always_ff @(posedge clk_i or posedge rst_i) begin 102 | if (rst_i) begin 103 | state <= ST_IDLE; 104 | end else begin 105 | state <= state_n; 106 | end 107 | end 108 | 109 | // test cycle counting 110 | always_ff @(posedge clk_i or posedge rst_i) begin 111 | if (rst_i) begin 112 | count <= '0; 113 | end else if (state == ST_WRITE || state == ST_READ) begin 114 | count <= count + 'd1; 115 | if (count == TEST_ROUNDS) begin 116 | count <= '0; 117 | end 118 | end 119 | end 120 | 121 | // rng control 122 | logic rng_load; 123 | always_comb begin 124 | rng_load = 0; 125 | case (state) 126 | ST_IDLE: begin 127 | if (start) rng_load = 1; 128 | end 129 | 130 | ST_WRITE: begin 131 | if (count == TEST_ROUNDS) rng_load = 1; 132 | end 133 | 134 | default: rng_load = 0; 135 | endcase 136 | end 137 | 138 | logic rng_enable; 139 | always_comb begin 140 | rng_enable = (state == ST_WRITE) || (state == ST_READ); 141 | end 142 | 143 | // address prng 144 | logic [RAM_ADDR_WIDTH-1:0] rng_addr; 145 | lfsr_prng #( 146 | .DATA_WIDTH(RAM_ADDR_WIDTH), 147 | .INVERT (0) 148 | ) u_prng_addr ( 149 | .clk (clk_i), 150 | .load(rng_load), 151 | .seed(random_seed | 32'h1), 152 | 153 | .enable (rng_enable), 154 | .data_out(rng_addr) 155 | ); 156 | 157 | // data prng 158 | logic [DATA_WIDTH-1:0] rng_data; 159 | lfsr_prng #( 160 | .DATA_WIDTH(DATA_WIDTH), 161 | .INVERT (0) 162 | ) u_prng_data ( 163 | .clk (clk_i), 164 | .load(rng_load), 165 | .seed(random_seed | 32'h1), 166 | 167 | .enable (rng_enable), 168 | .data_out(rng_data) 169 | ); 170 | 171 | // address and data output 172 | always_comb begin 173 | wb_adr_o = '0; 174 | wb_dat_o = '0; 175 | data_expected = '0; 176 | 177 | case (state) 178 | ST_WRITE, ST_WRITE_ACTION: begin 179 | wb_adr_o = ADDR_BASE | {{ADDR_ZEROS{1'b0}}, rng_addr}; 180 | wb_dat_o = rng_data & data_mask; 181 | end 182 | 183 | ST_READ, ST_READ_ACTION: begin 184 | wb_adr_o = ADDR_BASE | {{ADDR_ZEROS{1'b0}}, rng_addr}; 185 | data_expected = rng_data & data_mask; 186 | end 187 | 188 | default: begin 189 | wb_adr_o = '0; 190 | wb_dat_o = '0; 191 | data_expected = '0; 192 | end 193 | endcase 194 | end 195 | 196 | // data mask 197 | genvar i; 198 | for (i = 0; i < DATA_WIDTH / 8; i = i + 1) begin : gen_compare 199 | assign data_mask[i*8+:8] = wb_sel_o[i] ? 8'hFF : 8'h00; 200 | assign read_compare[i] = ~wb_sel_o[i] ? 1'b1 : (wb_dat_i[i*8+:8] == data_expected[i*8+:8]); 201 | end 202 | 203 | // wishbone bus 204 | assign wb_cyc_o = wb_stb_o; 205 | 206 | always_comb begin 207 | wb_we_o = (state == ST_WRITE_ACTION); 208 | wb_stb_o = (state == ST_READ_ACTION || state == ST_WRITE_ACTION); 209 | end 210 | 211 | always_comb begin 212 | case (wb_adr_o[1:0]) 213 | 2'b00: wb_sel_o = 4'b1111; // full word 214 | 2'b10: wb_sel_o = 4'b1100; // half word 215 | 2'b01: wb_sel_o = 4'b0010; // byte 216 | 2'b11: wb_sel_o = 4'b1000; // byte 217 | endcase 218 | end 219 | 220 | // status output 221 | always_ff @(posedge clk_i or posedge rst_i) begin 222 | if (rst_i) begin 223 | done <= 0; 224 | error <= 0; 225 | 226 | error_round <= '0; 227 | error_addr <= '0; 228 | error_read_data <= '0; 229 | error_expected_data <= '0; 230 | end else begin 231 | case (state) 232 | ST_DONE: begin 233 | done <= 1; 234 | error <= 0; 235 | end 236 | 237 | ST_ERROR: begin 238 | done <= 0; 239 | error <= 1; 240 | 241 | error_round <= count; 242 | error_addr <= wb_adr_o; 243 | error_read_data <= wb_dat_i; 244 | error_expected_data <= data_expected; 245 | end 246 | 247 | default: begin 248 | done <= 0; 249 | error <= 0; 250 | end 251 | endcase 252 | end 253 | end 254 | 255 | endmodule 256 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab4/wb_mux_2.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2015-2016 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Wishbone 2 port multiplexer 31 | */ 32 | module wb_mux_2 # 33 | ( 34 | parameter DATA_WIDTH = 32, // width of data bus in bits (8, 16, 32, or 64) 35 | parameter ADDR_WIDTH = 32, // width of address bus in bits 36 | parameter SELECT_WIDTH = (DATA_WIDTH/8) // width of word select bus (1, 2, 4, or 8) 37 | ) 38 | ( 39 | input wire clk, 40 | input wire rst, 41 | 42 | /* 43 | * Wishbone master input 44 | */ 45 | input wire [ADDR_WIDTH-1:0] wbm_adr_i, // ADR_I() address input 46 | input wire [DATA_WIDTH-1:0] wbm_dat_i, // DAT_I() data in 47 | output wire [DATA_WIDTH-1:0] wbm_dat_o, // DAT_O() data out 48 | input wire wbm_we_i, // WE_I write enable input 49 | input wire [SELECT_WIDTH-1:0] wbm_sel_i, // SEL_I() select input 50 | input wire wbm_stb_i, // STB_I strobe input 51 | output wire wbm_ack_o, // ACK_O acknowledge output 52 | output wire wbm_err_o, // ERR_O error output 53 | output wire wbm_rty_o, // RTY_O retry output 54 | input wire wbm_cyc_i, // CYC_I cycle input 55 | 56 | /* 57 | * Wishbone slave 0 output 58 | */ 59 | output wire [ADDR_WIDTH-1:0] wbs0_adr_o, // ADR_O() address output 60 | input wire [DATA_WIDTH-1:0] wbs0_dat_i, // DAT_I() data in 61 | output wire [DATA_WIDTH-1:0] wbs0_dat_o, // DAT_O() data out 62 | output wire wbs0_we_o, // WE_O write enable output 63 | output wire [SELECT_WIDTH-1:0] wbs0_sel_o, // SEL_O() select output 64 | output wire wbs0_stb_o, // STB_O strobe output 65 | input wire wbs0_ack_i, // ACK_I acknowledge input 66 | input wire wbs0_err_i, // ERR_I error input 67 | input wire wbs0_rty_i, // RTY_I retry input 68 | output wire wbs0_cyc_o, // CYC_O cycle output 69 | 70 | /* 71 | * Wishbone slave 0 address configuration 72 | */ 73 | input wire [ADDR_WIDTH-1:0] wbs0_addr, // Slave address prefix 74 | input wire [ADDR_WIDTH-1:0] wbs0_addr_msk, // Slave address prefix mask 75 | 76 | /* 77 | * Wishbone slave 1 output 78 | */ 79 | output wire [ADDR_WIDTH-1:0] wbs1_adr_o, // ADR_O() address output 80 | input wire [DATA_WIDTH-1:0] wbs1_dat_i, // DAT_I() data in 81 | output wire [DATA_WIDTH-1:0] wbs1_dat_o, // DAT_O() data out 82 | output wire wbs1_we_o, // WE_O write enable output 83 | output wire [SELECT_WIDTH-1:0] wbs1_sel_o, // SEL_O() select output 84 | output wire wbs1_stb_o, // STB_O strobe output 85 | input wire wbs1_ack_i, // ACK_I acknowledge input 86 | input wire wbs1_err_i, // ERR_I error input 87 | input wire wbs1_rty_i, // RTY_I retry input 88 | output wire wbs1_cyc_o, // CYC_O cycle output 89 | 90 | /* 91 | * Wishbone slave 1 address configuration 92 | */ 93 | input wire [ADDR_WIDTH-1:0] wbs1_addr, // Slave address prefix 94 | input wire [ADDR_WIDTH-1:0] wbs1_addr_msk // Slave address prefix mask 95 | ); 96 | 97 | wire wbs0_match = ~|((wbm_adr_i ^ wbs0_addr) & wbs0_addr_msk); 98 | wire wbs1_match = ~|((wbm_adr_i ^ wbs1_addr) & wbs1_addr_msk); 99 | 100 | wire wbs0_sel = wbs0_match; 101 | wire wbs1_sel = wbs1_match & ~(wbs0_match); 102 | 103 | wire master_cycle = wbm_cyc_i & wbm_stb_i; 104 | 105 | wire select_error = ~(wbs0_sel | wbs1_sel) & master_cycle; 106 | 107 | // master 108 | assign wbm_dat_o = wbs0_sel ? wbs0_dat_i : 109 | wbs1_sel ? wbs1_dat_i : 110 | {DATA_WIDTH{1'b0}}; 111 | 112 | assign wbm_ack_o = wbs0_ack_i | 113 | wbs1_ack_i; 114 | 115 | assign wbm_err_o = wbs0_err_i | 116 | wbs1_err_i | 117 | select_error; 118 | 119 | assign wbm_rty_o = wbs0_rty_i | 120 | wbs1_rty_i; 121 | 122 | // slave 0 123 | assign wbs0_adr_o = wbm_adr_i; 124 | assign wbs0_dat_o = wbm_dat_i; 125 | assign wbs0_we_o = wbm_we_i & wbs0_sel; 126 | assign wbs0_sel_o = wbm_sel_i; 127 | assign wbs0_stb_o = wbm_stb_i & wbs0_sel; 128 | assign wbs0_cyc_o = wbm_cyc_i & wbs0_sel; 129 | 130 | // slave 1 131 | assign wbs1_adr_o = wbm_adr_i; 132 | assign wbs1_dat_o = wbm_dat_i; 133 | assign wbs1_we_o = wbm_we_i & wbs1_sel; 134 | assign wbs1_sel_o = wbm_sel_i; 135 | assign wbs1_stb_o = wbm_stb_i & wbs1_sel; 136 | assign wbs1_cyc_o = wbm_cyc_i & wbs1_sel; 137 | 138 | 139 | endmodule 140 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab5/lab5_master.sv: -------------------------------------------------------------------------------- 1 | module lab5_master #( 2 | parameter ADDR_WIDTH = 32, 3 | parameter DATA_WIDTH = 32 4 | ) ( 5 | input wire clk_i, 6 | input wire rst_i, 7 | 8 | // TODO: 添加需要的控制信号,例如按键开关? 9 | 10 | // wishbone master 11 | output reg wb_cyc_o, 12 | output reg wb_stb_o, 13 | input wire wb_ack_i, 14 | output reg [ADDR_WIDTH-1:0] wb_adr_o, 15 | output reg [DATA_WIDTH-1:0] wb_dat_o, 16 | input wire [DATA_WIDTH-1:0] wb_dat_i, 17 | output reg [DATA_WIDTH/8-1:0] wb_sel_o, 18 | output reg wb_we_o 19 | ); 20 | 21 | // TODO: 实现实验 5 的内存+串口 Master 22 | 23 | endmodule 24 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab5/uart_controller.sv: -------------------------------------------------------------------------------- 1 | module uart_controller #( 2 | parameter ADDR_WIDTH = 32, 3 | parameter DATA_WIDTH = 32, 4 | 5 | parameter CLK_FREQ = 50_000_000, 6 | parameter BAUD = 115200 7 | ) ( 8 | // clk and reset 9 | input wire clk_i, 10 | input wire rst_i, 11 | 12 | // wishbone slave interface 13 | input wire wb_cyc_i, 14 | input wire wb_stb_i, 15 | output reg wb_ack_o, 16 | input wire [ADDR_WIDTH-1:0] wb_adr_i, 17 | input wire [DATA_WIDTH-1:0] wb_dat_i, 18 | output reg [DATA_WIDTH-1:0] wb_dat_o, 19 | input wire [DATA_WIDTH/8-1:0] wb_sel_i, 20 | input wire wb_we_i, 21 | 22 | // uart interface 23 | output reg uart_txd_o, 24 | input wire uart_rxd_i 25 | ); 26 | 27 | localparam REG_DATA = 8'h00; 28 | localparam REG_STATUS = 8'h05; 29 | 30 | // uart transmitter 31 | logic txd_start; 32 | logic txd_busy; 33 | logic [7:0] txd_data; 34 | 35 | async_transmitter #( 36 | .ClkFrequency(CLK_FREQ), 37 | .Baud (BAUD) 38 | ) u_async_transmitter ( 39 | .clk (clk_i), 40 | .TxD_start(txd_start), 41 | .TxD_data (txd_data), 42 | .TxD (uart_txd_o), 43 | .TxD_busy (txd_busy) 44 | ); 45 | 46 | // uart receiver 47 | logic rxd_data_ready; 48 | logic [7:0] rxd_data; 49 | logic rxd_clear; 50 | 51 | async_receiver #( 52 | .ClkFrequency(CLK_FREQ), 53 | .Baud (BAUD) 54 | ) u_async_receiver ( 55 | .clk (clk_i), 56 | .RxD (uart_rxd_i), 57 | .RxD_data_ready(rxd_data_ready), 58 | .RxD_clear (rxd_clear), 59 | .RxD_data (rxd_data) 60 | ); 61 | 62 | /*-- internal registers --*/ 63 | wire [7:0] reg_status = {2'b0, ~txd_busy, 4'b0, rxd_data_ready}; 64 | 65 | /*-- wishbone fsm --*/ 66 | always_ff @(posedge clk_i) begin 67 | if (rst_i) 68 | wb_ack_o <= 0; 69 | else 70 | // every request get ACK-ed immediately 71 | if (wb_ack_o) begin 72 | wb_ack_o <= 0; 73 | end else begin 74 | wb_ack_o <= wb_stb_i; 75 | end 76 | end 77 | 78 | // write logic 79 | always_ff @(posedge clk_i) begin 80 | if (rst_i) begin 81 | txd_start <= 0; 82 | end else if(wb_stb_i && wb_we_i) begin 83 | case (wb_adr_i[7:0]) 84 | REG_DATA: begin 85 | if(wb_sel_i[0]) begin 86 | txd_data <= wb_dat_i[7:0]; 87 | txd_start <= 1; 88 | end 89 | end 90 | 91 | default: ; // do nothing 92 | endcase 93 | end else begin 94 | txd_start <= 0; 95 | end 96 | end 97 | 98 | // read logic 99 | always_ff @(posedge clk_i) begin 100 | if(rst_i) begin 101 | rxd_clear <= 1; // clear rxd to initialize dataready 102 | end else if(wb_stb_i && !wb_we_i) begin 103 | case (wb_adr_i[7:0]) 104 | REG_DATA: begin 105 | if (wb_sel_i[0]) wb_dat_o[7:0] <= rxd_data; 106 | if (wb_sel_i[1]) wb_dat_o[15:8] <= rxd_data; 107 | if (wb_sel_i[2]) wb_dat_o[23:16] <= rxd_data; 108 | if (wb_sel_i[3]) wb_dat_o[31:24] <= rxd_data; 109 | 110 | rxd_clear <= 1; 111 | end 112 | 113 | REG_STATUS: begin 114 | if (wb_sel_i[0]) wb_dat_o[7:0] <= reg_status; 115 | if (wb_sel_i[1]) wb_dat_o[15:8] <= reg_status; 116 | if (wb_sel_i[2]) wb_dat_o[23:16] <= reg_status; 117 | if (wb_sel_i[3]) wb_dat_o[31:24] <= reg_status; 118 | end 119 | 120 | default: ; // do nothing 121 | endcase 122 | end else begin 123 | rxd_clear <= 0; 124 | end 125 | end 126 | 127 | endmodule 128 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab5/wb_mux_3.v: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2015-2016 Alex Forencich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | */ 24 | 25 | // Language: Verilog 2001 26 | 27 | `timescale 1 ns / 1 ps 28 | 29 | /* 30 | * Wishbone 3 port multiplexer 31 | */ 32 | module wb_mux_3 # 33 | ( 34 | parameter DATA_WIDTH = 32, // width of data bus in bits (8, 16, 32, or 64) 35 | parameter ADDR_WIDTH = 32, // width of address bus in bits 36 | parameter SELECT_WIDTH = (DATA_WIDTH/8) // width of word select bus (1, 2, 4, or 8) 37 | ) 38 | ( 39 | input wire clk, 40 | input wire rst, 41 | 42 | /* 43 | * Wishbone master input 44 | */ 45 | input wire [ADDR_WIDTH-1:0] wbm_adr_i, // ADR_I() address input 46 | input wire [DATA_WIDTH-1:0] wbm_dat_i, // DAT_I() data in 47 | output wire [DATA_WIDTH-1:0] wbm_dat_o, // DAT_O() data out 48 | input wire wbm_we_i, // WE_I write enable input 49 | input wire [SELECT_WIDTH-1:0] wbm_sel_i, // SEL_I() select input 50 | input wire wbm_stb_i, // STB_I strobe input 51 | output wire wbm_ack_o, // ACK_O acknowledge output 52 | output wire wbm_err_o, // ERR_O error output 53 | output wire wbm_rty_o, // RTY_O retry output 54 | input wire wbm_cyc_i, // CYC_I cycle input 55 | 56 | /* 57 | * Wishbone slave 0 output 58 | */ 59 | output wire [ADDR_WIDTH-1:0] wbs0_adr_o, // ADR_O() address output 60 | input wire [DATA_WIDTH-1:0] wbs0_dat_i, // DAT_I() data in 61 | output wire [DATA_WIDTH-1:0] wbs0_dat_o, // DAT_O() data out 62 | output wire wbs0_we_o, // WE_O write enable output 63 | output wire [SELECT_WIDTH-1:0] wbs0_sel_o, // SEL_O() select output 64 | output wire wbs0_stb_o, // STB_O strobe output 65 | input wire wbs0_ack_i, // ACK_I acknowledge input 66 | input wire wbs0_err_i, // ERR_I error input 67 | input wire wbs0_rty_i, // RTY_I retry input 68 | output wire wbs0_cyc_o, // CYC_O cycle output 69 | 70 | /* 71 | * Wishbone slave 0 address configuration 72 | */ 73 | input wire [ADDR_WIDTH-1:0] wbs0_addr, // Slave address prefix 74 | input wire [ADDR_WIDTH-1:0] wbs0_addr_msk, // Slave address prefix mask 75 | 76 | /* 77 | * Wishbone slave 1 output 78 | */ 79 | output wire [ADDR_WIDTH-1:0] wbs1_adr_o, // ADR_O() address output 80 | input wire [DATA_WIDTH-1:0] wbs1_dat_i, // DAT_I() data in 81 | output wire [DATA_WIDTH-1:0] wbs1_dat_o, // DAT_O() data out 82 | output wire wbs1_we_o, // WE_O write enable output 83 | output wire [SELECT_WIDTH-1:0] wbs1_sel_o, // SEL_O() select output 84 | output wire wbs1_stb_o, // STB_O strobe output 85 | input wire wbs1_ack_i, // ACK_I acknowledge input 86 | input wire wbs1_err_i, // ERR_I error input 87 | input wire wbs1_rty_i, // RTY_I retry input 88 | output wire wbs1_cyc_o, // CYC_O cycle output 89 | 90 | /* 91 | * Wishbone slave 1 address configuration 92 | */ 93 | input wire [ADDR_WIDTH-1:0] wbs1_addr, // Slave address prefix 94 | input wire [ADDR_WIDTH-1:0] wbs1_addr_msk, // Slave address prefix mask 95 | 96 | /* 97 | * Wishbone slave 2 output 98 | */ 99 | output wire [ADDR_WIDTH-1:0] wbs2_adr_o, // ADR_O() address output 100 | input wire [DATA_WIDTH-1:0] wbs2_dat_i, // DAT_I() data in 101 | output wire [DATA_WIDTH-1:0] wbs2_dat_o, // DAT_O() data out 102 | output wire wbs2_we_o, // WE_O write enable output 103 | output wire [SELECT_WIDTH-1:0] wbs2_sel_o, // SEL_O() select output 104 | output wire wbs2_stb_o, // STB_O strobe output 105 | input wire wbs2_ack_i, // ACK_I acknowledge input 106 | input wire wbs2_err_i, // ERR_I error input 107 | input wire wbs2_rty_i, // RTY_I retry input 108 | output wire wbs2_cyc_o, // CYC_O cycle output 109 | 110 | /* 111 | * Wishbone slave 2 address configuration 112 | */ 113 | input wire [ADDR_WIDTH-1:0] wbs2_addr, // Slave address prefix 114 | input wire [ADDR_WIDTH-1:0] wbs2_addr_msk // Slave address prefix mask 115 | ); 116 | 117 | wire wbs0_match = ~|((wbm_adr_i ^ wbs0_addr) & wbs0_addr_msk); 118 | wire wbs1_match = ~|((wbm_adr_i ^ wbs1_addr) & wbs1_addr_msk); 119 | wire wbs2_match = ~|((wbm_adr_i ^ wbs2_addr) & wbs2_addr_msk); 120 | 121 | wire wbs0_sel = wbs0_match; 122 | wire wbs1_sel = wbs1_match & ~(wbs0_match); 123 | wire wbs2_sel = wbs2_match & ~(wbs0_match | wbs1_match); 124 | 125 | wire master_cycle = wbm_cyc_i & wbm_stb_i; 126 | 127 | wire select_error = ~(wbs0_sel | wbs1_sel | wbs2_sel) & master_cycle; 128 | 129 | // master 130 | assign wbm_dat_o = wbs0_sel ? wbs0_dat_i : 131 | wbs1_sel ? wbs1_dat_i : 132 | wbs2_sel ? wbs2_dat_i : 133 | {DATA_WIDTH{1'b0}}; 134 | 135 | assign wbm_ack_o = wbs0_ack_i | 136 | wbs1_ack_i | 137 | wbs2_ack_i; 138 | 139 | assign wbm_err_o = wbs0_err_i | 140 | wbs1_err_i | 141 | wbs2_err_i | 142 | select_error; 143 | 144 | assign wbm_rty_o = wbs0_rty_i | 145 | wbs1_rty_i | 146 | wbs2_rty_i; 147 | 148 | // slave 0 149 | assign wbs0_adr_o = wbm_adr_i; 150 | assign wbs0_dat_o = wbm_dat_i; 151 | assign wbs0_we_o = wbm_we_i & wbs0_sel; 152 | assign wbs0_sel_o = wbm_sel_i; 153 | assign wbs0_stb_o = wbm_stb_i & wbs0_sel; 154 | assign wbs0_cyc_o = wbm_cyc_i & wbs0_sel; 155 | 156 | // slave 1 157 | assign wbs1_adr_o = wbm_adr_i; 158 | assign wbs1_dat_o = wbm_dat_i; 159 | assign wbs1_we_o = wbm_we_i & wbs1_sel; 160 | assign wbs1_sel_o = wbm_sel_i; 161 | assign wbs1_stb_o = wbm_stb_i & wbs1_sel; 162 | assign wbs1_cyc_o = wbm_cyc_i & wbs1_sel; 163 | 164 | // slave 2 165 | assign wbs2_adr_o = wbm_adr_i; 166 | assign wbs2_dat_o = wbm_dat_i; 167 | assign wbs2_we_o = wbm_we_i & wbs2_sel; 168 | assign wbs2_sel_o = wbm_sel_i; 169 | assign wbs2_stb_o = wbm_stb_i & wbs2_sel; 170 | assign wbs2_cyc_o = wbm_cyc_i & wbs2_sel; 171 | 172 | 173 | endmodule 174 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab6/alu_32.sv: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | `include "defines.sv" 3 | 4 | module alu_32 ( 5 | input wire [31:0] a, 6 | input wire [31:0] b, 7 | input wire [4:0] op, 8 | output logic [31:0] y 9 | ); 10 | 11 | logic [4:0] x; 12 | assign x = b[4:0]; 13 | 14 | always_comb begin 15 | case (op) 16 | `ALU_OP_PLUS: 17 | y = a + b; 18 | `ALU_OP_MINUS: 19 | y = a - b; 20 | `ALU_OP_AND: 21 | y = a & b; 22 | `ALU_OP_OR: 23 | y = a | b; 24 | `ALU_OP_XOR: 25 | y = a ^ b; 26 | `ALU_OP_NOT: 27 | y = ~a; 28 | `ALU_OP_SLL: 29 | y = a << x[4:0]; 30 | `ALU_OP_SRL: 31 | y = a >> x[4:0]; 32 | `ALU_OP_SRA: 33 | y = $signed(a) >>> x[4:0]; 34 | `ALU_OP_ROL: 35 | y = (a << x) | (a >> ((~x) + 4'd1)); 36 | `ALU_OP_SEL_B: // used as a mux, used in lui. 37 | y = b; 38 | `ALU_OP_SEL_A: 39 | y = a; 40 | `ALU_OP_BIT_CLEAR: 41 | y = ~a & b; 42 | `ALU_OP_SLTU: 43 | y = a < b ? 32'b1 : 32'b0; 44 | `ALU_OP_SLT: 45 | y = $signed(a) < $signed(b) ? 32'b1 : 32'b0; 46 | `ALU_OP_CTZ: begin 47 | casez (a) 48 | 32'b????_????_????_????_????_????_????_???1: y = 32'd0; 49 | 32'b????_????_????_????_????_????_????_??10: y = 32'd1; 50 | 32'b????_????_????_????_????_????_????_?100: y = 32'd2; 51 | 32'b????_????_????_????_????_????_????_1000: y = 32'd3; 52 | 32'b????_????_????_????_????_????_???1_0000: y = 32'd4; 53 | 32'b????_????_????_????_????_????_??10_0000: y = 32'd5; 54 | 32'b????_????_????_????_????_????_?100_0000: y = 32'd6; 55 | 32'b????_????_????_????_????_????_1000_0000: y = 32'd7; 56 | 32'b????_????_????_????_????_???1_0000_0000: y = 32'd8; 57 | 32'b????_????_????_????_????_??10_0000_0000: y = 32'd9; 58 | 32'b????_????_????_????_????_?100_0000_0000: y = 32'd10; 59 | 32'b????_????_????_????_????_1000_0000_0000: y = 32'd11; 60 | 32'b????_????_????_????_???1_0000_0000_0000: y = 32'd12; 61 | 32'b????_????_????_????_??10_0000_0000_0000: y = 32'd13; 62 | 32'b????_????_????_????_?100_0000_0000_0000: y = 32'd14; 63 | 32'b????_????_????_????_1000_0000_0000_0000: y = 32'd15; 64 | 32'b????_????_????_???1_0000_0000_0000_0000: y = 32'd16; 65 | 32'b????_????_????_??10_0000_0000_0000_0000: y = 32'd17; 66 | 32'b????_????_????_?100_0000_0000_0000_0000: y = 32'd18; 67 | 32'b????_????_????_1000_0000_0000_0000_0000: y = 32'd19; 68 | 32'b????_????_???1_0000_0000_0000_0000_0000: y = 32'd20; 69 | 32'b????_????_??10_0000_0000_0000_0000_0000: y = 32'd21; 70 | 32'b????_????_?100_0000_0000_0000_0000_0000: y = 32'd22; 71 | 32'b????_????_1000_0000_0000_0000_0000_0000: y = 32'd23; 72 | 32'b????_???1_0000_0000_0000_0000_0000_0000: y = 32'd24; 73 | 32'b????_??10_0000_0000_0000_0000_0000_0000: y = 32'd25; 74 | 32'b????_?100_0000_0000_0000_0000_0000_0000: y = 32'd26; 75 | 32'b????_1000_0000_0000_0000_0000_0000_0000: y = 32'd27; 76 | 32'b???1_0000_0000_0000_0000_0000_0000_0000: y = 32'd28; 77 | 32'b??10_0000_0000_0000_0000_0000_0000_0000: y = 32'd29; 78 | 32'b?100_0000_0000_0000_0000_0000_0000_0000: y = 32'd30; 79 | 32'b1000_0000_0000_0000_0000_0000_0000_0000: y = 32'd31; 80 | default: y = 32'd32; 81 | endcase 82 | end 83 | `ALU_OP_MIN: begin 84 | y = $signed(a) < $signed(b) ? a : b; 85 | end 86 | `ALU_OP_ANDN: begin 87 | y = a & ~b; 88 | end 89 | default: 90 | y = 32'b0; 91 | 92 | endcase 93 | end; 94 | endmodule // alu_32 -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab6/btb.sv: -------------------------------------------------------------------------------- 1 | `include "defines.sv" 2 | 3 | `define VALID 66 4 | `define STATE 65:64 5 | `define TAG 63:32 6 | `define TGT 31:0 7 | 8 | module branch_predictor( 9 | input wire clk, 10 | input wire rst, 11 | // BTB predict 12 | input wire [31:0] old_pc_i, 13 | output reg branch_taken_o, 14 | output reg [31:0] pred_target_o, 15 | // BTB refresh 16 | input wire exe_stall_i, 17 | input wire exe_branch_enable_i, 18 | input wire exe_branch_taken_i, 19 | input wire [31:0] exe_pc_i, 20 | input wire [31:0] exe_alu_y_i 21 | ); 22 | // TAG_WIDTH=32, VALID_BIT=1, STATUS_BITS=2, TARGET=32 23 | logic [66:0] buffer[8]; 24 | logic [2:0] rank[8]; // rank[i] == 0 is the most recent used 25 | logic [2:0] old_pc_idx; 26 | logic old_pc_match; 27 | logic [2:0] exe_pc_idx; 28 | logic exe_pc_match; 29 | logic [2:0] target_rank; 30 | logic [2:0] evict; 31 | 32 | always_comb begin 33 | if (buffer[0][`TAG] == old_pc_i && buffer[0][`VALID]) {old_pc_idx, old_pc_match} = {3'd0, 1'b1}; 34 | else if (buffer[1][`TAG] == old_pc_i && buffer[1][`VALID]) {old_pc_idx, old_pc_match} = {3'd1, 1'b1}; 35 | else if (buffer[2][`TAG] == old_pc_i && buffer[2][`VALID]) {old_pc_idx, old_pc_match} = {3'd2, 1'b1}; 36 | else if (buffer[3][`TAG] == old_pc_i && buffer[3][`VALID]) {old_pc_idx, old_pc_match} = {3'd3, 1'b1}; 37 | else if (buffer[4][`TAG] == old_pc_i && buffer[4][`VALID]) {old_pc_idx, old_pc_match} = {3'd4, 1'b1}; 38 | else if (buffer[5][`TAG] == old_pc_i && buffer[5][`VALID]) {old_pc_idx, old_pc_match} = {3'd5, 1'b1}; 39 | else if (buffer[6][`TAG] == old_pc_i && buffer[6][`VALID]) {old_pc_idx, old_pc_match} = {3'd6, 1'b1}; 40 | else if (buffer[7][`TAG] == old_pc_i && buffer[7][`VALID]) {old_pc_idx, old_pc_match} = {3'd7, 1'b1}; 41 | else {old_pc_idx, old_pc_match} = 4'b0; 42 | 43 | if (buffer[0][`TAG] == exe_pc_i && buffer[0][`VALID]) {exe_pc_idx, exe_pc_match} = {3'd0, 1'b1}; 44 | else if (buffer[1][`TAG] == exe_pc_i && buffer[1][`VALID]) {exe_pc_idx, exe_pc_match} = {3'd1, 1'b1}; 45 | else if (buffer[2][`TAG] == exe_pc_i && buffer[2][`VALID]) {exe_pc_idx, exe_pc_match} = {3'd2, 1'b1}; 46 | else if (buffer[3][`TAG] == exe_pc_i && buffer[3][`VALID]) {exe_pc_idx, exe_pc_match} = {3'd3, 1'b1}; 47 | else if (buffer[4][`TAG] == exe_pc_i && buffer[4][`VALID]) {exe_pc_idx, exe_pc_match} = {3'd4, 1'b1}; 48 | else if (buffer[5][`TAG] == exe_pc_i && buffer[5][`VALID]) {exe_pc_idx, exe_pc_match} = {3'd5, 1'b1}; 49 | else if (buffer[6][`TAG] == exe_pc_i && buffer[6][`VALID]) {exe_pc_idx, exe_pc_match} = {3'd6, 1'b1}; 50 | else if (buffer[7][`TAG] == exe_pc_i && buffer[7][`VALID]) {exe_pc_idx, exe_pc_match} = {3'd7, 1'b1}; 51 | else {exe_pc_idx, exe_pc_match} = 4'b0; 52 | 53 | if (rank[0] == 3'b111) evict = 4'd0; 54 | else if (rank[1] == 3'b111) evict = 4'd1; 55 | else if (rank[2] == 3'b111) evict = 4'd2; 56 | else if (rank[3] == 3'b111) evict = 4'd3; 57 | else if (rank[4] == 3'b111) evict = 4'd4; 58 | else if (rank[5] == 3'b111) evict = 4'd5; 59 | else if (rank[6] == 3'b111) evict = 4'd6; 60 | else if (rank[7] == 3'b111) evict = 4'd7; 61 | else evict = 4'd0; 62 | end 63 | 64 | assign branch_taken_o = old_pc_match; 65 | assign pred_target_o = old_pc_match ? buffer[old_pc_idx][`TGT] : old_pc_i + 4; 66 | 67 | assign target_rank = rank[exe_pc_idx]; 68 | 69 | always_ff @(posedge clk) begin 70 | if (rst) begin 71 | rank[0] <= 3'd0; 72 | rank[1] <= 3'd1; 73 | rank[2] <= 3'd2; 74 | rank[3] <= 3'd3; 75 | rank[4] <= 3'd4; 76 | rank[5] <= 3'd5; 77 | rank[6] <= 3'd6; 78 | rank[7] <= 3'd7; 79 | for (integer i = 0; i < 8; i += 1) 80 | buffer[i][66] <= 1'b0; 81 | end else if (exe_branch_enable_i) begin 82 | // update only for branch instrs 83 | if (exe_pc_match) begin 84 | if (target_rank != 3'b0) begin // update rank 85 | if (rank[0] < target_rank) rank[0] <= rank[0] + 1; 86 | if (rank[1] < target_rank) rank[1] <= rank[1] + 1; 87 | if (rank[2] < target_rank) rank[2] <= rank[2] + 1; 88 | if (rank[3] < target_rank) rank[3] <= rank[3] + 1; 89 | if (rank[4] < target_rank) rank[4] <= rank[4] + 1; 90 | if (rank[5] < target_rank) rank[5] <= rank[5] + 1; 91 | if (rank[6] < target_rank) rank[6] <= rank[6] + 1; 92 | if (rank[7] < target_rank) rank[7] <= rank[7] + 1; 93 | rank[exe_pc_idx] <= 3'b0; 94 | end 95 | // update bimodal 96 | if (exe_branch_taken_i) begin // goto taken, 1 97 | if (buffer[old_pc_idx][65:64] != 2'b11) 98 | buffer[old_pc_idx][65:64] <= buffer[old_pc_idx][65:64] + 1; 99 | buffer[old_pc_idx][`TGT] <= exe_alu_y_i; 100 | end else begin // goto nottaken, 0 101 | if (buffer[old_pc_idx][65:64] != 2'b00) 102 | buffer[old_pc_idx][65:64] <= buffer[old_pc_idx][65:64] - 1; 103 | end 104 | end else begin // replace 105 | rank[0] <= rank[0] + 1; 106 | rank[1] <= rank[1] + 1; 107 | rank[2] <= rank[2] + 1; 108 | rank[3] <= rank[3] + 1; 109 | rank[4] <= rank[4] + 1; 110 | rank[5] <= rank[5] + 1; 111 | rank[6] <= rank[6] + 1; 112 | rank[7] <= rank[7] + 1; 113 | rank[evict] <= 4'b0; 114 | buffer[evict] <= {1'b1, exe_branch_taken_i, ~exe_branch_taken_i, exe_pc_i, exe_alu_y_i}; 115 | end 116 | end 117 | end 118 | 119 | endmodule -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab6/defines.sv: -------------------------------------------------------------------------------- 1 | // some constants needed to be defined 2 | `ifndef __DEFINES__ // I don't know whether header protection is needed 3 | `define __DEFINES__ 4 | 5 | 6 | `define ALU_SEL_PC 2'd0 7 | `define ALU_SEL_RS1 2'd1 8 | // ALU_SEL_CSR 2'd2 reserved here 9 | 10 | `define ALU_SEL_IMM 2'd0 11 | `define ALU_SEL_RS2 2'd1 12 | `define ALU_SEL_CSR 2'd2 13 | 14 | `define RD_SEL_ALU 2'd0 15 | `define RD_SEL_MEM 2'd1 16 | `define RD_SEL_PC 2'd2 17 | `define RD_SEL_CSR 2'd3 18 | 19 | `define ALU_OP_PLUS 5'd1 20 | `define ALU_OP_MINUS 5'd2 21 | `define ALU_OP_AND 5'd3 22 | `define ALU_OP_OR 5'd4 23 | `define ALU_OP_XOR 5'd5 24 | `define ALU_OP_NOT 5'd6 25 | `define ALU_OP_SLL 5'd7 26 | `define ALU_OP_SRL 5'd8 27 | `define ALU_OP_SRA 5'd9 28 | `define ALU_OP_ROL 5'd10 29 | `define ALU_OP_SEL_B 5'd11 30 | `define ALU_OP_SEL_A 5'd12 31 | `define ALU_OP_BIT_CLEAR 5'd13 32 | `define ALU_OP_SLTU 5'd14 33 | `define ALU_OP_SLT 5'd15 34 | `define ALU_OP_CTZ 5'd29 35 | `define ALU_OP_MIN 5'd30 36 | `define ALU_OP_ANDN 5'd31 37 | 38 | `define SRAM_SEL_1 2'b00 39 | `define SRAM_SEL_2 2'b01 40 | `define SRAM_SEL_4 2'b10 41 | 42 | `define MODE_M 2'b11 43 | `define MODE_S 2'b01 44 | `define MODE_U 2'b00 45 | 46 | `define INT_NONE 2'b00 47 | `define INT_TIMER_M 2'b01 48 | `define INT_TIMER_S 2'b10 49 | 50 | `define PC_ADD4 2'b00 51 | `define PC_BRANCH 2'b01 52 | `define PC_TRAP 2'b10 53 | 54 | `define BRANCH_EQU 3'd0 55 | `define BRANCH_NEQ 3'd1 56 | `define BRANCH_LT 3'd2 57 | `define BRANCH_GE 3'd3 58 | `define BRANCH_LTU 3'd4 59 | `define BRANCH_GEU 3'd5 60 | 61 | `define LOAD_EXT_ZERO 1'b0 62 | `define LOAD_EXT_SIGNED 1'b1 63 | 64 | `endif //__DEFINES__ 65 | 66 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab6/exe.sv: -------------------------------------------------------------------------------- 1 | `include "defines.sv" 2 | 3 | module execution( 4 | input wire [31:0] pc_i, 5 | input wire [31:0] rs1_data_i, 6 | input wire [31:0] rs2_data_i, 7 | input wire [31:0] imm_i, 8 | input wire [4:0] csr_imm_i, 9 | input wire [31:0] csr_i, 10 | input wire [1:0] alu_sel_a_i, 11 | input wire [1:0] alu_sel_b_i, 12 | input wire [4:0] alu_op_i, 13 | input wire branch_i, 14 | input wire [2:0] branch_type_i, 15 | input wire branch_ja_i, 16 | 17 | 18 | output reg [31:0] alu_y_o, 19 | output reg [31:0] sram_data_o, 20 | output reg branch_o 21 | ); 22 | 23 | assign sram_data_o = rs2_data_i; 24 | 25 | 26 | always_comb begin 27 | branch_o = 1'b0; 28 | if (branch_i) begin 29 | if (branch_ja_i) begin 30 | branch_o = 1'b1; 31 | end else begin 32 | case(branch_type_i) 33 | `BRANCH_EQU: branch_o = (rs1_data_i == rs2_data_i); 34 | `BRANCH_NEQ: branch_o = (rs1_data_i != rs2_data_i); 35 | `BRANCH_LT: branch_o = ($signed(rs1_data_i) < $signed(rs2_data_i)); 36 | `BRANCH_GE: branch_o = ~($signed(rs1_data_i) < $signed(rs2_data_i)); 37 | `BRANCH_LTU: branch_o = (rs1_data_i < rs2_data_i); 38 | `BRANCH_GEU: branch_o = ~(rs1_data_i < rs2_data_i); 39 | endcase 40 | end 41 | end 42 | end 43 | 44 | alu_32 alu( 45 | .a(alu_sel_a_i == `ALU_SEL_RS1 ? rs1_data_i : ( 46 | alu_sel_a_i == `ALU_SEL_CSR ? {27'b0, csr_imm_i} : pc_i )), 47 | .b(alu_sel_b_i == `ALU_SEL_RS2 ? rs2_data_i : ( 48 | alu_sel_b_i == `ALU_SEL_CSR ? csr_i : imm_i )), 49 | .y(alu_y_o), 50 | .op(alu_op_i) 51 | ); 52 | 53 | 54 | 55 | 56 | endmodule // execution 57 | 58 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab6/hazard.sv: -------------------------------------------------------------------------------- 1 | `include "defines.sv" 2 | 3 | module hazard_detector ( 4 | input wire immu_wait_i, 5 | input wire imem_wait_i, 6 | 7 | input wire [4:0] id_rs1_i, 8 | input wire [4:0] id_rs2_i, 9 | input wire id_fencei_i, 10 | 11 | output reg [31:0] rs1_out_o, 12 | output reg rs1_side_path_o, 13 | output reg [31:0] rs2_out_o, 14 | output reg rs2_side_path_o, 15 | 16 | input wire [4:0] exe_rd_i, 17 | input wire exe_rd_we_i, 18 | input wire [31:0] exe_rd_data_i, 19 | input wire exe_rd_ready_i, 20 | input wire branch_i, 21 | input wire branch_failed, 22 | 23 | input wire [4:0] mem1_rd_i, 24 | input wire mem1_rd_we_i, 25 | input wire [31:0] mem1_rd_data_i, 26 | input wire mem1_rd_ready_i, 27 | input wire [4:0] mem2_rd_i, 28 | input wire mem2_rd_we_i, 29 | input wire [31:0] mem2_rd_data_i, 30 | input wire mem2_rd_ready_i, 31 | 32 | 33 | input wire dmmu_wait_i, 34 | input wire dmem_wait_i, 35 | 36 | input wire [4:0] wb_rd_i, 37 | input wire wb_rd_we_i, 38 | input wire [31:0] wb_rd_data_i, 39 | input wire wb_rd_ready_i, 40 | 41 | input wire csr_write_i, 42 | input wire mem2_trap_i, 43 | input wire wb_trap_i, 44 | 45 | output reg if1_stall_o, 46 | output reg [1:0] if1_branch_o, 47 | output reg if2_stall_o, 48 | output reg if2_bubble_o, 49 | output reg id_stall_o, 50 | output reg id_bubble_o, 51 | output reg exe_stall_o, 52 | output reg exe_bubble_o, 53 | output reg mem1_stall_o, 54 | output reg mem1_bubble_o, 55 | output reg mem2_stall_o, 56 | output reg mem2_bubble_o, 57 | output reg wb_stall_o, 58 | output reg wb_bubble_o 59 | 60 | ); 61 | 62 | 63 | // RAW detection 64 | logic read_after_write; 65 | logic raw_rs1, raw_rs2; 66 | assign read_after_write = raw_rs1 | raw_rs2; 67 | 68 | always_comb begin 69 | raw_rs1 = 1'b0; 70 | rs1_out_o = 32'b0; 71 | rs1_side_path_o = 1'b0; 72 | 73 | if (exe_rd_i == id_rs1_i && exe_rd_i != 5'h0 && exe_rd_we_i) begin 74 | if (exe_rd_ready_i) begin 75 | rs1_out_o = exe_rd_data_i; 76 | rs1_side_path_o = 1'b1; 77 | end else 78 | raw_rs1 = 1'b1; 79 | end else 80 | if (mem1_rd_i == id_rs1_i && mem1_rd_i != 5'h0 && mem1_rd_we_i) begin 81 | if (mem1_rd_ready_i) begin 82 | rs1_out_o = mem1_rd_data_i; 83 | rs1_side_path_o = 1'b1; 84 | end else 85 | raw_rs1 = 1'b1; 86 | end else 87 | if (mem2_rd_i == id_rs1_i && mem2_rd_i != 5'h0 && mem2_rd_we_i) begin 88 | if (mem2_rd_ready_i) begin 89 | rs1_out_o = mem2_rd_data_i; 90 | rs1_side_path_o = 1'b1; 91 | end else 92 | raw_rs1 = 1'b1; 93 | end else 94 | if (wb_rd_i == id_rs1_i && wb_rd_i != 5'h0 && wb_rd_we_i) begin 95 | if (wb_rd_ready_i) begin 96 | rs1_out_o = wb_rd_data_i; 97 | rs1_side_path_o = 1'b1; 98 | end else 99 | raw_rs1 = 1'b1; 100 | end 101 | end // always_comb 102 | 103 | always_comb begin 104 | raw_rs2 = 1'b0; 105 | rs2_out_o = 32'b0; 106 | rs2_side_path_o = 1'b0; 107 | 108 | if (exe_rd_i == id_rs2_i && exe_rd_i != 5'h0 && exe_rd_we_i) begin 109 | if (exe_rd_ready_i) begin 110 | rs2_out_o = exe_rd_data_i; 111 | rs2_side_path_o = 1'b1; 112 | end else 113 | raw_rs2 = 1'b1; 114 | end else 115 | if (mem1_rd_i == id_rs2_i && mem1_rd_i != 5'h0 && mem1_rd_we_i) begin 116 | if (mem1_rd_ready_i) begin 117 | rs2_out_o = mem1_rd_data_i; 118 | rs2_side_path_o = 1'b1; 119 | end else 120 | raw_rs2 = 1'b1; 121 | end else 122 | if (mem2_rd_i == id_rs2_i && mem2_rd_i != 5'h0 && mem2_rd_we_i) begin 123 | if (mem2_rd_ready_i) begin 124 | rs2_out_o = mem2_rd_data_i; 125 | rs2_side_path_o = 1'b1; 126 | end else 127 | raw_rs2 = 1'b1; 128 | end else 129 | if (wb_rd_i == id_rs2_i && wb_rd_i != 5'h0 && wb_rd_we_i) begin 130 | if (wb_rd_ready_i) begin 131 | rs2_out_o = wb_rd_data_i; 132 | rs2_side_path_o = 1'b1; 133 | end else 134 | raw_rs2 = 1'b1; 135 | end 136 | end // always_comb 137 | 138 | 139 | //assign if_stall_o = read_after_write | imem_wait_i | dmem_wait_i; 140 | 141 | // ID + EXE + MEM 142 | always_comb begin 143 | if1_stall_o = 1'b0; 144 | if1_branch_o = `PC_ADD4; 145 | 146 | if2_stall_o = 1'b0; 147 | if2_bubble_o = 1'b0; 148 | 149 | id_stall_o = 1'b0; 150 | id_bubble_o = 1'b0; 151 | 152 | exe_stall_o = 1'b0; 153 | exe_bubble_o = 1'b0; 154 | 155 | mem1_stall_o = 1'b0; 156 | mem1_bubble_o = 1'b0; 157 | 158 | mem2_stall_o = 1'b0; 159 | mem2_bubble_o = 1'b0; 160 | 161 | wb_stall_o = 1'b0; 162 | wb_bubble_o = 1'b0; 163 | 164 | if (dmmu_wait_i && wb_trap_i) begin 165 | if1_stall_o = 1'b1; 166 | if2_stall_o = 1'b1; 167 | id_stall_o = 1'b1; 168 | exe_stall_o = 1'b1; 169 | mem1_stall_o = 1'b1; 170 | mem2_bubble_o = 1'b1; 171 | wb_stall_o = 1'b1; 172 | end else if (imem_wait_i && wb_trap_i) begin 173 | if1_stall_o = 1'b1; 174 | if2_stall_o = 1'b1; 175 | id_bubble_o = 1'b1; 176 | exe_bubble_o = 1'b1; 177 | mem1_bubble_o = 1'b1; 178 | mem2_bubble_o = 1'b1; 179 | wb_stall_o = 1'b1; 180 | end else if (immu_wait_i && wb_trap_i) begin 181 | if1_stall_o = 1'b1; 182 | if2_bubble_o = 1'b1; 183 | id_bubble_o = 1'b1; 184 | exe_bubble_o = 1'b1; 185 | mem1_bubble_o = 1'b1; 186 | mem2_bubble_o = 1'b1; 187 | wb_stall_o = 1'b1; 188 | end else if (wb_trap_i) begin 189 | if1_branch_o = `PC_TRAP; 190 | if2_bubble_o = 1'b1; 191 | id_bubble_o = 1'b1; 192 | exe_bubble_o = 1'b1; 193 | mem1_bubble_o = 1'b1; 194 | mem2_bubble_o = 1'b1; 195 | wb_bubble_o = 1'b1; 196 | end else if (dmem_wait_i) begin 197 | if1_stall_o = 1'b1; 198 | if2_stall_o = 1'b1; 199 | id_stall_o = 1'b1; 200 | exe_stall_o = 1'b1; 201 | mem1_stall_o = 1'b1; 202 | mem2_stall_o = 1'b1; 203 | wb_bubble_o = 1'b1; 204 | end else if (mem2_trap_i) begin 205 | if1_stall_o = 1'b1; 206 | if2_stall_o = 1'b1; 207 | id_bubble_o = 1'b1; 208 | exe_bubble_o = 1'b1; 209 | mem1_bubble_o = 1'b1; 210 | mem2_bubble_o = 1'b1; 211 | end else if (dmmu_wait_i) begin 212 | if1_stall_o = 1'b1; 213 | if2_stall_o = 1'b1; 214 | id_stall_o = 1'b1; 215 | exe_stall_o = 1'b1; 216 | mem1_stall_o = 1'b1; 217 | mem2_bubble_o = 1'b1; 218 | end else if (imem_wait_i && branch_failed) begin 219 | if1_stall_o = 1'b1; 220 | if2_stall_o = 1'b1; 221 | id_stall_o = 1'b1; 222 | exe_stall_o = 1'b1; 223 | mem1_bubble_o = 1'b1; 224 | end else if (immu_wait_i && branch_failed) begin 225 | if1_stall_o = 1'b1; 226 | if2_bubble_o = 1'b1; 227 | id_bubble_o = 1'b1; 228 | exe_stall_o = 1'b1; 229 | mem1_bubble_o = 1'b1; 230 | end else if (branch_failed) begin 231 | if1_branch_o = branch_i ? `PC_BRANCH : `PC_ADD4; 232 | if2_bubble_o = 1'b1; 233 | id_bubble_o = 1'b1; 234 | exe_bubble_o = 1'b1; 235 | end else if (read_after_write) begin 236 | if1_stall_o = 1'b1; 237 | if2_stall_o = 1'b1; 238 | id_stall_o = 1'b1; 239 | exe_bubble_o = 1'b1; 240 | end else if (imem_wait_i | csr_write_i | id_fencei_i) begin 241 | if1_stall_o = 1'b1; 242 | if2_stall_o = 1'b1; 243 | id_bubble_o = 1'b1; 244 | end else if (immu_wait_i) begin 245 | if1_stall_o = 1'b1; 246 | if2_bubble_o = 1'b1; 247 | end 248 | end // always_comb 249 | 250 | //assign wb_stall_o = 1'b0; 251 | //assign wb_bubble_o = dmem_wait_i; 252 | 253 | 254 | 255 | endmodule // hazard_detector 256 | 257 | 258 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab6/inst_fetch.sv: -------------------------------------------------------------------------------- 1 | `include "defines.sv" 2 | 3 | module inst_fetch( 4 | input wire clk, 5 | input wire rst, 6 | 7 | input wire branch_failed_i, 8 | input wire [31:0] branch_pc_i, 9 | input wire [31:0] trap_pc_i, 10 | input wire [1:0] branch_i, 11 | 12 | input wire exe_stall_i, 13 | input wire exe_branch_enable_i, 14 | input wire exe_branch_taken_i, 15 | input wire [31:0] exe_pc_i, 16 | input wire [31:0] exe_alu_y_i, 17 | 18 | input wire stall_i, 19 | 20 | output logic branch_taken_o, 21 | output logic [31:0] pc_o 22 | 23 | 24 | ); 25 | 26 | reg [31:0] pc_reg; 27 | logic [31:0] pc_predict; 28 | 29 | 30 | branch_predictor btb( 31 | .clk(clk), 32 | .rst(rst), 33 | 34 | .old_pc_i(pc_reg), 35 | .branch_taken_o(branch_taken_o), 36 | .pred_target_o(pc_predict), 37 | 38 | .exe_stall_i(exe_stall_i), 39 | .exe_branch_enable_i(exe_branch_enable_i), 40 | .exe_branch_taken_i(exe_branch_taken_i && (branch_i != `PC_TRAP)), 41 | .exe_pc_i(exe_pc_i), 42 | .exe_alu_y_i(exe_alu_y_i) 43 | ); 44 | 45 | //assign pc_predict = pc_reg + 4; 46 | //assign branch_taken_o = 1'b0; 47 | 48 | // pc mux + pc reg 49 | always_ff @ (posedge clk) begin 50 | if (rst) begin 51 | pc_reg <= 32'h8000_0000; 52 | end else begin 53 | if (!stall_i) begin 54 | pc_reg <= branch_i == `PC_TRAP ? trap_pc_i : 55 | branch_failed_i ? ( 56 | branch_i == `PC_BRANCH ? branch_pc_i : exe_pc_i + 4 57 | ) : pc_predict; 58 | end 59 | end 60 | end 61 | 62 | assign pc_o = pc_reg; 63 | 64 | endmodule // inst_fetch 65 | 66 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab6/instr_cache.sv: -------------------------------------------------------------------------------- 1 | `include "defines.sv" 2 | 3 | module instr_cache#( 4 | parameter INDEX_WIDTH = 5, 5 | parameter NROWS = 32, 6 | parameter TAG_WIDTH = 31 - INDEX_WIDTH // 27 7 | )( 8 | input wire clk, 9 | input wire rst, 10 | 11 | input wire cache_rst_i, 12 | 13 | input wire [31:0] addr_i, 14 | input wire enable_i, 15 | 16 | output reg [31:0] data_o, 17 | output reg wait_o, 18 | 19 | // interface of wishbone 20 | output reg wb_cyc_o, 21 | output reg wb_stb_o, 22 | input wire wb_ack_i, 23 | output reg [31:0] wb_adr_o, 24 | output reg [31:0] wb_dat_o, 25 | input wire [31:0] wb_dat_i, 26 | output reg [3:0] wb_sel_o, 27 | output reg wb_we_o 28 | ); 29 | enum logic[1:0] { 30 | ICACHE_INIT, 31 | ICACHE_MEM 32 | } icache_state; 33 | // 1 + TAG_WIDTH + 32 34 | logic [TAG_WIDTH+32:0] cachelines[NROWS]; 35 | logic [TAG_WIDTH-1:0] addr_tag; 36 | logic [INDEX_WIDTH-1:0] addr_idx; 37 | logic icache_hit; 38 | logic [TAG_WIDTH+32:0] selected_line; 39 | logic imem_wait; 40 | logic imem_read_enable; 41 | logic [31:0] imem_data_o; 42 | 43 | assign addr_tag = addr_i[31:INDEX_WIDTH+1]; 44 | assign addr_idx = addr_i[INDEX_WIDTH:1]; 45 | assign selected_line = cachelines[addr_idx]; 46 | assign icache_hit = (selected_line[TAG_WIDTH+32] && 47 | selected_line[TAG_WIDTH+31:32] == addr_tag 48 | ) & ~cache_rst_i; 49 | 50 | always_ff @(posedge clk) begin 51 | if (rst | cache_rst_i) begin 52 | for (integer i = 0; i < NROWS; i = i + 1) 53 | cachelines[i][TAG_WIDTH+32] <= 1'b0; 54 | end 55 | if (rst) begin 56 | icache_state <= ICACHE_INIT; 57 | end else begin 58 | case(icache_state) 59 | ICACHE_INIT: begin 60 | if (enable_i) begin 61 | if (icache_hit) 62 | icache_state <= ICACHE_INIT; 63 | else 64 | icache_state <= ICACHE_MEM; 65 | end 66 | end 67 | ICACHE_MEM: begin 68 | if (~imem_wait) begin 69 | cachelines[addr_idx] <= {1'b1, addr_tag, imem_data_o}; 70 | icache_state <= ICACHE_INIT; 71 | end 72 | // else remain in icache_state 73 | end 74 | endcase 75 | end 76 | end 77 | 78 | always_comb begin 79 | wait_o = 1'b1; 80 | imem_read_enable = 1'b0; 81 | data_o = 32'b0; 82 | case(icache_state) 83 | ICACHE_INIT: begin 84 | if (enable_i) begin 85 | if (icache_hit) begin 86 | data_o = selected_line[31:0]; 87 | wait_o = 1'b0; 88 | end else begin 89 | wait_o = 1'b1; 90 | end 91 | end else begin 92 | wait_o = 1'b0; 93 | end 94 | end 95 | ICACHE_MEM: begin 96 | wait_o = imem_wait; 97 | imem_read_enable = 1'b1; 98 | data_o = imem_data_o; 99 | end 100 | endcase 101 | end 102 | 103 | mem_controller icache_mem ( 104 | .clk(clk), 105 | .rst(rst), 106 | 107 | .addr_i(addr_i), 108 | .data_i(32'h0), 109 | .sel_i(4'b1111), 110 | .we_i(1'b0), 111 | .re_i(imem_read_enable), 112 | .data_o(imem_data_o), 113 | .mem_wait_o(imem_wait), 114 | 115 | .wb_cyc_o(wb_cyc_o), 116 | .wb_stb_o(wb_stb_o), 117 | .wb_ack_i(wb_ack_i), 118 | .wb_adr_o(wb_adr_o), 119 | .wb_dat_o(wb_dat_o), 120 | .wb_dat_i(wb_dat_i), 121 | .wb_sel_o(wb_sel_o), 122 | .wb_we_o(wb_we_o) 123 | ); 124 | endmodule -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab6/mem_controller.sv: -------------------------------------------------------------------------------- 1 | module mem_controller( 2 | 3 | 4 | input wire clk, 5 | input wire rst, 6 | // interface to CPU. 7 | input wire [31:0] addr_i, 8 | input wire [31:0] data_i, 9 | input wire [3:0] sel_i, 10 | input wire we_i, // write enable 11 | input wire re_i, // read enable 12 | output reg [31:0] data_o, 13 | output reg mem_wait_o, // whether we should wait 14 | 15 | // interface of wishbone 16 | output reg wb_cyc_o, 17 | output reg wb_stb_o, 18 | input wire wb_ack_i, 19 | output reg [31:0] wb_adr_o, 20 | output reg [31:0] wb_dat_o, 21 | input wire [31:0] wb_dat_i, 22 | output reg [3:0] wb_sel_o, 23 | output reg wb_we_o 24 | ); 25 | 26 | typedef enum logic [2:0] { 27 | ST_IDLE, 28 | ST_WAIT, 29 | ST_DONE 30 | } state_t; 31 | state_t state; 32 | 33 | always_ff @ (posedge clk) begin 34 | if (rst) begin 35 | state <= ST_IDLE; 36 | end else begin 37 | case (state) 38 | ST_IDLE: begin 39 | if (we_i || re_i) begin 40 | state <= ST_WAIT; 41 | end 42 | end 43 | ST_WAIT: begin 44 | if (wb_ack_i) begin 45 | state <= ST_DONE; 46 | end 47 | end 48 | ST_DONE: begin 49 | state <= ST_IDLE; 50 | end 51 | endcase 52 | end 53 | end // always_ff @ (posedge clk) 54 | 55 | 56 | always_comb begin 57 | wb_adr_o = addr_i; 58 | wb_dat_o = data_i; 59 | data_o = wb_dat_i; 60 | wb_we_o = 1'b0; 61 | wb_cyc_o = 1'b0; 62 | mem_wait_o = 1'b0; 63 | wb_sel_o = sel_i; 64 | 65 | 66 | case (state) 67 | ST_IDLE: begin 68 | if (we_i || re_i) begin 69 | wb_we_o = we_i & ~re_i; 70 | wb_cyc_o = 1'b1; 71 | mem_wait_o = 1'b1; 72 | end 73 | end 74 | ST_WAIT: begin 75 | wb_we_o = we_i & ~re_i; 76 | wb_cyc_o = 1'b1; 77 | mem_wait_o = ~wb_ack_i; 78 | end 79 | ST_DONE: begin // to lower cyc & stb a cycle, according to TA 80 | 81 | wb_cyc_o = 1'b0; 82 | if (we_i || re_i) begin 83 | mem_wait_o = 1'b1; 84 | end 85 | end 86 | endcase 87 | end 88 | assign wb_stb_o = wb_cyc_o; 89 | 90 | endmodule // mem_controller 91 | 92 | 93 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab6/memory.sv: -------------------------------------------------------------------------------- 1 | `include "defines.sv" 2 | 3 | 4 | 5 | module mem_decoder ( 6 | input wire [1:0] addr_i, 7 | input wire [1:0] sel_i, 8 | input wire load_ext_type_i, 9 | input wire [31:0] data_w_i, // from EXE 10 | input wire [31:0] data_r_i, // from DMEM 11 | 12 | output reg [31:0] data_w_o, // to DMEM 13 | output reg [31:0] data_r_o, // to WB 14 | output reg [3:0] sel_o, 15 | output reg bad_addr 16 | ); 17 | 18 | // since it's a combintional logic, 19 | // it's proper to combine two parts 20 | // - before SRAM and after SRAM 21 | // together 22 | 23 | always_comb begin 24 | sel_o = 4'b0; 25 | bad_addr = 1'b0; 26 | data_w_o = 32'b0; 27 | data_r_o = 32'b0; 28 | 29 | case(sel_i) 30 | `SRAM_SEL_1: begin 31 | case(addr_i) 32 | 2'b00: begin 33 | sel_o = 4'b0001; 34 | data_w_o[7:0] = data_w_i[7:0]; 35 | data_r_o[7:0] = data_r_i[7:0]; 36 | end 37 | 2'b01: begin 38 | sel_o = 4'b0010; 39 | data_w_o[15:8] = data_w_i[7:0]; 40 | data_r_o[7:0] = data_r_i[15:8]; 41 | end 42 | 2'b10: begin 43 | sel_o = 4'b0100; 44 | data_w_o[23:16] = data_w_i[7:0]; 45 | data_r_o[7:0] = data_r_i[23:16]; 46 | end 47 | 2'b11: begin 48 | sel_o = 4'b1000; 49 | data_w_o[31:24] = data_w_i[7:0]; 50 | data_r_o[7:0] = data_r_i[31:24]; 51 | end 52 | endcase 53 | if (load_ext_type_i == `LOAD_EXT_ZERO) data_r_o[31:8] = 24'b0; 54 | else data_r_o[31:8] = {{24{data_r_o[7]}}}; 55 | end 56 | `SRAM_SEL_2: begin 57 | case(addr_i) 58 | 2'b00: begin 59 | sel_o = 4'b0011; 60 | data_w_o[15:0] = data_w_i[15:0]; 61 | data_r_o[15:0] = data_r_i[15:0]; 62 | end 63 | 2'b10: begin 64 | sel_o = 4'b1100; 65 | data_w_o[31:16] = data_w_i[15:0]; 66 | data_r_o[15:0] = data_r_i[31:16]; 67 | end 68 | default: bad_addr = 1'b1; 69 | endcase // case (addr_i) 70 | if (load_ext_type_i == `LOAD_EXT_ZERO) data_r_o[31:16] = 16'b0; 71 | else data_r_o[31:16] = {{16{data_r_o[15]}}}; 72 | end 73 | `SRAM_SEL_4: begin 74 | if (addr_i == 2'b00) begin 75 | sel_o = 4'b1111; 76 | data_w_o = data_w_i; 77 | data_r_o = data_r_i; 78 | end 79 | else bad_addr = 1'b1; 80 | end 81 | endcase // case (mem_sram_sel_reg) 82 | end 83 | 84 | endmodule // mem_decoder 85 | 86 | 87 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab6/mmu.sv: -------------------------------------------------------------------------------- 1 | // Virtual Page Tranlation Module 2 | 3 | `include "defines.sv" 4 | 5 | module mmu( 6 | input wire clk, 7 | input wire rst, 8 | 9 | input wire tlb_rst_i, 10 | 11 | input wire [31:0] addr_i, 12 | input wire [1:0] mode_i, 13 | input wire [31:0] satp_i, 14 | input wire enable_i, 15 | input wire [2:0] permission_i, // XWR 16 | input wire sum_i, // sum field in mstatus 17 | 18 | output reg [31:0] addr_o, 19 | output reg wait_o, 20 | output reg page_fault_o, 21 | 22 | // interface of wishbone 23 | output reg wb_cyc_o, 24 | output reg wb_stb_o, 25 | input wire wb_ack_i, 26 | output reg [31:0] wb_adr_o, 27 | output reg [31:0] wb_dat_o, 28 | input wire [31:0] wb_dat_i, 29 | output reg [3:0] wb_sel_o, 30 | output reg wb_we_o 31 | 32 | ); 33 | 34 | enum logic [2:0] { 35 | MMU_INIT, 36 | MMU_LV1, 37 | MMU_LV1_DONE, 38 | MMU_LV2, 39 | MMU_DONE 40 | } state; 41 | 42 | logic tlb_valid; 43 | logic [19:0] tlb_vp; 44 | logic [31:0] tlb_pe; 45 | 46 | logic tlb_found; 47 | logic mode_direct; 48 | 49 | 50 | assign mode_direct = (mode_i == `MODE_M | satp_i[31] == 1'b0); 51 | 52 | assign tlb_found = (!mode_direct & tlb_valid & tlb_vp == addr_i[31:12]); 53 | 54 | 55 | logic [19:0] page_table_addr; 56 | logic mem_wait; 57 | logic [31:0] page_table_data; 58 | logic request; 59 | logic [31:0] lv1_addr; 60 | logic [9:0] offset; 61 | 62 | always_ff @ (posedge clk) begin 63 | if (rst) begin 64 | state <= MMU_INIT; 65 | lv1_addr <= 32'h0; 66 | end else begin 67 | case(state) 68 | MMU_INIT: begin 69 | if (enable_i) begin 70 | if (tlb_found || mode_direct) begin 71 | state <= MMU_INIT; 72 | end else begin 73 | state <= MMU_LV1; 74 | end 75 | end 76 | end 77 | MMU_LV1: begin 78 | if (!mem_wait) begin 79 | state <= MMU_LV1_DONE; 80 | lv1_addr <= page_table_data; 81 | end 82 | end 83 | MMU_LV1_DONE: begin 84 | if (page_fault_o) begin 85 | state <= MMU_INIT; 86 | end else begin 87 | state <= MMU_LV2; 88 | end 89 | end 90 | MMU_LV2: begin 91 | if (!mem_wait) begin 92 | state <= MMU_DONE; 93 | end 94 | end 95 | MMU_DONE: begin 96 | state <= MMU_INIT; 97 | end 98 | default: begin 99 | state <= MMU_INIT; 100 | end 101 | endcase 102 | end 103 | end // always_ff @ (posedge clk) 104 | 105 | logic [19:0] ppage; 106 | 107 | always_comb begin 108 | ppage = 20'h0; 109 | page_fault_o = 1'b0; 110 | request = 1'b0; 111 | page_table_addr = 20'b0; 112 | wait_o = 1'b1; 113 | offset = 10'b0; 114 | case(state) 115 | MMU_INIT: begin 116 | if (enable_i) begin 117 | if (mode_direct) begin 118 | ppage = addr_i[31:12]; 119 | wait_o = 1'b0; 120 | end else if (tlb_found) begin 121 | if ((mode_i == `MODE_U && !tlb_pe[4]) || 122 | (permission_i & ~tlb_pe[3:1]) != 3'b0 || 123 | (mode_i == `MODE_S && tlb_pe[4] && ( !sum_i || permission_i[2] ) )) begin 124 | page_fault_o = 1'b1; 125 | end 126 | ppage = tlb_pe[29:10]; 127 | wait_o = 1'b0; 128 | end 129 | // TODO: may reduce cycle? 130 | /* else begin 131 | request = 1'b1; 132 | page_table_addr = satp[19:0]; 133 | offset = addr_i[31:22]; 134 | end 135 | */ 136 | end else begin // if (enable_i) 137 | wait_o = 1'b0; 138 | end 139 | end // case: MMU_INIT 140 | MMU_LV1: begin 141 | request = 1'b1; 142 | page_table_addr = satp_i[19:0]; 143 | offset = addr_i[31:22]; 144 | end 145 | MMU_LV1_DONE: begin 146 | // !V || leaf_page || !U 147 | if (lv1_addr[0] == 1'b0 || lv1_addr[3:1] != 3'b0 || (mode_i == `MODE_U && !lv1_addr[4])) begin 148 | page_fault_o = 1'b1; 149 | wait_o = 1'b0; 150 | end 151 | end 152 | MMU_LV2: begin 153 | request = 1'b1; 154 | page_table_addr = lv1_addr[29:10]; 155 | offset = addr_i[21:12]; 156 | if (!mem_wait) begin 157 | wait_o = 1'b0; 158 | // !V || !R&W || !U || permission || S&(!SUM | exec) 159 | if (page_table_data[0] == 1'b0 || 160 | page_table_data[2:1] == 2'b10 || 161 | (mode_i == `MODE_U && !page_table_data[4]) || 162 | (permission_i & (~page_table_data[3:1])) != 3'b0 || 163 | (mode_i == `MODE_S && page_table_data[4] && ( !sum_i || permission_i[2] ) ) ) begin 164 | page_fault_o = 1'b1; 165 | end else begin 166 | ppage = page_table_data[29:10]; 167 | end 168 | end 169 | end // case: MMU_LV2 170 | MMU_DONE: begin 171 | wait_o = enable_i; 172 | end 173 | endcase 174 | end // always_comb 175 | 176 | always_ff @ (posedge clk) begin 177 | if (rst || tlb_rst_i) begin 178 | tlb_valid <= 1'b0; 179 | end else begin 180 | if (state == MMU_LV2 && !mem_wait && !page_fault_o) begin 181 | tlb_valid <= 1'b1; 182 | tlb_vp <= addr_i[31:12]; 183 | tlb_pe <= page_table_data; 184 | end 185 | end 186 | end // always_ff @ (posedge clk) 187 | 188 | assign addr_o = {ppage, addr_i[11:0]}; 189 | 190 | 191 | mem_controller mem ( 192 | .clk(clk), 193 | .rst(rst), 194 | 195 | .addr_i({page_table_addr, offset, 2'b0}), 196 | .data_i(32'h0), 197 | .sel_i(4'b1111), 198 | .we_i(1'b0), 199 | .re_i(request), 200 | .data_o(page_table_data), 201 | .mem_wait_o(mem_wait), 202 | 203 | .wb_cyc_o(wb_cyc_o), 204 | .wb_stb_o(wb_stb_o), 205 | .wb_ack_i(wb_ack_i), 206 | .wb_adr_o(wb_adr_o), 207 | .wb_dat_o(wb_dat_o), 208 | .wb_dat_i(wb_dat_i), 209 | .wb_sel_o(wb_sel_o), 210 | .wb_we_o(wb_we_o) 211 | ); 212 | 213 | 214 | 215 | 216 | 217 | endmodule // mmu 218 | 219 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab6/mtime.sv: -------------------------------------------------------------------------------- 1 | // mtime and mtimecmp MMIO register 2 | 3 | module mtime ( 4 | // clk and reset 5 | input wire clk_i, 6 | input wire rst_i, 7 | 8 | // wishbone slave interface 9 | input wire wb_cyc_i, 10 | input wire wb_stb_i, 11 | output reg wb_ack_o, 12 | input wire [31:0] wb_adr_i, 13 | input wire [31:0] wb_dat_i, 14 | output reg [31:0] wb_dat_o, 15 | input wire [3:0] wb_sel_i, 16 | input wire wb_we_i, 17 | 18 | output reg timeout_o, 19 | output reg [63:0] mtime_o 20 | ); 21 | 22 | logic [63:0] mtime; 23 | logic [63:0] mtimecmp; 24 | 25 | assign mtime_o = mtime; 26 | 27 | always_ff @ (posedge clk_i) begin 28 | if (rst_i) begin 29 | mtime <= 64'h0; 30 | mtimecmp <= 64'hffff_ffff_ffff_ffff; 31 | end else begin 32 | if (wb_cyc_i && wb_stb_i && wb_we_i) begin 33 | case (wb_adr_i) 34 | 32'h0200_BFF8: begin // mtime 35 | if (wb_sel_i[0]) mtime[7:0] <= wb_dat_i[7:0]; 36 | if (wb_sel_i[1]) mtime[15:8] <= wb_dat_i[15:8]; 37 | if (wb_sel_i[2]) mtime[23:16] <= wb_dat_i[23:16]; 38 | if (wb_sel_i[3]) mtime[31:24] <= wb_dat_i[31:24]; 39 | end 40 | 32'h0200_BFFC: begin // mtime+4 41 | if (wb_sel_i[0]) mtime[39:32] <= wb_dat_i[7:0]; 42 | if (wb_sel_i[1]) mtime[47:40] <= wb_dat_i[15:8]; 43 | if (wb_sel_i[2]) mtime[55:48] <= wb_dat_i[23:16]; 44 | if (wb_sel_i[3]) mtime[63:56] <= wb_dat_i[31:24]; 45 | end 46 | 32'h0200_4000: begin // mtimecmp 47 | if (wb_sel_i[0]) mtimecmp[7:0] <= wb_dat_i[7:0]; 48 | if (wb_sel_i[1]) mtimecmp[15:8] <= wb_dat_i[15:8]; 49 | if (wb_sel_i[2]) mtimecmp[23:16] <= wb_dat_i[23:16]; 50 | if (wb_sel_i[3]) mtimecmp[31:24] <= wb_dat_i[31:24]; 51 | mtime <= mtime + 1; 52 | end 53 | 32'h0200_4004: begin // mtimecmp+4 54 | if (wb_sel_i[0]) mtimecmp[39:32] <= wb_dat_i[7:0]; 55 | if (wb_sel_i[1]) mtimecmp[47:40] <= wb_dat_i[15:8]; 56 | if (wb_sel_i[2]) mtimecmp[55:48] <= wb_dat_i[23:16]; 57 | if (wb_sel_i[3]) mtimecmp[63:56] <= wb_dat_i[31:24]; 58 | mtime <= mtime + 1; 59 | end 60 | default: 61 | mtime <= mtime + 1; 62 | endcase // case (wb_adr_i) 63 | end else // if (wb_cyc_i && wb_stb_i && wb_we_i) 64 | mtime <= mtime + 1; 65 | end 66 | end 67 | 68 | // send ack immediately 69 | assign wb_ack_o = wb_cyc_i & wb_stb_i; 70 | 71 | // set time out 72 | assign timeout_o = mtime >= mtimecmp; 73 | 74 | always_comb begin 75 | wb_dat_o = 32'h0; 76 | if (wb_cyc_i && wb_stb_i && !wb_we_i) begin 77 | case (wb_adr_i) 78 | 32'h0200_BFF8: // mtime 79 | wb_dat_o = mtime[31:0]; 80 | 32'h0200_BFFC: // mtime+4 81 | wb_dat_o = mtime[63:32]; 82 | 32'h0200_4000: // mtimecmp 83 | wb_dat_o = mtimecmp[31:0]; 84 | 32'h0200_4004: // mtimecmp+4 85 | wb_dat_o = mtimecmp[63:32]; 86 | endcase // case (wb_adr_i) 87 | end 88 | end 89 | endmodule 90 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/lab6/reg_file_32.sv: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | 3 | module reg_file_32 ( 4 | input wire clk, 5 | input wire reset, 6 | input wire [4:0] raddr_a, 7 | input wire [4:0] raddr_b, 8 | input wire [4:0] waddr, 9 | input wire [31:0] wdata, 10 | input wire we, 11 | output logic [31:0] rdata_a, 12 | output logic [31:0] rdata_b 13 | ); 14 | 15 | 16 | // x0 is always 0, so it's not stored. 17 | reg [31:0] reg_store [31:1]; 18 | 19 | 20 | 21 | always_ff @ (posedge clk) begin 22 | if (reset) begin 23 | // I'm not sure whether this would generate a 24 | // good circuit... 25 | for (int i = 1; i <= 31; i++) begin 26 | reg_store[i] <= 0; 27 | end 28 | end else begin 29 | if (we && waddr != 5'd0) begin 30 | reg_store[waddr] <= wdata; 31 | end 32 | end 33 | end // always_ff @ (posedge clk) 34 | 35 | assign rdata_a = raddr_a == 5'd0 ? 32'd0 : reg_store[raddr_a]; 36 | assign rdata_b = raddr_b == 5'd0 ? 32'd0 : reg_store[raddr_b]; 37 | 38 | 39 | 40 | endmodule // reg_file_32 41 | 42 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/vga.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | // 3 | // WIDTH: bits in register hdata & vdata 4 | // HSIZE: horizontal size of visible field 5 | // HFP: horizontal front of pulse 6 | // HSP: horizontal stop of pulse 7 | // HMAX: horizontal max size of value 8 | // VSIZE: vertical size of visible field 9 | // VFP: vertical front of pulse 10 | // VSP: vertical stop of pulse 11 | // VMAX: vertical max size of value 12 | // HSPP: horizontal synchro pulse polarity (0 - negative, 1 - positive) 13 | // VSPP: vertical synchro pulse polarity (0 - negative, 1 - positive) 14 | // 15 | module vga #( 16 | parameter WIDTH = 0, 17 | HSIZE = 0, 18 | HFP = 0, 19 | HSP = 0, 20 | HMAX = 0, 21 | VSIZE = 0, 22 | VFP = 0, 23 | VSP = 0, 24 | VMAX = 0, 25 | HSPP = 0, 26 | VSPP = 0 27 | ) ( 28 | input wire clk, 29 | output wire hsync, 30 | output wire vsync, 31 | output reg [WIDTH - 1:0] hdata, 32 | output reg [WIDTH - 1:0] vdata, 33 | output wire data_enable 34 | ); 35 | 36 | // hdata 37 | always @(posedge clk) begin 38 | if (hdata == (HMAX - 1)) hdata <= 0; 39 | else hdata <= hdata + 1; 40 | end 41 | 42 | // vdata 43 | always @(posedge clk) begin 44 | if (hdata == (HMAX - 1)) begin 45 | if (vdata == (VMAX - 1)) vdata <= 0; 46 | else vdata <= vdata + 1; 47 | end 48 | end 49 | 50 | // hsync & vsync & blank 51 | assign hsync = ((hdata >= HFP) && (hdata < HSP)) ? HSPP : !HSPP; 52 | assign vsync = ((vdata >= VFP) && (vdata < VSP)) ? VSPP : !VSPP; 53 | assign data_enable = ((hdata < HSIZE) & (vdata < VSIZE)); 54 | 55 | endmodule 56 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/wb_arbiter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Generates a Wishbone arbiter with the specified number of ports 4 | """ 5 | 6 | from __future__ import print_function 7 | 8 | import argparse 9 | import math 10 | from jinja2 import Template 11 | 12 | def main(): 13 | parser = argparse.ArgumentParser(description=__doc__.strip()) 14 | parser.add_argument('-p', '--ports', type=int, default=2, help="number of ports") 15 | parser.add_argument('-n', '--name', type=str, help="module name") 16 | parser.add_argument('-o', '--output', type=str, help="output file name") 17 | 18 | args = parser.parse_args() 19 | 20 | try: 21 | generate(**args.__dict__) 22 | except IOError as ex: 23 | print(ex) 24 | exit(1) 25 | 26 | def generate(ports=2, name=None, output=None): 27 | if name is None: 28 | name = "wb_arbiter_{0}".format(ports) 29 | 30 | if output is None: 31 | output = name + ".v" 32 | 33 | print("Opening file '{0}'...".format(output)) 34 | 35 | output_file = open(output, 'w') 36 | 37 | print("Generating {0} port Wishbone arbiter {1}...".format(ports, name)) 38 | 39 | select_width = int(math.ceil(math.log(ports, 2))) 40 | 41 | t = Template(u"""/* 42 | Copyright (c) 2015-2016 Alex Forencich 43 | Permission is hereby granted, free of charge, to any person obtaining a copy 44 | of this software and associated documentation files (the "Software"), to deal 45 | in the Software without restriction, including without limitation the rights 46 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 47 | copies of the Software, and to permit persons to whom the Software is 48 | furnished to do so, subject to the following conditions: 49 | The above copyright notice and this permission notice shall be included in 50 | all copies or substantial portions of the Software. 51 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 52 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 53 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 54 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 55 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 56 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 57 | THE SOFTWARE. 58 | */ 59 | // Language: Verilog 2001 60 | `timescale 1 ns / 1 ps 61 | /* 62 | * Wishbone {{n}} port arbiter 63 | */ 64 | module {{name}} # 65 | ( 66 | parameter DATA_WIDTH = 32, // width of data bus in bits (8, 16, 32, or 64) 67 | parameter ADDR_WIDTH = 32, // width of address bus in bits 68 | parameter SELECT_WIDTH = (DATA_WIDTH/8), // width of word select bus (1, 2, 4, or 8) 69 | parameter ARB_TYPE_ROUND_ROBIN = 0, // select round robin arbitration 70 | parameter ARB_LSB_HIGH_PRIORITY = 1 // LSB priority selection 71 | ) 72 | ( 73 | input wire clk, 74 | input wire rst, 75 | {%- for p in ports %} 76 | /* 77 | * Wishbone master {{p}} input 78 | */ 79 | input wire [ADDR_WIDTH-1:0] wbm{{p}}_adr_i, // ADR_I() address input 80 | input wire [DATA_WIDTH-1:0] wbm{{p}}_dat_i, // DAT_I() data in 81 | output wire [DATA_WIDTH-1:0] wbm{{p}}_dat_o, // DAT_O() data out 82 | input wire wbm{{p}}_we_i, // WE_I write enable input 83 | input wire [SELECT_WIDTH-1:0] wbm{{p}}_sel_i, // SEL_I() select input 84 | input wire wbm{{p}}_stb_i, // STB_I strobe input 85 | output wire wbm{{p}}_ack_o, // ACK_O acknowledge output 86 | output wire wbm{{p}}_err_o, // ERR_O error output 87 | output wire wbm{{p}}_rty_o, // RTY_O retry output 88 | input wire wbm{{p}}_cyc_i, // CYC_I cycle input 89 | {%- endfor %} 90 | /* 91 | * Wishbone slave output 92 | */ 93 | output wire [ADDR_WIDTH-1:0] wbs_adr_o, // ADR_O() address output 94 | input wire [DATA_WIDTH-1:0] wbs_dat_i, // DAT_I() data in 95 | output wire [DATA_WIDTH-1:0] wbs_dat_o, // DAT_O() data out 96 | output wire wbs_we_o, // WE_O write enable output 97 | output wire [SELECT_WIDTH-1:0] wbs_sel_o, // SEL_O() select output 98 | output wire wbs_stb_o, // STB_O strobe output 99 | input wire wbs_ack_i, // ACK_I acknowledge input 100 | input wire wbs_err_i, // ERR_I error input 101 | input wire wbs_rty_i, // RTY_I retry input 102 | output wire wbs_cyc_o // CYC_O cycle output 103 | ); 104 | wire [{{n-1}}:0] request; 105 | wire [{{n-1}}:0] grant; 106 | {% for p in ports %} 107 | assign request[{{p}}] = wbm{{p}}_cyc_i; 108 | {%- endfor %} 109 | {% for p in ports %} 110 | wire wbm{{p}}_sel = grant[{{p}}] & grant_valid; 111 | {%- endfor %} 112 | {%- for p in ports %} 113 | // master {{p}} 114 | assign wbm{{p}}_dat_o = wbs_dat_i; 115 | assign wbm{{p}}_ack_o = wbs_ack_i & wbm{{p}}_sel; 116 | assign wbm{{p}}_err_o = wbs_err_i & wbm{{p}}_sel; 117 | assign wbm{{p}}_rty_o = wbs_rty_i & wbm{{p}}_sel; 118 | {%- endfor %} 119 | // slave 120 | assign wbs_adr_o = {% for p in ports %}wbm{{p}}_sel ? wbm{{p}}_adr_i : 121 | {% endfor %}{ADDR_WIDTH{1'b0}}; 122 | assign wbs_dat_o = {% for p in ports %}wbm{{p}}_sel ? wbm{{p}}_dat_i : 123 | {% endfor %}{DATA_WIDTH{1'b0}}; 124 | assign wbs_we_o = {% for p in ports %}wbm{{p}}_sel ? wbm{{p}}_we_i : 125 | {% endfor %}1'b0; 126 | assign wbs_sel_o = {% for p in ports %}wbm{{p}}_sel ? wbm{{p}}_sel_i : 127 | {% endfor %}{SELECT_WIDTH{1'b0}}; 128 | assign wbs_stb_o = {% for p in ports %}wbm{{p}}_sel ? wbm{{p}}_stb_i : 129 | {% endfor %}1'b0; 130 | assign wbs_cyc_o = {% for p in ports %}wbm{{p}}_sel ? 1'b1 : 131 | {% endfor %}1'b0; 132 | // arbiter instance 133 | arbiter #( 134 | .PORTS({{n}}), 135 | .ARB_TYPE_ROUND_ROBIN(ARB_TYPE_ROUND_ROBIN), 136 | .ARB_BLOCK(1), 137 | .ARB_BLOCK_ACK(0), 138 | .ARB_LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY) 139 | ) 140 | arb_inst ( 141 | .clk(clk), 142 | .rst(rst), 143 | .request(request), 144 | .acknowledge(), 145 | .grant(grant), 146 | .grant_valid(grant_valid), 147 | .grant_encoded() 148 | ); 149 | endmodule 150 | """) 151 | 152 | output_file.write(t.render( 153 | n=ports, 154 | w=select_width, 155 | name=name, 156 | ports=range(ports) 157 | )) 158 | 159 | print("Done") 160 | 161 | if __name__ == "__main__": 162 | main() 163 | 164 | 165 | -------------------------------------------------------------------------------- /thinpad_top.srcs/sources_1/new/wb_mux.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Generates a Wishbone multiplexer with the specified number of ports 4 | """ 5 | 6 | from __future__ import print_function 7 | 8 | import argparse 9 | import math 10 | from jinja2 import Template 11 | 12 | def main(): 13 | parser = argparse.ArgumentParser(description=__doc__.strip()) 14 | parser.add_argument('-p', '--ports', type=int, default=2, help="number of ports") 15 | parser.add_argument('-n', '--name', type=str, help="module name") 16 | parser.add_argument('-o', '--output', type=str, help="output file name") 17 | 18 | args = parser.parse_args() 19 | 20 | try: 21 | generate(**args.__dict__) 22 | except IOError as ex: 23 | print(ex) 24 | exit(1) 25 | 26 | def generate(ports=2, name=None, output=None): 27 | if name is None: 28 | name = "wb_mux_{0}".format(ports) 29 | 30 | if output is None: 31 | output = name + ".v" 32 | 33 | print("Opening file '{0}'...".format(output)) 34 | 35 | output_file = open(output, 'w') 36 | 37 | print("Generating {0} port Wishbone mux {1}...".format(ports, name)) 38 | 39 | select_width = int(math.ceil(math.log(ports, 2))) 40 | 41 | t = Template(u"""/* 42 | 43 | Copyright (c) 2015-2016 Alex Forencich 44 | 45 | Permission is hereby granted, free of charge, to any person obtaining a copy 46 | of this software and associated documentation files (the "Software"), to deal 47 | in the Software without restriction, including without limitation the rights 48 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 49 | copies of the Software, and to permit persons to whom the Software is 50 | furnished to do so, subject to the following conditions: 51 | 52 | The above copyright notice and this permission notice shall be included in 53 | all copies or substantial portions of the Software. 54 | 55 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 56 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 57 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 58 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 59 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 60 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 61 | THE SOFTWARE. 62 | 63 | */ 64 | 65 | // Language: Verilog 2001 66 | 67 | `timescale 1 ns / 1 ps 68 | 69 | /* 70 | * Wishbone {{n}} port multiplexer 71 | */ 72 | module {{name}} # 73 | ( 74 | parameter DATA_WIDTH = 32, // width of data bus in bits (8, 16, 32, or 64) 75 | parameter ADDR_WIDTH = 32, // width of address bus in bits 76 | parameter SELECT_WIDTH = (DATA_WIDTH/8) // width of word select bus (1, 2, 4, or 8) 77 | ) 78 | ( 79 | input wire clk, 80 | input wire rst, 81 | 82 | /* 83 | * Wishbone master input 84 | */ 85 | input wire [ADDR_WIDTH-1:0] wbm_adr_i, // ADR_I() address input 86 | input wire [DATA_WIDTH-1:0] wbm_dat_i, // DAT_I() data in 87 | output wire [DATA_WIDTH-1:0] wbm_dat_o, // DAT_O() data out 88 | input wire wbm_we_i, // WE_I write enable input 89 | input wire [SELECT_WIDTH-1:0] wbm_sel_i, // SEL_I() select input 90 | input wire wbm_stb_i, // STB_I strobe input 91 | output wire wbm_ack_o, // ACK_O acknowledge output 92 | output wire wbm_err_o, // ERR_O error output 93 | output wire wbm_rty_o, // RTY_O retry output 94 | input wire wbm_cyc_i, // CYC_I cycle input 95 | {%- for p in ports %} 96 | 97 | /* 98 | * Wishbone slave {{p}} output 99 | */ 100 | output wire [ADDR_WIDTH-1:0] wbs{{p}}_adr_o, // ADR_O() address output 101 | input wire [DATA_WIDTH-1:0] wbs{{p}}_dat_i, // DAT_I() data in 102 | output wire [DATA_WIDTH-1:0] wbs{{p}}_dat_o, // DAT_O() data out 103 | output wire wbs{{p}}_we_o, // WE_O write enable output 104 | output wire [SELECT_WIDTH-1:0] wbs{{p}}_sel_o, // SEL_O() select output 105 | output wire wbs{{p}}_stb_o, // STB_O strobe output 106 | input wire wbs{{p}}_ack_i, // ACK_I acknowledge input 107 | input wire wbs{{p}}_err_i, // ERR_I error input 108 | input wire wbs{{p}}_rty_i, // RTY_I retry input 109 | output wire wbs{{p}}_cyc_o, // CYC_O cycle output 110 | 111 | /* 112 | * Wishbone slave {{p}} address configuration 113 | */ 114 | input wire [ADDR_WIDTH-1:0] wbs{{p}}_addr, // Slave address prefix 115 | input wire [ADDR_WIDTH-1:0] wbs{{p}}_addr_msk{% if not loop.last %},{% else %} {% endif %} // Slave address prefix mask 116 | {%- endfor %} 117 | ); 118 | {% for p in ports %} 119 | wire wbs{{p}}_match = ~|((wbm_adr_i ^ wbs{{p}}_addr) & wbs{{p}}_addr_msk); 120 | {%- endfor %} 121 | {% for p in ports %} 122 | wire wbs{{p}}_sel = wbs{{p}}_match{% if p > 0 %} & ~({% for q in range(p) %}wbs{{q}}_match{% if not loop.last %} | {% endif %}{% endfor %}){% endif %}; 123 | {%- endfor %} 124 | 125 | wire master_cycle = wbm_cyc_i & wbm_stb_i; 126 | 127 | wire select_error = ~({% for p in ports %}wbs{{p}}_sel{% if not loop.last %} | {% endif %}{% endfor %}) & master_cycle; 128 | 129 | // master 130 | assign wbm_dat_o = {% for p in ports %}wbs{{p}}_sel ? wbs{{p}}_dat_i : 131 | {% endfor %}{DATA_WIDTH{1'b0}}; 132 | 133 | assign wbm_ack_o = {% for p in ports %}wbs{{p}}_ack_i{% if not loop.last %} | 134 | {% endif %}{% endfor %}; 135 | 136 | assign wbm_err_o = {% for p in ports %}wbs{{p}}_err_i | 137 | {% endfor %}select_error; 138 | 139 | assign wbm_rty_o = {% for p in ports %}wbs{{p}}_rty_i{% if not loop.last %} | 140 | {% endif %}{% endfor %}; 141 | {% for p in ports %} 142 | // slave {{p}} 143 | assign wbs{{p}}_adr_o = wbm_adr_i; 144 | assign wbs{{p}}_dat_o = wbm_dat_i; 145 | assign wbs{{p}}_we_o = wbm_we_i & wbs{{p}}_sel; 146 | assign wbs{{p}}_sel_o = wbm_sel_i; 147 | assign wbs{{p}}_stb_o = wbm_stb_i & wbs{{p}}_sel; 148 | assign wbs{{p}}_cyc_o = wbm_cyc_i & wbs{{p}}_sel; 149 | {% endfor %} 150 | 151 | endmodule 152 | 153 | """) 154 | 155 | output_file.write(t.render( 156 | n=ports, 157 | w=select_width, 158 | name=name, 159 | ports=range(ports) 160 | )) 161 | 162 | print("Done") 163 | 164 | if __name__ == "__main__": 165 | main() 166 | 167 | --------------------------------------------------------------------------------