├── .DS_Store ├── LICENSE ├── README.md └── sim ├── ddr_ref_model ├── MemoryArray.sv ├── StateTable.sv ├── StateTableCore.sv ├── arch_defines.v ├── arch_package.sv ├── ddr4_model.sv ├── ddr4_sdram_model_wrapper.sv ├── ddr_model.sv ├── interface.sv ├── proj_package.sv └── timing_tasks.sv ├── ip ├── .Xil │ └── .ddr4_ctrl.xcix.lock ├── ddr4_ctrl.xci └── ddr4_ctrl.xcix ├── scripts └── import_sim_env.tcl └── source ├── aliuyun_faas_sim_tb.sv ├── aliyun_faas_agent.sv ├── aliyun_faas_alite_agent.sv ├── aliyun_faas_alite_driver.sv ├── aliyun_faas_base_pkg.sv ├── aliyun_faas_card_model.sv ├── aliyun_faas_ddr_ref_model.sv ├── aliyun_faas_dma_agent.sv ├── aliyun_faas_dma_driver.sv ├── aliyun_faas_driver.sv ├── aliyun_faas_interfaces.sv ├── aliyun_faas_interrupt_agent.sv ├── aliyun_faas_interrupt_driver.sv ├── aliyun_faas_sim_env.sv ├── aliyun_faas_sim_top.sv ├── aliyun_faas_xdma_agent.sv └── aliyun_faas_xdma_driver.sv /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aliyun/alibabacloud-fpga/9973e5b4219c83ef9b96282f5cc1937eaec93e90/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # alibabacloud-fpga 2 | #该平台代码用于仅阿里云FaaS(FPGA as a Service)HDL逻辑仿真 3 | #适用软件版本:Vivado-2018.2、Vivado-2019.1 4 | #使用方式: 5 | 1、拷贝sim文件夹至hdl工程下与hw在同一目录下 6 | 2、在创建的vivado工程中执行sim/scripts/import_sim_env.tcl 7 | 3、在aliyun_faas_sim_tb.sv文件中创建用户个人testcase 8 | #userapi 9 | #在aliyun_faas_sim_env.sv文件中,aliyun_faas_sim_env class提供了调用仿真平台进行仿真的用户API接口,主要包含axi4-lite、xdma、dma、中断接口的使用: 10 | # 11 | #中断接口 12 | #中断接口主要用于使能、关闭中断功能,及中断响应清除 13 | //=================================================================================== 14 | //user api:faas_int_enable() 15 | //enable the interrupt function 16 | //=================================================================================== 17 | task faas_int_enable(); 18 | //=================================================================================== 19 | //user api:faas_int_close() 20 | //close the interrupt function 21 | //=================================================================================== 22 | task faas_int_close(); 23 | //=================================================================================== 24 | //user api: faas_int_flag_clear() 25 | //int_num: interrupt number 26 | //在中断处理函数中完成系统中断处理后清除中断号int_num对应的中断标志 27 | //=================================================================================== 28 | task automatic faas_int_flag_clear(input logic [$clog2(`INTERRUPT_WIDTH)-1:0] int_num); 29 | 30 | #AXI4-Lite总线读写 31 | #ALITE API主要提供对alite接口的读写函数,用户无需关系ALITE时序细节,通过相应API即可完成数据的读写, 32 | #所提供的两个读写函数中channel参数用于标识用于正常的testbench读写还是在中断处理中的读写。 33 | //=================================================================================== 34 | //user api: faas_alite_write() 35 | //waddr: alite write addr 36 | //wdata: alite write data 37 | //channel: 0:used to write in application 38 | // 1:used to write in interrupt 39 | //state rerturn the write state,equal to ali_lite bresp signals 40 | //在中断处理函数中调用faas_alite_write时channel指定为1,否则指定为0 41 | //=================================================================================== 42 | task automatic faas_alite_write(input [`ALITE_AWADDR_WIDTH-1:0] waddr, 43 | input [`ALITE_WDATA_WIDTH-1:0] wdata, 44 | input channel, 45 | output[`ALITE_BRESP_WIDTH-1:0] state 46 | ); 47 | //=================================================================================== 48 | //user api:faas_alite_read() 49 | //raddr: alite read addr 50 | //rdata: alite read data 51 | //channel: 0:used to read in application 52 | // 1:used to read in interrupt 53 | //state rerturn the read state,equal to ali_lite rresp signals 54 | //在中断处理函数中调用faas_alite_write时channel指定为1,否则指定为0 55 | //=================================================================================== 56 | task automatic faas_alite_read(input [`ALITE_ARADDR_WIDTH-1:0] raddr, 57 | input channel, 58 | output [`ALITE_RRESP_WIDTH-1:0] state, 59 | output [`ALITE_RDATA_WIDTH-1:0] rdata 60 | ); 61 | #XDMA接口读写 62 | #faas_xdma_write() 函数用于用户对XDMA的写通道进行访问请求,其中参数wdata[]采用动态数组实现,数据格式 63 | #为unsigned byte,用户无需关心axi4协议要求,只需注入待写入地址基址waddr及待写入数据wdata即可,FAAS SIM #ENV会自动进行数据的分割分发。同时针对不同类型的待写入数据(int、float等),用户可在此函数基础上进行二次开发。 64 | #faas_xdma_read()函数用于用户对XMDA读通道进行数据访问请求,对于xdma读的乱序传输等要求,为给用户提供更大的 65 | #自由度,此处用户应注意raddr及length的参数设置保证读取数据范围在4K边界范围内(平台中已添加地址检测)。同时 66 | #针对不同类型的待写入数据(int、float等),用户可在此函数基础上进行二次开发。 67 | #两个读写函数中channel参数用于标识用于正常的testbench读写还是在中断处理中的读写。 68 | //=================================================================================== 69 | //user api:faas_xdma_write() 70 | //wdata: xdma write data 71 | //waddr: xdma write addr 72 | //channel: 0:used to write in application 73 | // 1:used to write in interrupt 74 | //state rerturn the write state,equal to axi_xdma bresp signals 75 | //在中断处理函数中调用faas_alite_write时channel指定为1,否则指定为0 76 | //=================================================================================== 77 | task automatic faas_xdma_write(input byte unsigned wdata[], 78 | input [`XDMA_AWADDR_WIDTH-1:0] waddr, 79 | input channel, 80 | output[`XDMA_BRESP_WIDTH-1:0] state 81 | ); 82 | //=================================================================================== 83 | //user api:faas_xdma_read() 84 | //raddr: xdma read addr 85 | //length: read length,not exceed 4096 86 | //id: id number used in xdma read channel,euqal to arid 87 | //channel: 0:used to write in application 88 | // 1:used to write in interrupt 89 | //rdata: return the read data 90 | //state rerturn the write state,equal to axi_xdma rresp signals 91 | //=================================================================================== 92 | task automatic faas_xdma_read(input [`XDMA_ARADDR_WIDTH-1:0] raddr, 93 | input int length, 94 | input [`XDMA_ARID_WIDTH-1:0] id, 95 | input channel, 96 | output byte unsigned rdata[], 97 | output [`XDMA_RRESP_WIDTH-1:0] state 98 | ); 99 | #DMA接口读写 100 | #由于DMA操作仿真平台为slave port,故而DMA的读写操作由DUT发起,faas_dma_wdata_fetch() 101 | #函数用于获取DMA写至host端的数据,而faas_dma_rdata_update()用于将待用于DMA读取的数据写至memory cache。 102 | #由于两个函数读写对象为FAAS SIM ENV中的memory cache,故而对于地址及写入数据长度均无限制,针对不同类型的待 103 | #写入数据(int、float等),用户可在此函数基础上进行二次开发。 104 | #两个读写函数中channel参数用于标识用于正常的testbench读写还是在中断处理中的读写。 105 | //=================================================================================== 106 | //user api:faas_dma_wdata_fetch() 107 | //get the data write form the dma channel 108 | //waddr: dma write addr 109 | //length: fetch data length 110 | //channel: 0:used to write in application 111 | // 1:used to write in interrupt 112 | //wdata: return the wdata dma write 113 | //state: return the state; 114 | //=================================================================================== 115 | task automatic faas_dma_wdata_fetch(input [`DMA_AWADDR_WIDTH-1:0] waddr, 116 | input int length, 117 | input channel, 118 | output byte unsigned wdata[], 119 | output state 120 | ); 121 | //=================================================================================== 122 | //user api:faas_dma_rdata_update() 123 | //get the data read ro the dma channel 124 | //raddr: dma read addr 125 | //rdata[]: the rdata dma read 126 | //channel: 0:used to read data update in application 127 | // 1:used to read data update in interrupt 128 | //state: return the state; 129 | //=================================================================================== 130 | task automatic faas_dma_rdata_update(input [`DMA_AWADDR_WIDTH-1:0] raddr, 131 | input byte unsigned rdata[], 132 | input channel, 133 | output state 134 | ); 135 | #其他接口 136 | //=================================================================================== 137 | //user api:faas_wait_for_ddr_cal_done() 138 | //wait for the ddr reference model cal done 139 | //用户的rtl设计中若使用了ddr接口,则在testcase中应首先调用该api等待ddr校准完成 140 | //=================================================================================== 141 | task faas_wait_for_ddr_cal_done(); -------------------------------------------------------------------------------- /sim/ddr_ref_model/StateTable.sv: -------------------------------------------------------------------------------- 1 | `pragma protect begin_protected 2 | `pragma protect version = 1 3 | `pragma protect encrypt_agent = "XILINX" 4 | `pragma protect encrypt_agent_info = "Xilinx Encryption Tool 2015" 5 | `pragma protect key_keyowner = "Cadence Design Systems.", key_keyname = "cds_rsa_key", key_method = "rsa" 6 | `pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 64) 7 | `pragma protect key_block 8 | JFT7olhrsTCn+ua1lge2xzJc6xV9zehjCT5vMCN6GPUIf8dvvCgCGnH0PryzpF2T3u8VgDN2GJ1d 9 | OEw+xSU4XQ== 10 | 11 | `pragma protect key_keyowner = "Synopsys", key_keyname = "SNPS-VCS-RSA-2", key_method = "rsa" 12 | `pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 128) 13 | `pragma protect key_block 14 | DWN4fzIO1W1DFLPBoYl4OYwBRXztzK+LBLr4z1/82R1MFFbfQvskKIvCWAR1MRziyWgaYO9LnzdX 15 | xA7PpBQLU0K79QvubOk6+a1Ss5+eO9Ildkm7dEXBb9XwHNBHUMhEH1bMJRHMA7tfx570l4MEM/yL 16 | 5BJy8k1v9ZEb1wyr7fw= 17 | 18 | `pragma protect key_keyowner = "Aldec", key_keyname = "ALDEC15_001", key_method = "rsa" 19 | `pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256) 20 | `pragma protect key_block 21 | GsloE+YSC8eF8ZjGMHJ9cowlE4zZtchVLe39wyJxfV/9Su4KfXPknTKrqPtB7w75vtJ6aUF5WgsZ 22 | D9WzwYFAkocFRmoBZGcZpl9cKg1+oj2xsKxv4CyJjZrIfriVNBoQsjv3mv2Pl1cUU6whc+VGaZ2S 23 | WQqq0AGeen3e5hh2jR8C6VcXmzNUEOpUXGJXdLs8uTMLVNhDrRGT52GKlJwAauElnA1GRZlDU/4P 24 | tduimEh1lJxNW9cQKrEhyaw6GHOKSpCQYKa6iz2hcaTTM5ukIifpRBsViA9EA019NKau7wX5do15 25 | 44WrGQ6Pku2+p41P5gXXGoIC9PJUqOVHrJJqvA== 26 | 27 | `pragma protect key_keyowner = "ATRENTA", key_keyname = "ATR-SG-2015-RSA-3", key_method = "rsa" 28 | `pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256) 29 | `pragma protect key_block 30 | dm2h0SfQUU6hjNgoA0pqw4ElcOLURiRQMlNp8Ljva1cvpbZdr23LtP2d8w5NNgrg4ofcEkTfPoCi 31 | qeFAQgrfNAYSAHzgC4BJaxJwYs9imY4ko6Sy1O42y0az8iGpGoKBSvNSX5xuLUjwPt785DF7bxnT 32 | pJe3l4kU/rKQ/JHJSYZDavZhz7Lto2otnDfEKCpKOHR59wSuCDIJFV9vgrCQJiMLGTLRYl+Q057D 33 | cARSN+sOdWxzBHZdChGlYm9NS44xOvOnNqQPykmp87UohNE5kXrEfABQHVlCHBrp1yNnZwGPmB/0 34 | EWp+59x7lh8LJKJv2R+xoENeBLJSbODhJrg+zA== 35 | 36 | `pragma protect key_keyowner = "Xilinx", key_keyname = "xilinxt_2017_05", key_method = "rsa" 37 | `pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256) 38 | `pragma protect key_block 39 | KLXlplMxMOr1UBh/V5AsV69JA8GA3+Vp5E8rfDFcFwrKpB0qUC98FVfyYjX0wZ7hvcN0+jIU4kWT 40 | vFIuyoldYnLu7XbvYamToCH9VsQSxHreBi3oMuK7rcmOPb4y7t0YHitun763RL73Fm9GWd2IEjlU 41 | HOmVreB8GHjZEMSCjh6O39X0h4Xb4LfoWf0i6Bg08GyZ3e+Rbvu4NPstL9O+YLzBTo2FvlWx9JZU 42 | 7OWmMADvdgLxnJDZC7hGmOW1pFgsEVLQYNOnmSPpBLU7R/oDo12I2dfWTARjOaDdAGCKyXLK5uFD 43 | b9957h/Z204aRFv25nyrJMZ0U0DgVcbsJFjaeg== 44 | 45 | `pragma protect key_keyowner = "Mentor Graphics Corporation", key_keyname = "MGC-VELOCE-RSA", key_method = "rsa" 46 | `pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 128) 47 | `pragma protect key_block 48 | i8S77Q8PhqhUkfeFveat2i35TbsLYBPdAL2QEQ24FrUhgbaJI98QdPzn95fQYWjX8bBYO6c7S4gI 49 | XiyWHFsxrYW9TGaKwZYZ2HLQIYrp+WDKsCsXA/CidvbAZW+M2UelTLU+isKkz7R5gdwrMiFTa6/J 50 | LJf6mpx/GKxxwOfMNnc= 51 | 52 | `pragma protect key_keyowner = "Mentor Graphics Corporation", key_keyname = "MGC-VERIF-SIM-RSA-2", key_method = "rsa" 53 | `pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 256) 54 | `pragma protect key_block 55 | Gu0KbdM1rFg2ntk8q9kyOlc0bktBZ3dwHmgv3XVJwWJJ/JvhU1/FpUsRHKoW3jrRV3KqhkKbHHap 56 | qmHQ3yAa5guKP9HWchAtStr/o/5/gykqC/E9gv5nOb9WTzVEnIuivDNYb3V1jYeiUwp1D1udgk1c 57 | e/UQbOJ1prqLDgwjmJHJnbgc6vStOjj4AwjvAnAYPJiolFJIVScEp7Lk7zWE5wY164tJV7VT3hPV 58 | GG5rJM3+KZUD8K1NQfH3EpQsi2yar+87kFlgJznKw8ABh/jZe5skBIXFxZOHuK0ihGEH/KNJ1wVl 59 | 2WA2hx5dSaQuxCSLW3A8LUpsdcC5JHh16ITaNQ== 60 | 61 | `pragma protect data_method = "AES128-CBC" 62 | `pragma protect encoding = (enctype = "BASE64", line_length = 76, bytes = 3136) 63 | `pragma protect data_block 64 | /uyJlef/Ij1AWiQn0ynjAcNR4xRu6tMAHifLxAVQEI+G9yNscU8+3BBvfZXI6L0PkAPvv6uiQUPZ 65 | DuGYHN/e/S9IgxrXjSzp/lYlFPyXCsxAcTR26wqTzqsZ4EjPB9ffs+666dZqZds1Zk4DkYFvIyhy 66 | 3p0YtKjVFYNeRQAzlWupPlaSHP9VurkwU7JSeeshjbhvDg8UgcL1idSWEzEuIlaE8ok7y7Sy5U4F 67 | uqxYo/kiALBMq6yf9RCUyH+GtgQDIXnUHyauHSUythXF7K5SQSdokLvihpm6lKhVKYnT9lAqHHis 68 | PV7Bv/kE1RBrtp+nJJryDNfU7gvJ/TMlu06SbjLADNoCeN+oI/B3z1cGL6lKYhplpd+uhkwno9E/ 69 | MP9bFnzEpfckmgjVGXkSnsDUOTxuZsfGjtzukHYvzm40opNyAh4M2ZU0rzWfQkJZ5FGqqJogUwiV 70 | 8Pio/ouU9JBE+KvCpsojtf/uQNwjJluHleoE68IX1LdsJLHm2e9hK3esDwBkxdyNc7BafCoRzNrX 71 | 2KczzIN8XvH9BMz4DTdZT07XvgJFz+GrfuDkl+sVSUGfzZrCsvsx1gmfaytxz6BUv7qJI5DN+8RR 72 | FXXZjyczq4XJKIicRiHle8qi5mizahMBeijXD1DxyKELbOCrbrVTSB98iP5mU/fElI7SFFpLWvU3 73 | x4ZjizTD7FjGJAiein6oxY+DBNAnTpTIRXjsnP4mTPrmSV32EpCp/0bMY1OS7BYsM0QvsOcCZoAH 74 | nVK1X/LSdoq70A7/J1UkxsZ6zqK2Bb5UCTTn/n/Dmy+EqsooRzc+QZCDnnQogzLsQ+YcVEwn7fRj 75 | 6YvoLcuSRwpo/oBkyg5BB+mzR1XLLjSK8rgf3WZIrIbCv9qeTH5G95MVqRG+P83nxFKenZACf5uv 76 | 5DZW/+T02FFs19ab+2D3WckGCwKctTms3W6bGMR6ywQGCcc5mWMMwlOHHI7uNMV/L4jad+9BrJ1E 77 | hgsq4bS28zEFK7yWffd/zS0q3ZuS82ekjZH0MnNN7cuzammQtjYUgO0A41ftEo0K0llaWj4jiBYb 78 | MDYQVc0weMLG+mv4kDKiUijQshH+94DKdYVqOyVbuFjYxrTXmwlLavWgsd6cngAzAmuZ4G9EmGWz 79 | QCA8DHlPfUMNExZCYoRtGH5s3Feaw7k2ACIjydh05RnXyuPx7iYBl19cinhwlYlIg7Sqk9F6qpVd 80 | IBgvI6Z9s5/e2uIZUj+QY57OAEA0LKBgRYNsh/dLGHm4y4VvqAACy8UbHGKKrokGYwWb9C+vnM9x 81 | cfm13eGiV2YXdM4SiGF7tbPrmJ2hxFj1yq2s28FteJfW2pSug3NXgVPv0MF++AplLP2feFLqqqZa 82 | fFE9APU+Qp2bIl32NL16Nt4EX75OhRs19mZpn4xiXvkH4z4XfzkP4CeuEc4qZHSjWz+gQMkuesjV 83 | LD3Az7UEwW76BcsycoMH1rFREaoHtfVjEQ1OaaGXRXXyaavtEOQG5ptIrffe6kKfWFc1Sh05vBJQ 84 | YvbwZIsyZ+3a3j53OgIAdWAVsZiTDUI1+vsGuRhIreL/FY7Ry8ahw8aZn7ky5rvUbiH10CC+TXRT 85 | aPV1m+dDb1NnoELmtf6PIjElz16tRGb5RnEmOxeMklvfveuyXaRsTionxLpKvLx6EmaHQI5Q1W95 86 | lRRp5CtrSavp2tDa/c+DZWvLx0i2HyBNxcUx/OEOvFxaN4q/ufgOxHI+rhBzMJNrTAr32H5g/USe 87 | S4G+MdHpZnxtZyghtCsMDGGkmtnnJbpNW3DCuyDHEsSncZik2fnOu1i1BTC7wyr39QOo6udhsc1d 88 | j+Nl20EX7PXJA3iijEiibJKjcVud3KhrZFNdMCmGBi0ClO7uyCaOfm3GhZojpVqs3V1mHFJb1xWI 89 | j/bk+wXaEFIN7TGMCn1NG57JiJhD6P+fNzJQDPl2YY04CSJEy12bigWmSFZHWqPWzpdSJ6a1Vpez 90 | 9ZJCC0UDZq5xVBfW5s1B1G/j3CzbHbt3LZ6ss4pK+ffPECFmsLmuGbKEA6/7908W9fnWqTrAP43A 91 | CerePBJ3pyN1GXI1cVRv/FEQbnynESTBQDhmYencDv9jcn1rOsTOz1w/u4CIAvcWb3Ohi+2tSVz6 92 | v365I0+5a44KoQcyxxNL8JFxCK2bAtxqZsVdtbpci1RDJJbXBKE7fr92SFzIeJDho1LH4OGUUFUo 93 | 34B0KYc/knSoTQaCP5eEqIkLaqJIwI/U1Zy5sbwftub1N8OPzxUwG7HH9W2LxymNXuf912e325J1 94 | OgNAGX0at6AIfeAxWiAPfGrvUs+pfSVMeu/L/hYxpzNCV43xtnkwJXJWXRQ7LNJ9DpSkrfGzOuNp 95 | AEeW0AGXQaHUMPKqoVYZKUnxDDxDrrtJQJeiWrYXl9XVZir1nwxJwqWtRHN+TrfOSTMJkPMojO7G 96 | ppb9hPTDDC0/4MRmvh74ee+Q9o8RrZjiwU86xkjw9aVk8OAwrm3YqLexwFo7xy25KwKi8SJeDKrm 97 | xa59qeltNpIDb+oo1KllIoV7kE+QrOPXatdYa0Mk2Br2ENSSCkrrtyweMvHrmh577iUUHHn1hYba 98 | AAJyXApzpc5Zj8xjkropP9AhbIJ0Ds1mVJh9VZEYVHu6MOuZOP4jeBfUwnvkprUPB/nyDYT0wX3J 99 | O0fp9+TYIUC/LnYFhMskK7wur17Tes7e/ZK/JrMPzgua8ak25cx22J8odHpiQczsPH/0ed16TVsO 100 | 069zyKCsdhWl4ZkPhUrZWlE1cLsQtEG4TigOLHFXQzGtrUI52IgmfvS8amilXROaDkXNZH8gtUZL 101 | DBmIUH++ISeoab5EZu9kucGGU0qtnirPdqMx1iaJkA2W0bhrQM9L5yvSBRGnoI5jkiZSQxCs2Jad 102 | RXxRlaMbO0lWoW+NHLenmlCZgg8kdtizLBwakmObmFMEftOucUeB4VpM/UjeM14iiYAUyfhooxzA 103 | CwSXs8DS3UBL1THmyCgUxVaTVCQzZ4NuOkDodtO9U7tGib0NrsHp1IItrdS3aYZ2xIASoEBJKuCA 104 | /vgbd48vkNy7FZ6m/xENerJgaguQZFEUcWcQrabVh5DhNKCYkuHVOcYFPGZMqNi8q49IfLghc58M 105 | SQ0zoSSecM8RlU+eyx3MKvAtLJUievVGDyj2Yx3aJlTrGlMaETAjj4RM9ZNiwpcHeHXZtYxS80Ri 106 | IOKgrDXHf5ATWvM+VPNtlXTXAQV0rH9rA3q3ankXk/qYsPSpGZJdTqY/rNVg5H6YacKrJyswMW5E 107 | 0eZ72eEduNdhLMWFzpnflKR9J9FccF8xS56URIRlhGQjG+KnvRiyfLS+RIVa5VJziuGQSbFLAnKk 108 | 1s0QjywE4mKmS0xr4qfYqEpUQJcd54urK2XU05JfOS0qx56llE4oEhmKTuaQU4D9CqClR5zjwZ2I 109 | sbld9J7JLHOSxyPifDqd9BB+DW6i4R3nQ+sY46LFMWD3kvSUkNLi3Y+JjWudmC2npwrrHTV/4Xcr 110 | ZPL+dl8tY6qaGWbZRHMNPdJM4QFO/vyx5v0zDNFteaVhNUynKoQGWafczZEO4abyO6dDgQ6bKv+H 111 | AopJLcmauGaRyuyxAdlskPeTlJCY2Ics71I7sD6WS9xhome58G1aOfagNUkxTknGIQS+IWlzOjol 112 | 8ihDz+S9elJNltQCBZA5N670l9/5QUxoOtyBrRSUC1z0AvfFBlwp15tQhI9NpniMXdZfDVvBBBtU 113 | 8dAkX00NfHdyBd9+VY6PBnHvKAiOtrG1BJVFaILINRWPnSRkApAbjhve+zGUd2+pEYayQu099L1E 114 | 1WYZRKPEqYmOdUbpzWMqEyb18bNYdzauoVEnuMobzyVEB1UBfQ5GGRt/FDbTAjSkLsay8lrST79V 115 | TzQJCREBl1DAUbZJW3IWTYNN2Muj+V9XSztqcBDaxoIouAPwXEGPye01UivI8yKmMa1OqmaJdDaP 116 | F1zhW3wJq1k5d1tRTxLWjKMos5t5Ui1Q7/uXiNnbCA0dJq8B65fwxOUGZu16etGWT6XAmwKlb+pZ 117 | SjW8xb6WVqemu7dAOvdZnhW+gQKTcDTqHRooP04IJ9wNuEEqEK2eA/pg7HvQ+2TYnqdtvMBFnF+y 118 | m+XimV+RFyroRQ4EStBgm7RTuyiKSsNKF599YZDlOvikFCUo31YLzVtg8HZEssv4Nc4T7oRQj6Gg 119 | kg== 120 | `pragma protect end_protected 121 | -------------------------------------------------------------------------------- /sim/ddr_ref_model/arch_defines.v: -------------------------------------------------------------------------------- 1 | // MICRON TECHNOLOGY, INC. - CONFIDENTIAL AND PROPRIETARY INFORMATION 2 | `ifdef DDR4_2G_X4 3 | `define DDR4_X4 4 | `define DDR4_2G 5 | `endif 6 | `ifdef DDR4_2G_X8 7 | `define DDR4_X8 8 | `define DDR4_2G 9 | `endif 10 | `ifdef DDR4_2G_X16 11 | `define DDR4_X16 12 | `define DDR4_2G 13 | `endif 14 | `ifdef DDR4_4G_X4 15 | `define DDR4_X4 16 | `define DDR4_4G 17 | `endif 18 | `ifdef DDR4_4G_X8 19 | `define DDR4_X8 20 | `define DDR4_4G 21 | `endif 22 | `ifdef DDR4_4G_X16 23 | `define DDR4_X16 24 | `define DDR4_4G 25 | `endif 26 | `ifdef DDR4_8G_X4 27 | `define DDR4_X4 28 | `define DDR4_8G 29 | `endif 30 | `ifdef DDR4_8G_X8 31 | `define DDR4_X8 32 | `define DDR4_8G 33 | `endif 34 | `ifdef DDR4_8G_X16 35 | `define DDR4_X16 36 | `define DDR4_8G 37 | `endif 38 | `ifdef DDR4_16G_X4 39 | `define DDR4_X4 40 | `define DDR4_16G 41 | `endif 42 | `ifdef DDR4_16G_X8 43 | `define DDR4_X8 44 | `define DDR4_16G 45 | `endif 46 | `ifdef DDR4_16G_X16 47 | `define DDR4_X16 48 | `define DDR4_16G 49 | `endif 50 | 51 | -------------------------------------------------------------------------------- /sim/ddr_ref_model/ddr4_sdram_model_wrapper.sv: -------------------------------------------------------------------------------- 1 | 2 | 3 | /****************************************************************************** 4 | // (c) Copyright 2013 - 2014 Xilinx, Inc. All rights reserved. 5 | // 6 | // This file contains confidential and proprietary information 7 | // of Xilinx, Inc. and is protected under U.S. and 8 | // international copyright and other intellectual property 9 | // laws. 10 | // 11 | // DISCLAIMER 12 | // This disclaimer is not a license and does not grant any 13 | // rights to the materials distributed herewith. Except as 14 | // otherwise provided in a valid license issued to you by 15 | // Xilinx, and to the maximum extent permitted by applicable 16 | // law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND 17 | // WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES 18 | // AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING 19 | // BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- 20 | // INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and 21 | // (2) Xilinx shall not be liable (whether in contract or tort, 22 | // including negligence, or under any other theory of 23 | // liability) for any loss or damage of any kind or nature 24 | // related to, arising under or in connection with these 25 | // materials, including for any direct, or any indirect, 26 | // special, incidental, or consequential loss or damage 27 | // (including loss of data, profits, goodwill, or any type of 28 | // loss or damage suffered as a result of any action brought 29 | // by a third party) even if such damage or loss was 30 | // reasonably foreseeable or Xilinx had been advised of the 31 | // possibility of the same. 32 | // 33 | // CRITICAL APPLICATIONS 34 | // Xilinx products are not designed or intended to be fail- 35 | // safe, or for use in any application requiring fail-safe 36 | // performance, such as life-support or safety devices or 37 | // systems, Class III medical devices, nuclear facilities, 38 | // applications related to the deployment of airbags, or any 39 | // other applications that could lead to death, personal 40 | // injury, or severe property or environmental damage 41 | // (individually and collectively, "Critical 42 | // Applications"). Customer assumes the sole risk and 43 | // liability of any use of Xilinx products in Critical 44 | // Applications, subject only to applicable laws and 45 | // regulations governing limitations on product liability. 46 | // 47 | // THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS 48 | // PART OF THIS FILE AT ALL TIMES. 49 | ******************************************************************************/ 50 | // ____ ____ 51 | // / /\/ / 52 | // /___/ \ / Vendor : Xilinx 53 | // \ \ \/ Version : 1.0 54 | // \ \ Application : MIG 55 | // / / Filename : ddr4_sdram_model_wrapper.sv 56 | // /___/ /\ Date Last Modified : $Date: $ 57 | // \ \ / \ Date Created : Fri Nov 14 2014 58 | // \___\/\___\ 59 | // 60 | // Device : UltraScale 61 | // Design Name : Model_wrapper 62 | // Purpose : 63 | // Reference : 64 | // Revision History : 65 | //***************************************************************************** 66 | 67 | 68 | `define DDR4_8G_X8 69 | `define DDR4_833_Timing 70 | // Added define SILENT to avoid timeset setting display messages in transcript 71 | `define SILENT 72 | `define FIXED_2400 73 | 74 | -------------------------------------------------------------------------------- /sim/ddr_ref_model/ddr_model.sv: -------------------------------------------------------------------------------- 1 | 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 02/14/2019 03:14:24 PM 7 | // Design Name: 8 | // Module Name: ddr_model 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | `timescale 1ps/1ps 22 | `include "arch_package.sv" 23 | `ifdef XILINX_SIMULATOR 24 | module short(in1, in1); 25 | inout in1; 26 | endmodule 27 | `endif 28 | module ddr_model( 29 | input c0_sys_clk_p, 30 | input c0_sys_clk_n, 31 | input c0_ddr4_act_n, 32 | input [16:0] c0_ddr4_adr, 33 | input [1:0] c0_ddr4_ba, 34 | input [1:0] c0_ddr4_bg, 35 | input [1:0] c0_ddr4_cke, 36 | input [1:0] c0_ddr4_odt, 37 | input [1:0] c0_ddr4_cs_n, 38 | input [1:0] c0_ddr4_ck_t_int, 39 | input [1:0] c0_ddr4_ck_c_int, 40 | input c0_ddr4_reset_n, 41 | inout [7:0] c0_ddr4_dm_dbi_n, 42 | inout [63:0] c0_ddr4_dq, 43 | inout [7:0] c0_ddr4_dqs_t, 44 | inout [7:0] c0_ddr4_dqs_c 45 | ); 46 | localparam ADDR_WIDTH = 17; 47 | localparam DQ_WIDTH = 64; 48 | localparam DQS_WIDTH = 8; 49 | localparam DM_WIDTH = 8; 50 | localparam DRAM_WIDTH = 8; 51 | localparam tCK = 938 ; //DDR4 interface clock period in ps 52 | localparam real SYSCLK_PERIOD = tCK; 53 | localparam NUM_PHYSICAL_PARTS = (DQ_WIDTH/DRAM_WIDTH) ; 54 | localparam CLAMSHELL_PARTS = (NUM_PHYSICAL_PARTS/2); 55 | localparam ODD_PARTS = ((CLAMSHELL_PARTS*2) < NUM_PHYSICAL_PARTS) ? 1 : 0; 56 | parameter RANK_WIDTH = 2; 57 | parameter CS_WIDTH = 2; 58 | parameter ODT_WIDTH = 2; 59 | parameter CA_MIRROR = "ON"; 60 | 61 | 62 | localparam MRS = 3'b000; 63 | localparam REF = 3'b001; 64 | localparam PRE = 3'b010; 65 | localparam ACT = 3'b011; 66 | localparam WR = 3'b100; 67 | localparam RD = 3'b101; 68 | localparam ZQC = 3'b110; 69 | localparam NOP = 3'b111; 70 | 71 | import arch_package::*; 72 | parameter UTYPE_density CONFIGURED_DENSITY = _8G; 73 | 74 | // Input clock is assumed to be equal to the memory clock frequency 75 | // User should change the parameter as necessary if a different input 76 | // clock frequency is used 77 | //localparam real CLKIN_PERIOD_NS = 3284 / 1000.0; 78 | 79 | //initial begin 80 | // $shm_open("waves.shm"); 81 | // $shm_probe("ACMTF"); 82 | //end 83 | //=================================================================================== 84 | //members 85 | //=================================================================================== 86 | reg [16:0] c0_ddr4_adr_sdram[RANK_WIDTH-1:0]; 87 | reg [1:0] c0_ddr4_ba_sdram[RANK_WIDTH-1:0]; 88 | reg [1:0] c0_ddr4_bg_sdram[RANK_WIDTH-1:0]; 89 | 90 | wire c0_ddr4_ck_t; 91 | wire c0_ddr4_ck_c; 92 | 93 | //wire c0_init_calib_complete; 94 | //wire c0_data_compare_error; 95 | 96 | reg [31:0] cmdName; 97 | bit en_model=1'b1; 98 | tri model_enable = en_model; 99 | //=================================================================================== 100 | //logic 101 | //=================================================================================== 102 | assign c0_ddr4_ck_t = c0_ddr4_ck_t_int[0]; 103 | assign c0_ddr4_ck_c = c0_ddr4_ck_c_int[0]; 104 | 105 | always @( * ) begin 106 | c0_ddr4_adr_sdram[0] <= c0_ddr4_adr; 107 | c0_ddr4_adr_sdram[1] <= (CA_MIRROR == "ON") ? 108 | {c0_ddr4_adr[ADDR_WIDTH-1:14], 109 | c0_ddr4_adr[11], c0_ddr4_adr[12], 110 | c0_ddr4_adr[13], c0_ddr4_adr[10:9], 111 | c0_ddr4_adr[7], c0_ddr4_adr[8], 112 | c0_ddr4_adr[5], c0_ddr4_adr[6], 113 | c0_ddr4_adr[3], c0_ddr4_adr[4], 114 | c0_ddr4_adr[2:0]} : 115 | c0_ddr4_adr; 116 | c0_ddr4_ba_sdram[0] <= c0_ddr4_ba; 117 | c0_ddr4_ba_sdram[1] <= (CA_MIRROR == "ON") ? 118 | {c0_ddr4_ba[0], 119 | c0_ddr4_ba[1]} : 120 | c0_ddr4_ba; 121 | c0_ddr4_bg_sdram[0] <= c0_ddr4_bg; 122 | c0_ddr4_bg_sdram[1] <= (CA_MIRROR == "ON" && DRAM_WIDTH != 16) ? 123 | {c0_ddr4_bg[0], 124 | c0_ddr4_bg[1]} : 125 | c0_ddr4_bg; 126 | end 127 | 128 | reg [ADDR_WIDTH-1:0] DDR4_ADRMOD[RANK_WIDTH-1:0]; 129 | 130 | always @(*) 131 | if (c0_ddr4_cs_n == 4'b1111) 132 | cmdName = "DSEL"; 133 | else 134 | if (c0_ddr4_act_n) 135 | casez (DDR4_ADRMOD[0][16:14]) 136 | MRS: cmdName = "MRS"; 137 | REF: cmdName = "REF"; 138 | PRE: cmdName = "PRE"; 139 | WR: cmdName = "WR"; 140 | RD: cmdName = "RD"; 141 | ZQC: cmdName = "ZQC"; 142 | NOP: cmdName = "NOP"; 143 | default: cmdName = "***"; 144 | endcase 145 | else 146 | cmdName = "ACT"; 147 | 148 | reg wr_en ; 149 | always@(posedge c0_ddr4_ck_t)begin 150 | if(!c0_ddr4_reset_n)begin 151 | wr_en <= #100 1'b0 ; 152 | end else begin 153 | if(cmdName == "WR")begin 154 | wr_en <= #100 1'b1 ; 155 | end else if (cmdName == "RD")begin 156 | wr_en <= #100 1'b0 ; 157 | end 158 | end 159 | end 160 | 161 | genvar rnk; 162 | generate 163 | for (rnk = 0; rnk < CS_WIDTH; rnk++) begin:rankup 164 | always @(*) 165 | if (c0_ddr4_act_n) 166 | casez (c0_ddr4_adr_sdram[0][16:14]) 167 | WR, RD: begin 168 | DDR4_ADRMOD[rnk] = c0_ddr4_adr_sdram[rnk] & 18'h1C7FF; 169 | end 170 | default: begin 171 | DDR4_ADRMOD[rnk] = c0_ddr4_adr_sdram[rnk]; 172 | end 173 | endcase 174 | else begin 175 | DDR4_ADRMOD[rnk] = c0_ddr4_adr_sdram[rnk]; 176 | end 177 | end 178 | endgenerate 179 | 180 | //=========================================================================== 181 | // Memory Model instantiation 182 | //=========================================================================== 183 | genvar i; 184 | genvar r; 185 | genvar s; 186 | 187 | generate 188 | if (DRAM_WIDTH == 4) begin: mem_model_x4 189 | 190 | DDR4_if #(.CONFIGURED_DQ_BITS (4)) iDDR4[0:(RANK_WIDTH*NUM_PHYSICAL_PARTS)-1](); 191 | for (r = 0; r < RANK_WIDTH; r++) begin:memModels_Ri 192 | for (i = 0; i < NUM_PHYSICAL_PARTS; i++) begin:memModel 193 | ddr4_model # 194 | ( 195 | .CONFIGURED_DQ_BITS (4), 196 | .CONFIGURED_DENSITY (CONFIGURED_DENSITY) 197 | ) ddr4_model( 198 | .model_enable (model_enable), 199 | .iDDR4 (iDDR4[(r*NUM_PHYSICAL_PARTS)+i]) 200 | ); 201 | end 202 | end 203 | 204 | for (r = 0; r < RANK_WIDTH; r++) begin:tranDQ 205 | for (i = 0; i < NUM_PHYSICAL_PARTS; i++) begin:tranDQ1 206 | for (s = 0; s < 4; s++) begin:tranDQp 207 | `ifdef XILINX_SIMULATOR 208 | short bidiDQ(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQ[s], c0_ddr4_dq[s+i*4]); 209 | `else 210 | tran bidiDQ(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQ[s], c0_ddr4_dq[s+i*4]); 211 | `endif 212 | end 213 | end 214 | end 215 | 216 | for (r = 0; r < RANK_WIDTH; r++) begin:tranDQS 217 | for (i = 0; i < NUM_PHYSICAL_PARTS; i++) begin:tranDQS1 218 | `ifdef XILINX_SIMULATOR 219 | short bidiDQS(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQS_t, c0_ddr4_dqs_t[i]); 220 | short bidiDQS_(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQS_c, c0_ddr4_dqs_c[i]); 221 | `else 222 | tran bidiDQS(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQS_t, c0_ddr4_dqs_t[i]); 223 | tran bidiDQS_(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQS_c, c0_ddr4_dqs_c[i]); 224 | `endif 225 | end 226 | end 227 | 228 | for (r = 0; r < RANK_WIDTH; r++) begin:ADDR_RANKS 229 | for (i = 0; i < NUM_PHYSICAL_PARTS; i++) begin:ADDR_R 230 | 231 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].BG = c0_ddr4_bg_sdram[r]; 232 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].BA = c0_ddr4_ba_sdram[r]; 233 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].ADDR_17 = (ADDR_WIDTH == 18) ? DDR4_ADRMOD[r][ADDR_WIDTH-1] : 1'b0; 234 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].ADDR = DDR4_ADRMOD[r][13:0]; 235 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].CS_n = c0_ddr4_cs_n[r]; 236 | 237 | end 238 | end 239 | 240 | for (r = 0; r < RANK_WIDTH; r++) begin:tranADCTL_RANKS 241 | for (i = 0; i < NUM_PHYSICAL_PARTS; i++) begin:tranADCTL 242 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].CK = {c0_ddr4_ck_t, c0_ddr4_ck_c}; 243 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].ACT_n = c0_ddr4_act_n; 244 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].RAS_n_A16 = DDR4_ADRMOD[r][16]; 245 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].CAS_n_A15 = DDR4_ADRMOD[r][15]; 246 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].WE_n_A14 = DDR4_ADRMOD[r][14]; 247 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].CKE = c0_ddr4_cke[r]; 248 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].ODT = c0_ddr4_odt[r]; 249 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].PARITY = 1'b0; 250 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].TEN = 1'b0; 251 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].ZQ = 1'b1; 252 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].PWR = 1'b1; 253 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].VREF_CA = 1'b1; 254 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].VREF_DQ = 1'b1; 255 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].RESET_n = c0_ddr4_reset_n; 256 | end 257 | end 258 | end 259 | else if (DRAM_WIDTH == 8) begin: mem_model_x8 260 | 261 | DDR4_if #(.CONFIGURED_DQ_BITS(8)) iDDR4[0:(RANK_WIDTH*NUM_PHYSICAL_PARTS)-1](); 262 | 263 | for (r = 0; r < RANK_WIDTH; r++) begin:memModels_Ri1 264 | for (i = 0; i < NUM_PHYSICAL_PARTS; i++) begin:memModel1 265 | ddr4_model #( 266 | .CONFIGURED_DQ_BITS(8), 267 | .CONFIGURED_DENSITY (CONFIGURED_DENSITY) 268 | ) ddr4_model( 269 | .model_enable (model_enable) 270 | ,.iDDR4 (iDDR4[(r*NUM_PHYSICAL_PARTS)+i]) 271 | ); 272 | end 273 | end 274 | 275 | for (r = 0; r < RANK_WIDTH; r++) begin:tranDQ2 276 | for (i = 0; i < NUM_PHYSICAL_PARTS; i++) begin:tranDQ12 277 | for (s = 0; s < 8; s++) begin:tranDQ2 278 | `ifdef XILINX_SIMULATOR 279 | short bidiDQ(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQ[s], c0_ddr4_dq[s+i*8]); 280 | `else 281 | tran bidiDQ(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQ[s], c0_ddr4_dq[s+i*8]); 282 | `endif 283 | end 284 | end 285 | end 286 | 287 | for (r = 0; r < RANK_WIDTH; r++) begin:tranDQS2 288 | for (i = 0; i < NUM_PHYSICAL_PARTS; i++) begin:tranDQS12 289 | `ifdef XILINX_SIMULATOR 290 | short bidiDQS(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQS_t, c0_ddr4_dqs_t[i]); 291 | short bidiDQS_(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQS_c, c0_ddr4_dqs_c[i]); 292 | short bidiDM(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DM_n, c0_ddr4_dm_dbi_n[i]); 293 | `else 294 | tran bidiDQS(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQS_t, c0_ddr4_dqs_t[i]); 295 | tran bidiDQS_(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQS_c, c0_ddr4_dqs_c[i]); 296 | tran bidiDM(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DM_n, c0_ddr4_dm_dbi_n[i]); 297 | `endif 298 | end 299 | end 300 | 301 | for (r = 0; r < RANK_WIDTH; r++) begin:ADDR_RANKS 302 | for (i = 0; i < NUM_PHYSICAL_PARTS; i++) begin:ADDR_R 303 | 304 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].BG = c0_ddr4_bg_sdram[r]; 305 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].BA = c0_ddr4_ba_sdram[r]; 306 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].ADDR_17 = (ADDR_WIDTH == 18) ? DDR4_ADRMOD[r][ADDR_WIDTH-1] : 1'b0; 307 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].ADDR = DDR4_ADRMOD[r][13:0]; 308 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].CS_n = c0_ddr4_cs_n[r]; 309 | 310 | end 311 | end 312 | 313 | for (r = 0; r < RANK_WIDTH; r++) begin:tranADCTL_RANKS1 314 | for (i = 0; i < NUM_PHYSICAL_PARTS; i++) begin:tranADCTL1 315 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].CK = {c0_ddr4_ck_t, c0_ddr4_ck_c}; 316 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].ACT_n = c0_ddr4_act_n; 317 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].RAS_n_A16 = DDR4_ADRMOD[r][16]; 318 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].CAS_n_A15 = DDR4_ADRMOD[r][15]; 319 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].WE_n_A14 = DDR4_ADRMOD[r][14]; 320 | 321 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].CKE = c0_ddr4_cke[r]; 322 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].ODT = c0_ddr4_odt[r]; 323 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].PARITY = 1'b0; 324 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].TEN = 1'b0; 325 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].ZQ = 1'b1; 326 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].PWR = 1'b1; 327 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].VREF_CA = 1'b1; 328 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].VREF_DQ = 1'b1; 329 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].RESET_n = c0_ddr4_reset_n; 330 | end 331 | end 332 | 333 | end else begin: mem_model_x16 334 | 335 | if (DQ_WIDTH/16) begin: mem 336 | 337 | DDR4_if #(.CONFIGURED_DQ_BITS (16)) iDDR4[0:(RANK_WIDTH*NUM_PHYSICAL_PARTS)-1](); 338 | 339 | for (r = 0; r < RANK_WIDTH; r++) begin:memModels_Ri2 340 | for (i = 0; i < NUM_PHYSICAL_PARTS; i++) begin:memModel2 341 | ddr4_model # 342 | ( 343 | .CONFIGURED_DQ_BITS (16), 344 | .CONFIGURED_DENSITY (CONFIGURED_DENSITY) 345 | ) ddr4_model( 346 | .model_enable (model_enable), 347 | .iDDR4 (iDDR4[(r*NUM_PHYSICAL_PARTS)+i]) 348 | ); 349 | end 350 | end 351 | 352 | for (r = 0; r < RANK_WIDTH; r++) begin:tranDQ3 353 | for (i = 0; i < NUM_PHYSICAL_PARTS; i++) begin:tranDQ13 354 | for (s = 0; s < 16; s++) begin:tranDQ2 355 | `ifdef XILINX_SIMULATOR 356 | short bidiDQ(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQ[s], c0_ddr4_dq[s+i*16]); 357 | `else 358 | tran bidiDQ(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQ[s], c0_ddr4_dq[s+i*16]); 359 | `endif 360 | end 361 | end 362 | end 363 | 364 | for (r = 0; r < RANK_WIDTH; r++) begin:tranDQS3 365 | for (i = 0; i < NUM_PHYSICAL_PARTS; i++) begin:tranDQS13 366 | `ifdef XILINX_SIMULATOR 367 | short bidiDQS0(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQS_t[0], c0_ddr4_dqs_t[(2*i)]); 368 | short bidiDQS0_(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQS_c[0], c0_ddr4_dqs_c[(2*i)]); 369 | short bidiDM0(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DM_n[0], c0_ddr4_dm_dbi_n[(2*i)]); 370 | short bidiDQS1(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQS_t[1], c0_ddr4_dqs_t[((2*i)+1)]); 371 | short bidiDQS1_(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQS_c[1], c0_ddr4_dqs_c[((2*i)+1)]); 372 | short bidiDM1(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DM_n[1], c0_ddr4_dm_dbi_n[((2*i)+1)]); 373 | 374 | `else 375 | tran bidiDQS0(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQS_t[0], c0_ddr4_dqs_t[(2*i)]); 376 | tran bidiDQS0_(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQS_c[0], c0_ddr4_dqs_c[(2*i)]); 377 | tran bidiDM0(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DM_n[0], c0_ddr4_dm_dbi_n[(2*i)]); 378 | tran bidiDQS1(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQS_t[1], c0_ddr4_dqs_t[((2*i)+1)]); 379 | tran bidiDQS1_(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DQS_c[1], c0_ddr4_dqs_c[((2*i)+1)]); 380 | tran bidiDM1(iDDR4[(r*NUM_PHYSICAL_PARTS)+i].DM_n[1], c0_ddr4_dm_dbi_n[((2*i)+1)]); 381 | `endif 382 | end 383 | end 384 | 385 | for (r = 0; r < RANK_WIDTH; r++) begin:tranADCTL_RANKS 386 | for (i = 0; i < NUM_PHYSICAL_PARTS; i++) begin:tranADCTL 387 | 388 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].BG = c0_ddr4_bg_sdram[r]; 389 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].BA = c0_ddr4_ba_sdram[r]; 390 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].ADDR_17 = (ADDR_WIDTH == 18) ? DDR4_ADRMOD[r][ADDR_WIDTH-1] : 1'b0; 391 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].ADDR = DDR4_ADRMOD[r][13:0]; 392 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].CS_n = c0_ddr4_cs_n[r]; 393 | 394 | end 395 | end 396 | 397 | for (r = 0; r < RANK_WIDTH; r++) begin:tranADCTL_RANKS1 398 | for (i = 0; i < NUM_PHYSICAL_PARTS; i++) begin:tranADCTL1 399 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].CK = {c0_ddr4_ck_t, c0_ddr4_ck_c}; 400 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].ACT_n = c0_ddr4_act_n; 401 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].RAS_n_A16 = DDR4_ADRMOD[r][16]; 402 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].CAS_n_A15 = DDR4_ADRMOD[r][15]; 403 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].WE_n_A14 = DDR4_ADRMOD[r][14]; 404 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].CKE = c0_ddr4_cke[r]; 405 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].ODT = c0_ddr4_odt[r]; 406 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].PARITY = 1'b0; 407 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].TEN = 1'b0; 408 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].ZQ = 1'b1; 409 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].PWR = 1'b1; 410 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].VREF_CA = 1'b1; 411 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].VREF_DQ = 1'b1; 412 | assign iDDR4[(r*NUM_PHYSICAL_PARTS)+ i].RESET_n = c0_ddr4_reset_n; 413 | end 414 | end 415 | end 416 | 417 | if (DQ_WIDTH%16) begin: mem_extra_bits 418 | // DDR4 X16 dual rank is not supported 419 | DDR4_if #(.CONFIGURED_DQ_BITS (16)) iDDR4[(DQ_WIDTH/DRAM_WIDTH):(DQ_WIDTH/DRAM_WIDTH)](); 420 | 421 | ddr4_model # 422 | ( 423 | .CONFIGURED_DQ_BITS (16), 424 | .CONFIGURED_DENSITY (CONFIGURED_DENSITY) 425 | ) ddr4_model( 426 | .model_enable (model_enable), 427 | .iDDR4 (iDDR4[(DQ_WIDTH/DRAM_WIDTH)]) 428 | ); 429 | 430 | for (i = (DQ_WIDTH/DRAM_WIDTH)*16; i < DQ_WIDTH; i=i+1) begin:tranDQ 431 | `ifdef XILINX_SIMULATOR 432 | short bidiDQ(iDDR4[i/16].DQ[i%16], c0_ddr4_dq[i]); 433 | short bidiDQ_msb(iDDR4[i/16].DQ[(i%16)+8], c0_ddr4_dq[i]); 434 | `else 435 | tran bidiDQ(iDDR4[i/16].DQ[i%16], c0_ddr4_dq[i]); 436 | tran bidiDQ_msb(iDDR4[i/16].DQ[(i%16)+8], c0_ddr4_dq[i]); 437 | `endif 438 | end 439 | 440 | `ifdef XILINX_SIMULATOR 441 | short bidiDQS0(iDDR4[DQ_WIDTH/DRAM_WIDTH].DQS_t[0], c0_ddr4_dqs_t[DQS_WIDTH-1]); 442 | short bidiDQS0_(iDDR4[DQ_WIDTH/DRAM_WIDTH].DQS_c[0], c0_ddr4_dqs_c[DQS_WIDTH-1]); 443 | short bidiDM0(iDDR4[DQ_WIDTH/DRAM_WIDTH].DM_n[0], c0_ddr4_dm_dbi_n[DM_WIDTH-1]); 444 | short bidiDQS1(iDDR4[DQ_WIDTH/DRAM_WIDTH].DQS_t[1], c0_ddr4_dqs_t[DQS_WIDTH-1]); 445 | short bidiDQS1_(iDDR4[DQ_WIDTH/DRAM_WIDTH].DQS_c[1], c0_ddr4_dqs_c[DQS_WIDTH-1]); 446 | short bidiDM1(iDDR4[DQ_WIDTH/DRAM_WIDTH].DM_n[1], c0_ddr4_dm_dbi_n[DM_WIDTH-1]); 447 | `else 448 | tran bidiDQS0(iDDR4[DQ_WIDTH/DRAM_WIDTH].DQS_t[0], c0_ddr4_dqs_t[DQS_WIDTH-1]); 449 | tran bidiDQS0_(iDDR4[DQ_WIDTH/DRAM_WIDTH].DQS_c[0], c0_ddr4_dqs_c[DQS_WIDTH-1]); 450 | tran bidiDM0(iDDR4[DQ_WIDTH/DRAM_WIDTH].DM_n[0], c0_ddr4_dm_dbi_n[DM_WIDTH-1]); 451 | tran bidiDQS1(iDDR4[DQ_WIDTH/DRAM_WIDTH].DQS_t[1], c0_ddr4_dqs_t[DQS_WIDTH-1]); 452 | tran bidiDQS1_(iDDR4[DQ_WIDTH/DRAM_WIDTH].DQS_c[1], c0_ddr4_dqs_c[DQS_WIDTH-1]); 453 | tran bidiDM1(iDDR4[DQ_WIDTH/DRAM_WIDTH].DM_n[1], c0_ddr4_dm_dbi_n[DM_WIDTH-1]); 454 | `endif 455 | 456 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].CK = {c0_ddr4_ck_t, c0_ddr4_ck_c}; 457 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].ACT_n = c0_ddr4_act_n; 458 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].RAS_n_A16 = DDR4_ADRMOD[0][16]; 459 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].CAS_n_A15 = DDR4_ADRMOD[0][15]; 460 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].WE_n_A14 = DDR4_ADRMOD[0][14]; 461 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].CKE = c0_ddr4_cke[0]; 462 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].ODT = c0_ddr4_odt[0]; 463 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].BG = c0_ddr4_bg_sdram[0]; 464 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].BA = c0_ddr4_ba_sdram[0]; 465 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].ADDR_17 = (ADDR_WIDTH == 18) ? DDR4_ADRMOD[0][ADDR_WIDTH-1] : 1'b0; 466 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].ADDR = DDR4_ADRMOD[0][13:0]; 467 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].RESET_n = c0_ddr4_reset_n; 468 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].TEN = 1'b0; 469 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].ZQ = 1'b1; 470 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].PWR = 1'b1; 471 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].VREF_CA = 1'b1; 472 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].VREF_DQ = 1'b1; 473 | assign iDDR4[DQ_WIDTH/DRAM_WIDTH].CS_n = c0_ddr4_cs_n[0]; 474 | end 475 | end 476 | endgenerate 477 | endmodule 478 | -------------------------------------------------------------------------------- /sim/ddr_ref_model/interface.sv: -------------------------------------------------------------------------------- 1 | // MICRON TECHNOLOGY, INC. - CONFIDENTIAL AND PROPRIETARY INFORMATION 2 | `include "ddr4_sdram_model_wrapper.sv" 3 | interface DDR4_if #(parameter CONFIGURED_DQ_BITS = 8) (); 4 | timeunit 1ps; 5 | timeprecision 1ps; 6 | import arch_package::*; 7 | parameter CONFIGURED_DQS_BITS = (16 == CONFIGURED_DQ_BITS) ? 2 : 1; 8 | parameter CONFIGURED_DM_BITS = (16 == CONFIGURED_DQ_BITS) ? 2 : 1; 9 | logic[1:0] CK; // CK[0]==CK_c CK[1]==CK_t 10 | logic ACT_n; 11 | logic RAS_n_A16; 12 | logic CAS_n_A15; 13 | logic WE_n_A14; 14 | logic ALERT_n; 15 | logic PARITY; 16 | logic RESET_n; 17 | logic TEN; 18 | logic CS_n; 19 | logic CKE; 20 | logic ODT; 21 | logic[MAX_RANK_BITS-1:0] C; 22 | logic[MAX_BANK_GROUP_BITS-1:0] BG; 23 | logic[MAX_BANK_BITS-1:0] BA; 24 | logic[13:0] ADDR; 25 | logic ADDR_17; 26 | wire[CONFIGURED_DM_BITS-1:0] DM_n; 27 | wire[CONFIGURED_DQ_BITS-1:0] DQ; 28 | wire[CONFIGURED_DQS_BITS-1:0] DQS_t; 29 | wire[CONFIGURED_DQS_BITS-1:0] DQS_c; 30 | logic ZQ; 31 | logic PWR; 32 | logic VREF_CA; 33 | logic VREF_DQ; 34 | endinterface 35 | 36 | -------------------------------------------------------------------------------- /sim/ddr_ref_model/proj_package.sv: -------------------------------------------------------------------------------- 1 | // MICRON TECHNOLOGY, INC. - CONFIDENTIAL AND PROPRIETARY INFORMATION 2 | `include "ddr4_sdram_model_wrapper.sv" 3 | package proj_package; 4 | timeunit 1ps; 5 | timeprecision 1ps; 6 | import arch_package::*; 7 | 8 | parameter DEF_CCD_L = 6; 9 | 10 | function void project_dut_config(inout UTYPE_dutconfig dut_config); 11 | dut_config.min_CL_dll_off = 5; 12 | dut_config.max_CL_dll_off = 10; 13 | dut_config.max_CL_dbi_enabled = 32; 14 | dut_config.max_CL_dbi_disabled = 30; 15 | dut_config.min_CL_dbi_enabled = 10; 16 | dut_config.min_CL_dbi_disabled = 9; 17 | dut_config.cl_17_19_21_feature = 1; // Add this line 0-off 1-on 18 | dut_config.cl_a12_feature = 1; // Add this line 0-off 1-on 19 | dut_config.ppr_feature = 1; 20 | dut_config.min_CL = 9; 21 | dut_config.max_CL = 32; 22 | dut_config.max_CWL = 20; 23 | dut_config.min_CWL = MIN_CWL; 24 | dut_config.max_CAL = 8; 25 | endfunction 26 | 27 | function void GetCWLSpeedRange(input UTYPE_DutModeConfig dut_mode_config, input UTYPE_TS ts, 28 | output int min, output int max, output int ideal); 29 | ideal = 9; 30 | min = 9; 31 | max = 9; 32 | case (ts) 33 | TS_1875, 34 | TS_1500: begin 35 | if ((2 == dut_mode_config.wr_preamble_clocks) || (1 == dut_mode_config.gear_down)) begin 36 | ideal = 10; 37 | max = 10; 38 | end 39 | end 40 | TS_1250 : begin 41 | ideal = 9; 42 | if ((2 == dut_mode_config.wr_preamble_clocks) || (1 == dut_mode_config.gear_down)) 43 | ideal = 10; 44 | min = ideal; 45 | max = 11; 46 | end 47 | TS_1072 : begin 48 | ideal = 10; 49 | if (2 == dut_mode_config.wr_preamble_clocks) 50 | ideal = (1 == dut_mode_config.gear_down) ? 12 : 11; 51 | min = ideal; 52 | max = 12; 53 | end 54 | TS_938 : begin 55 | ideal = 11; 56 | if ((2 == dut_mode_config.wr_preamble_clocks) || (1 == dut_mode_config.gear_down)) 57 | ideal = 12; 58 | min = ideal; 59 | max = 14; 60 | end 61 | TS_833 : begin 62 | ideal = 12; 63 | if (2 == dut_mode_config.wr_preamble_clocks) 64 | ideal = 14; 65 | min = ideal; 66 | max = 16; 67 | end 68 | TS_750 : begin 69 | ideal = 14; 70 | if (2 == dut_mode_config.wr_preamble_clocks) 71 | ideal = 16; 72 | min = ideal; 73 | max = 18; 74 | end 75 | TS_682, TS_625 : begin 76 | ideal = 16; 77 | if (2 == dut_mode_config.wr_preamble_clocks) 78 | ideal = 18; 79 | min = ideal; 80 | max = 20; 81 | end 82 | endcase 83 | endfunction 84 | 85 | function void GetCLSpeedRange(input UTYPE_DutModeConfig dut_mode_config, output UTYPE_TS slowest, output UTYPE_TS fastest, output UTYPE_TS ideal); 86 | UTYPE_TS default_tck; 87 | 88 | if (0 == dut_mode_config.read_dbi) begin 89 | case (dut_mode_config.CL) 90 | 9: begin 91 | ideal = TS_1500; 92 | slowest = TS_1500; fastest = TS_1500; 93 | end 94 | 10: begin 95 | ideal = TS_1250; 96 | slowest = TS_1500; fastest = TS_1250; 97 | end 98 | 11: begin 99 | ideal = TS_1250; 100 | slowest = TS_1250; fastest = TS_1250; 101 | end 102 | 12: begin 103 | ideal = TS_1250; 104 | slowest = TS_1250; fastest = TS_1072; 105 | end 106 | 13: begin 107 | ideal = TS_1072; 108 | slowest = TS_1072; fastest = TS_1072; 109 | end 110 | 14: begin 111 | ideal = TS_1072; 112 | slowest = TS_1072; fastest = TS_938; 113 | end 114 | 15,16: begin 115 | ideal = TS_938; 116 | slowest = TS_938; fastest = TS_938; 117 | end 118 | 17,18: begin 119 | ideal = TS_833; 120 | slowest = TS_833; fastest = TS_750; 121 | end 122 | 19: begin 123 | ideal = TS_750; 124 | slowest = TS_750; fastest = TS_750; 125 | end 126 | 20: begin 127 | ideal = TS_750; 128 | slowest = TS_750; fastest = TS_625; 129 | end 130 | // CL21 w/ DBI disabled is not in the spec!! 131 | 21: begin 132 | ideal = TS_750; 133 | slowest = TS_750; fastest = TS_625; 134 | end 135 | 22,24: begin 136 | ideal = TS_625; 137 | slowest = TS_625; fastest = TS_625; 138 | end 139 | 23,25,26,27,28,29,30,31,32: begin 140 | ideal = TS_625; 141 | slowest = TS_625; fastest = TS_625; 142 | end 143 | endcase 144 | end else begin 145 | case (dut_mode_config.CL) 146 | 5,9,10: begin 147 | ideal = TS_1500; 148 | slowest = TS_1500; fastest = TS_1500; 149 | end 150 | 11: begin 151 | ideal = TS_1500; 152 | slowest = TS_1500; fastest = TS_1500; 153 | end 154 | 12: begin 155 | ideal = TS_1500; 156 | slowest = TS_1500; fastest = TS_1250; 157 | end 158 | 13: begin 159 | ideal = TS_1250; 160 | slowest = TS_1250; fastest = TS_1250; 161 | end 162 | 14: begin 163 | ideal = TS_1250; 164 | slowest = TS_1250; fastest = TS_1072; 165 | end 166 | 15,16: begin 167 | ideal = TS_1072; 168 | slowest = TS_1072; fastest = TS_1072; 169 | end 170 | 17: begin 171 | ideal = TS_938; 172 | slowest = TS_938; fastest = TS_938; 173 | end 174 | 18: begin 175 | ideal = TS_938; 176 | slowest = TS_938; fastest = TS_833; 177 | end 178 | 19: begin 179 | ideal = TS_833; 180 | slowest = TS_833; fastest = TS_833; 181 | end 182 | 20: begin 183 | ideal = TS_833; 184 | slowest = TS_833; fastest = TS_750; 185 | end 186 | 21,22,23: begin 187 | ideal = TS_750; 188 | slowest = TS_750; fastest = TS_750; 189 | end 190 | 24,25,26,27,28,29,30,31,32: begin 191 | ideal = TS_625; 192 | slowest = TS_625; fastest = TS_625; 193 | end 194 | endcase 195 | end 196 | `ifdef DDR4_STACK_X4_2H 197 | GetCLSpeedRange3DS(.dut_mode_config(dut_mode_config), .slowest(slowest), .fastest(fastest), .ideal(ideal)); 198 | `endif 199 | `ifdef DDR4_STACK_X8_2H 200 | GetCLSpeedRange3DS(.dut_mode_config(dut_mode_config), .slowest(slowest), .fastest(fastest), .ideal(ideal)); 201 | `endif 202 | `ifdef DDR4_STACK_X16_2H 203 | GetCLSpeedRange3DS(.dut_mode_config(dut_mode_config), .slowest(slowest), .fastest(fastest), .ideal(ideal)); 204 | `endif 205 | `ifdef DDR4_STACK_X4_4H 206 | GetCLSpeedRange3DS(.dut_mode_config(dut_mode_config), .slowest(slowest), .fastest(fastest), .ideal(ideal)); 207 | `endif 208 | `ifdef DDR4_STACK_X8_4H 209 | GetCLSpeedRange3DS(.dut_mode_config(dut_mode_config), .slowest(slowest), .fastest(fastest), .ideal(ideal)); 210 | `endif 211 | `ifdef DDR4_STACK_X16_4H 212 | GetCLSpeedRange3DS(.dut_mode_config(dut_mode_config), .slowest(slowest), .fastest(fastest), .ideal(ideal)); 213 | `endif 214 | if (default_tck == ideal) begin 215 | $display("WARNING Missing CL in GetCLSpeedRange(). Default is %p", default_tck); 216 | end 217 | endfunction 218 | 219 | function void GetCLSpeedRange3DS(input UTYPE_DutModeConfig dut_mode_config, output UTYPE_TS slowest, output UTYPE_TS fastest, output UTYPE_TS ideal); 220 | UTYPE_TS default_tck; 221 | 222 | case (dut_mode_config.CL) 223 | 9: begin 224 | ideal = TS_1500; 225 | slowest = TS_1500; fastest = TS_1500; 226 | end 227 | 10, 11: begin 228 | ideal = TS_1250; 229 | slowest = TS_1500; fastest = TS_1250; 230 | end 231 | 12, 13: begin 232 | ideal = TS_1250; 233 | slowest = TS_1250; fastest = TS_1250; 234 | end 235 | 14: begin 236 | ideal = TS_1072; 237 | slowest = TS_1250; fastest = TS_1072; 238 | end 239 | 15: begin 240 | ideal = TS_1072; 241 | slowest = TS_1072; fastest = TS_1072; 242 | end 243 | 16, 17: begin 244 | ideal = TS_938; 245 | slowest = TS_1072; fastest = TS_938; 246 | end 247 | 18, 19, 20: begin 248 | ideal = TS_833; 249 | slowest = TS_938; fastest = TS_833; 250 | end 251 | 22,24,25,26,27,28,29,30,31,32: begin 252 | ideal = TS_833; 253 | slowest = TS_833; fastest = TS_833; 254 | end 255 | endcase 256 | if (default_tck == ideal) begin 257 | $display("WARNING Missing CL in GetCLSpeedRange(). Default is %p", default_tck); 258 | end 259 | endfunction 260 | 261 | function int GettCCD_LSpeed(input UTYPE_DutModeConfig dut_mode_config, input UTYPE_TS ts); 262 | int tCCD_L; 263 | 264 | tCCD_L = 4; 265 | case (ts) 266 | TS_1250, 267 | TS_1072 : begin 268 | tCCD_L = ((2 == dut_mode_config.wr_preamble_clocks) || (1 == dut_mode_config.gear_down)) ? 6 : 5; 269 | end 270 | TS_938, 271 | TS_833 : begin 272 | tCCD_L = 6; 273 | end 274 | TS_750 : begin 275 | tCCD_L = ((2 == dut_mode_config.wr_preamble_clocks) || (1 == dut_mode_config.gear_down)) ? 8 : 7; 276 | end 277 | TS_682, 278 | TS_625 : begin 279 | tCCD_L = 8; 280 | end 281 | endcase 282 | return tCCD_L; 283 | endfunction 284 | 285 | function int GetMintWR(input UTYPE_DutModeConfig dut_mode_config, int tWRc, int tRTPc); 286 | int min_setting; 287 | 288 | min_setting = (tRTPc*2) > tWRc ? tRTPc*2 : tWRc; 289 | if (1 == dut_mode_config.gear_down) 290 | min_setting = min_setting + (min_setting % 4); 291 | else 292 | min_setting = min_setting + (min_setting % 2); 293 | if (min_setting < MIN_WR) 294 | min_setting = MIN_WR; 295 | else if (min_setting > MAX_WR) 296 | min_setting = MAX_WR; 297 | return min_setting; 298 | endfunction 299 | 300 | function UTYPE_delay_write_crc_dm GettWR_CRC_DMSpeed(input UTYPE_DutModeConfig dut_mode_config, input UTYPE_TS ts); 301 | UTYPE_delay_write_crc_dm tWR_CRC_DM; 302 | 303 | tWR_CRC_DM = DELAY_WRITE_5; 304 | case (ts) 305 | TS_1875, 306 | TS_1500, 307 | TS_1250 : begin 308 | tWR_CRC_DM = DELAY_WRITE_4; 309 | end 310 | TS_750, 311 | TS_682, 312 | TS_625 : begin 313 | tWR_CRC_DM = DELAY_WRITE_6; 314 | end 315 | endcase 316 | return tWR_CRC_DM; 317 | endfunction 318 | 319 | function void GetCWLSpeedRange_locked(input UTYPE_DutModeConfig dut_mode_config, input UTYPE_TS ts, input int tCK, 320 | output int min, output int max, output int ideal); 321 | ideal = 9; 322 | min = 9; 323 | max = 9; 324 | case (ts) 325 | TS_1875, 326 | TS_1500: begin 327 | if ((2 == dut_mode_config.wr_preamble_clocks) || (1 == dut_mode_config.gear_down)) begin 328 | ideal = 10; 329 | max = 10; 330 | end 331 | end 332 | TS_1250 : begin 333 | ideal = 9; 334 | if ((2 == dut_mode_config.wr_preamble_clocks) || (1 == dut_mode_config.gear_down)) 335 | ideal = 10; 336 | min = ideal; 337 | max = 11; 338 | end 339 | TS_1072 : begin 340 | ideal = 10; 341 | if (2 == dut_mode_config.wr_preamble_clocks) 342 | ideal = (1 == dut_mode_config.gear_down) ? 12 : 11; 343 | if (tCK >= 1250) begin 344 | ideal = 9; 345 | if (2 == dut_mode_config.wr_preamble_clocks) 346 | ideal = 11; 347 | end 348 | min = ideal; 349 | max = 12; 350 | end 351 | TS_938 : begin 352 | ideal = 11; 353 | if ((2 == dut_mode_config.wr_preamble_clocks) || (1 == dut_mode_config.gear_down)) 354 | ideal = 12; 355 | if (tCK >= 1250) begin 356 | ideal = 9; 357 | if (2 == dut_mode_config.wr_preamble_clocks) 358 | ideal = 11; 359 | end else if (tCK >= 1071) begin 360 | ideal = 10; 361 | if (2 == dut_mode_config.wr_preamble_clocks) 362 | ideal = 12; 363 | end 364 | min = ideal; 365 | max = 14; 366 | end 367 | TS_833 : begin 368 | ideal = 12; 369 | if (2 == dut_mode_config.wr_preamble_clocks) 370 | ideal = 14; 371 | if (tCK >= 1250) begin 372 | ideal = 9; 373 | if (2 == dut_mode_config.wr_preamble_clocks) 374 | ideal = 11; 375 | end else if (tCK >= 1071) begin 376 | ideal = 10; 377 | if (2 == dut_mode_config.wr_preamble_clocks) 378 | ideal = 12; 379 | end else if (tCK >= 937) begin 380 | ideal = 11; 381 | if (2 == dut_mode_config.wr_preamble_clocks) 382 | ideal = 14; 383 | end 384 | min = ideal; 385 | max = 16; 386 | end 387 | TS_750 : begin 388 | ideal = 14; 389 | if (2 == dut_mode_config.wr_preamble_clocks) 390 | ideal = 16; 391 | if (tCK >= 1250) begin 392 | ideal = 9; 393 | if (2 == dut_mode_config.wr_preamble_clocks) 394 | ideal = 11; 395 | end else if (tCK >= 1071) begin 396 | ideal = 10; 397 | if (2 == dut_mode_config.wr_preamble_clocks) 398 | ideal = 12; 399 | end else if (tCK >= 937) begin 400 | ideal = 11; 401 | if (2 == dut_mode_config.wr_preamble_clocks) 402 | ideal = 14; 403 | end else if (tCK >= 833) begin 404 | ideal = 12; 405 | if (2 == dut_mode_config.wr_preamble_clocks) 406 | ideal = 16; 407 | end 408 | min = ideal; 409 | max = 18; 410 | end 411 | TS_682, TS_625 : begin 412 | ideal = 16; 413 | if (2 == dut_mode_config.wr_preamble_clocks) 414 | ideal = 18; 415 | if (tCK >= 1250) begin 416 | ideal = 9; 417 | if (2 == dut_mode_config.wr_preamble_clocks) 418 | ideal = 11; 419 | end else if (tCK >= 1071) begin 420 | ideal = 10; 421 | if (2 == dut_mode_config.wr_preamble_clocks) 422 | ideal = 12; 423 | end else if (tCK >= 937) begin 424 | ideal = 11; 425 | if (2 == dut_mode_config.wr_preamble_clocks) 426 | ideal = 14; 427 | end else if (tCK >= 833) begin 428 | ideal = 12; 429 | if (2 == dut_mode_config.wr_preamble_clocks) 430 | ideal = 16; 431 | end else if (tCK >= 750) begin 432 | ideal = 14; 433 | if (2 == dut_mode_config.wr_preamble_clocks) 434 | ideal = 18; 435 | end 436 | min = ideal; 437 | max = 20; 438 | end 439 | 440 | endcase 441 | endfunction 442 | 443 | function int GettCCD_LSpeed_locked(input UTYPE_DutModeConfig dut_mode_config, input UTYPE_TS ts, input int tCK); 444 | int tCCD_L; 445 | 446 | tCCD_L = 4; 447 | case (ts) 448 | TS_1250, 449 | TS_1072 : begin 450 | if (tCK >= 1500) 451 | tCCD_L = 4; 452 | end 453 | TS_938, 454 | TS_833 : begin 455 | if (tCK >= 1500) 456 | tCCD_L = 4; 457 | else if (tCK >= 1071) 458 | tCCD_L = ((2 == dut_mode_config.wr_preamble_clocks) || (1 == dut_mode_config.gear_down)) ? 6 : 5; 459 | end 460 | TS_750 : begin 461 | if (tCK >= 1500) 462 | tCCD_L = 4; 463 | else if (tCK >= 1071) 464 | tCCD_L = ((2 == dut_mode_config.wr_preamble_clocks) || (1 == dut_mode_config.gear_down)) ? 6 : 5; 465 | else if (tCK >= 833) 466 | tCCD_L = 6; 467 | end 468 | TS_682 : begin 469 | if (tCK >= 1500) 470 | tCCD_L = 4; 471 | else if (tCK >= 1071) 472 | tCCD_L = ((2 == dut_mode_config.wr_preamble_clocks) || (1 == dut_mode_config.gear_down)) ? 6 : 5; 473 | else if (tCK >= 833) 474 | tCCD_L = 6; 475 | end 476 | TS_625 : begin 477 | if (tCK >= 1500) 478 | tCCD_L = 4; 479 | else if (tCK >= 1071) 480 | tCCD_L = ((2 == dut_mode_config.wr_preamble_clocks) || (1 == dut_mode_config.gear_down)) ? 6 : 5; 481 | else if (tCK >= 833) 482 | tCCD_L = 6; 483 | else if (tCK >= 682) 484 | tCCD_L = ((2 == dut_mode_config.wr_preamble_clocks) || (1 == dut_mode_config.gear_down)) ? 8 : 7; 485 | end 486 | endcase 487 | return tCCD_L; 488 | endfunction 489 | 490 | function bit ppr_available(input UTYPE_dutconfig dut_config); 491 | return 1; 492 | endfunction 493 | 494 | function bit sppr_available(input UTYPE_dutconfig dut_config); 495 | return 1; 496 | endfunction 497 | endpackage 498 | -------------------------------------------------------------------------------- /sim/ddr_ref_model/timing_tasks.sv: -------------------------------------------------------------------------------- 1 | // MICRON TECHNOLOGY, INC. - CONFIDENTIAL AND PROPRIETARY INFORMATION 2 | typedef enum { 3 | TS_LOADED, 4 | itCK_min, itCK_max, 5 | itDQSQ, itQHp, itDS, itDH, itIPW, 6 | itRPREp, itRPSTp, itQSHp, itQSLp, 7 | itWPSTp, itWPREp, itDQSCK, itDQSCK_min, itDQSCK_max, 8 | itDQSLp, itDQSHp, itDQSSp, itDQSSp_min, itDQSSp_max, 9 | itDLLKc_min, itRTP, itRTPc, itWTRc_S, itWTRc_L, itWTRc_S_CRC_DM, itWTRc_L_CRC_DM, itWR, itMRDc, itMOD, itMODc, 10 | itRCD, itRP, itRP_ref, itRC, itCCDc_S, itCCDc_L, 11 | itRRDc_S_512, itRRDc_L_512, itRRDc_S_1k, itRRDc_L_1k, itRRDc_S_2k, itRRDc_L_2k, 12 | itRRD_S_512, itRRD_L_512, itRRD_S_1k, itRRD_L_1k, itRRD_S_2k, itRRD_L_2k, 13 | itRAS, itFAW_512, itFAW_1k, itFAW_2k, itIS, itIH, itDIPW, 14 | itXPR, 15 | itPAR_ALERT_PWc, itPAR_ALERT_PWc_min, itPAR_ALERT_PWc_max, 16 | itXS, itXSDLLc, itCKESR, 17 | itCKSREc, itCKSRE, itCKSRXc, itCKSRX, itXSR, 18 | itXP, itXPc, itXPDLL, itXPDLLc, itCKE, itCKEc, itCPDEDc, itPD, itPDc, 19 | itACTPDENc, itPREPDENc, itREFPDENc, itMRSPDEN, 20 | itZQinitc, itZQoperc, itZQCSc, 21 | itWLS, itWLH, itAON_min, itAON_max, 22 | NUM_TIMESPEC 23 | } UTYPE_time_spec; 24 | 25 | // timing definition in tCK units 26 | integer tt_timesets [0:NUM_TS-1][0:NUM_TIMESPEC-1]; 27 | integer tCK; 28 | integer tOffset; 29 | int max_tCK, min_tCK; 30 | 31 | initial begin 32 | LoadTiming(); 33 | end 34 | 35 | // tCK and tOffset are the 'master' values. 36 | always @(tCK) begin 37 | timing.tCK = tCK; 38 | end 39 | always @(tOffset) begin 40 | timing.tOffset = tOffset; 41 | end 42 | 43 | task SettCK(input integer _tCK); 44 | tCK = _tCK; 45 | tOffset = _tCK; 46 | endtask 47 | 48 | task SetTimingStruct(input UTYPE_TS ts, UTYPE_tCKMode tck_mode = TCK_MIN); 49 | if (tt_timesets[ts][TS_LOADED] != 1) begin 50 | UTYPE_TS temp_ts; // 6.2 does not support name() on structures. 51 | 52 | temp_ts = timing.ts_loaded; 53 | $display("SetTiming:ERROR: Invalid timeset requested '%0s' @%0t. Timeset stays at '%0s'.", 54 | ts.name(), $time, temp_ts.name()); 55 | return; 56 | end 57 | 58 | if(tck_mode === TCK_MAX) begin 59 | SettCK(tt_timesets[ts][itCK_max]); 60 | end else if(tck_mode === TCK_RANDOM) begin 61 | SettCK($urandom_range(tt_timesets[ts][itCK_min], tt_timesets[ts][itCK_max])); 62 | end else 63 | SettCK(tt_timesets[ts][itCK_min]); 64 | `ifndef SILENT 65 | $display("Setting Timeset:%0s with tCk:%0d @%0t", ts.name(), tCK, $time); 66 | `endif 67 | timing.ts_loaded = ts; 68 | timing.tck_mode = tck_mode; 69 | // Clock timing. 70 | timing.ClockDutyCycle = 50; 71 | timing.tCK_min = tt_timesets[ts][itCK_min]; 72 | timing.tCK_max = tt_timesets[ts][itCK_max]; 73 | timing.tCHp_min = 48; 74 | timing.tCHp_min = 52; 75 | // Data timing. 76 | timing.tDQSQ = tt_timesets[ts][itDQSQ]; 77 | timing.tQHp = 38; 78 | timing.tDS = tt_timesets[ts][itDS]; 79 | timing.tDH = tt_timesets[ts][itDH]; 80 | timing.tIPW = tt_timesets[ts][itIPW]; 81 | // Data strobe timing. 82 | if (0 < tt_timesets[ts][itRPREp]) 83 | timing.tRPREp = tt_timesets[ts][itRPREp]; 84 | else 85 | timing.tRPREp = 100; 86 | if (0 < tt_timesets[ts][itRPSTp]) 87 | timing.tRPSTp = tt_timesets[ts][itRPSTp]; 88 | else 89 | timing.tRPSTp = 50; 90 | timing.tQSHp = 40; 91 | timing.tQSLp = 40; 92 | timing.tWPSTp = 50; 93 | timing.tWPREp = 100; 94 | timing.tDQSCK = tt_timesets[ts][itDQSCK]; 95 | timing.tDQSCK_dll_on = tt_timesets[ts][itDQSCK]; 96 | timing.tDQSCK_min = tt_timesets[ts][itDQSCK_min]; 97 | timing.tDQSCK_max = tt_timesets[ts][itDQSCK_max]; 98 | timing.tDQSCK_dll_off = 5800; 99 | timing.tDQSCK_dll_off_min = 1000; 100 | timing.tDQSCK_dll_off_max = 9000; 101 | timing.tDQSLp = 50; 102 | timing.tDQSLp_min = 45; 103 | timing.tDQSLp_max = 55; 104 | timing.tDQSHp = 50; 105 | timing.tDQSHp_min = 45; 106 | timing.tDQSHp_max = 55; 107 | timing.tDQSSp = 0; // Nominal. 108 | timing.tDQSSp_1tCK_min = -27; 109 | timing.tDQSSp_1tCK_max = 27; 110 | timing.tDQSSp_2tCK_min = timing.tDQSSp_1tCK_min; 111 | timing.tDQSSp_2tCK_max = timing.tDQSSp_1tCK_max; 112 | timing.tDQSSp_min = timing.tDQSSp_1tCK_min; 113 | timing.tDQSSp_max = timing.tDQSSp_1tCK_max; 114 | // Command and address timing. 115 | timing.tDLLKc = tt_timesets[ts][itDLLKc_min]; 116 | timing.tRTP = tt_timesets[ts][itRTP]; 117 | timing.tRTPc = ParamInClks(tt_timesets[ts][itRTP], tt_timesets[ts][itCK_min]); 118 | timing.tRTP_min = tt_timesets[ts][itRTP]; 119 | timing.tRTPc_min = 4; 120 | timing.tWTR_S = 2500; 121 | timing.tWTRc_S = ParamInClks(tt_timesets[ts][timing.tWTR_S], tt_timesets[ts][itCK_min]); 122 | timing.tWTR_L = 7500; 123 | timing.tWTRc_L = ParamInClks(tt_timesets[ts][timing.tWTR_L], tt_timesets[ts][itCK_min]); 124 | timing.tWTR_S_CRC_DM = 3750; 125 | timing.tWTRc_S_CRC_DM = ParamInClks(tt_timesets[ts][timing.tWTR_S_CRC_DM], tt_timesets[ts][itCK_min]); 126 | timing.tWTR_L_CRC_DM = 3750; 127 | timing.tWTRc_L_CRC_DM = ParamInClks(tt_timesets[ts][timing.tWTR_L_CRC_DM], tt_timesets[ts][itCK_min]); 128 | timing.tWR = tt_timesets[ts][itWR]; 129 | timing.tWRc = ParamInClks(tt_timesets[ts][itWR], tt_timesets[ts][itCK_min]); 130 | timing.tWR_CRC_DMc = 5; 131 | timing.tMRDc = 8; 132 | timing.tMOD = tt_timesets[ts][itMOD]; 133 | timing.tMODc = ParamInClks(tt_timesets[ts][itMOD], tt_timesets[ts][itCK_min]); 134 | timing.tMPRRc = 1; 135 | timing.tWR_MPRc = timing.tMODc; 136 | timing.tRCD = tt_timesets[ts][itRCD]; 137 | timing.tRCDc = ParamInClks(tt_timesets[ts][itRCD], tt_timesets[ts][itCK_min]); 138 | timing.tRP = tt_timesets[ts][itRP]; 139 | timing.tRPc = ParamInClks(tt_timesets[ts][itRP], tt_timesets[ts][itCK_min]); 140 | timing.tRP_ref_internal = tt_timesets[ts][itRP_ref]; 141 | timing.tRPc_ref_internal = ParamInClks(tt_timesets[ts][itRP_ref], tt_timesets[ts][itCK_min]); 142 | timing.tRC = tt_timesets[ts][itRC]; 143 | timing.tRCc = ParamInClks(tt_timesets[ts][itRC], tt_timesets[ts][itCK_min]); 144 | timing.tCCD_S = tt_timesets[ts][itCCDc_S] * tt_timesets[ts][itCK_min]; 145 | timing.tCCDc_S = tt_timesets[ts][itCCDc_S]; 146 | timing.tCCD_L = tt_timesets[ts][itCCDc_L] * tt_timesets[ts][itCK_min]; 147 | timing.tCCDc_L = tt_timesets[ts][itCCDc_L]; 148 | timing.tRAS = tt_timesets[ts][itRAS]; 149 | timing.tRASc = ParamInClks(tt_timesets[ts][itRAS], tt_timesets[ts][itCK_min]); 150 | timing.tPAR_CLOSE_BANKS = timing.tRAS; 151 | timing.tPAR_ALERT_ON = 1400; 152 | timing.tPAR_ALERT_ON_max = 6000; 153 | timing.tPAR_ALERT_ON_CYCLES = 4; 154 | timing.tPAR_ALERT_OFF = 3000; 155 | timing.tPAR_tRP_tRAS_adjustment = 2000; 156 | timing.tPAR_tRP_holdoff_adjustment = 1450; 157 | timing.tPAR_ALERT_PWc = tt_timesets[ts][itPAR_ALERT_PWc]; 158 | timing.tPAR_ALERT_PWc_min = tt_timesets[ts][itPAR_ALERT_PWc_min]; 159 | timing.tPAR_ALERT_PWc_max = tt_timesets[ts][itPAR_ALERT_PWc_max]; 160 | timing.tPAR_ALERT_PW = timing.tPAR_ALERT_PWc * tt_timesets[ts][itCK_min]; 161 | timing.tPAR_ALERT_PW_min = timing.tPAR_ALERT_PWc_min * tt_timesets[ts][itCK_min]; 162 | timing.tPAR_ALERT_PW_max = timing.tPAR_ALERT_PWc_max * tt_timesets[ts][itCK_min]; 163 | timing.tCRC_ALERT = 9000; 164 | timing.tCRC_ALERT_min = 3000; 165 | timing.tCRC_ALERT_max = 13000; 166 | timing.tCRC_ALERT_PWc_min = 6; 167 | timing.tCRC_ALERT_PWc_max = 10; 168 | timing.tCRC_ALERT_PWc = 7; 169 | if (16 == GetWidth()) begin 170 | timing.tFAW = tt_timesets[ts][itFAW_2k]; 171 | timing.tRRDc_S = tt_timesets[ts][itRRDc_S_2k]; 172 | timing.tRRDc_L = tt_timesets[ts][itRRDc_L_2k]; 173 | timing.tRRD_S = tt_timesets[ts][itRRD_S_2k]; 174 | timing.tRRD_L = tt_timesets[ts][itRRD_L_2k]; 175 | end else if (4 == GetWidth()) begin 176 | timing.tFAW = tt_timesets[ts][itFAW_512]; 177 | timing.tRRDc_S = tt_timesets[ts][itRRDc_S_512]; 178 | timing.tRRDc_L = tt_timesets[ts][itRRDc_L_512]; 179 | timing.tRRD_S = tt_timesets[ts][itRRD_S_512]; 180 | timing.tRRD_L = tt_timesets[ts][itRRD_L_512]; 181 | end else begin 182 | timing.tFAW = tt_timesets[ts][itFAW_1k]; 183 | timing.tRRDc_S = tt_timesets[ts][itRRDc_S_1k]; 184 | timing.tRRDc_L = tt_timesets[ts][itRRDc_L_1k]; 185 | timing.tRRD_S = tt_timesets[ts][itRRD_S_1k]; 186 | timing.tRRD_L = tt_timesets[ts][itRRD_L_1k]; 187 | end 188 | timing.tRRDc_dlr = 4; 189 | timing.tFAWc_dlr = 16; 190 | timing.tIS = tt_timesets[ts][itIS]; 191 | timing.tIH = tt_timesets[ts][itIH]; 192 | timing.tDIPW = tt_timesets[ts][itDIPW]; 193 | if (_2G == CONFIGURED_DENSITY) begin 194 | timing.tRFC1 = 160000; 195 | timing.tRFC2 = 110000; 196 | timing.tRFC4 = 90000; 197 | end else if (_4G == CONFIGURED_DENSITY) begin 198 | timing.tRFC1 = 260000; 199 | timing.tRFC2 = 160000; 200 | timing.tRFC4 = 110000; 201 | end else if (_8G == CONFIGURED_DENSITY) begin 202 | timing.tRFC1 = 350000; 203 | timing.tRFC2 = 260000; 204 | timing.tRFC4 = 160000; 205 | end else if (_16G == CONFIGURED_DENSITY) begin 206 | timing.tRFC1 = 350000; 207 | timing.tRFC2 = 260000; 208 | timing.tRFC4 = 160000; 209 | end 210 | timing.tRFC = timing.tRFC1; 211 | timing.tRFCc = ParamInClks(timing.tRFC1, tt_timesets[ts][itCK_min]); 212 | timing.tRFC1c = ParamInClks(timing.tRFC1, tt_timesets[ts][itCK_min]); 213 | timing.tRFC2c = ParamInClks(timing.tRFC2, tt_timesets[ts][itCK_min]); 214 | timing.tRFC4c = ParamInClks(timing.tRFC4, tt_timesets[ts][itCK_min]); 215 | // Reset timing. 216 | timing.tXPR = timing.tRFC + 10000; 217 | // Self refresh timing. 218 | timing.tXS = timing.tRFC + 10000; 219 | timing.tXSc = ParamInClks(timing.tRFC + 10000, tt_timesets[ts][itCK_min]); 220 | timing.tXS_Fast = timing.tRFC4 + 10000; 221 | timing.tXS_Fastc = ParamInClks(timing.tXS_Fast, tt_timesets[ts][itCK_min]); 222 | timing.tXSDLLc = tt_timesets[ts][itDLLKc_min]; 223 | timing.tCKESRc = ParamInClks(tt_timesets[ts][itCKE], tt_timesets[ts][itCK_min]) + 1; 224 | timing.tCKSRE = 10000; 225 | timing.tCKSREc = ParamInClks(timing.tCKSRE, tt_timesets[ts][itCK_min]); 226 | if (timing.tCKSREc < 5) begin 227 | timing.tCKSREc = 5; 228 | timing.tCKSRE = timing.tCKSREc * tt_timesets[ts][itCK_min]; 229 | end 230 | timing.tCKSRX = 10000; 231 | timing.tCKSRXc = ParamInClks(timing.tCKSRX, tt_timesets[ts][itCK_min]); 232 | if (timing.tCKSRXc < 5) begin 233 | timing.tCKSRXc = 5; 234 | timing.tCKSRX = timing.tCKSRXc * tt_timesets[ts][itCK_min]; 235 | end 236 | timing.tXSR = timing.tRFC + 10000; 237 | // Power down timing. 238 | if (timing.tCK_min > 1500) begin 239 | timing.tXPc = 4; 240 | timing.tXP = 4 * timing.tCK_min; 241 | end else begin 242 | timing.tXP = 6000; 243 | timing.tXPc = ParamInClks(6000, tt_timesets[ts][itCK_min]); 244 | end 245 | timing.tXPDLL = tt_timesets[ts][itXPDLL]; 246 | timing.tXPDLLc = ParamInClks(tt_timesets[ts][itXPDLL], tt_timesets[ts][itCK_min]); 247 | timing.tCKE = tt_timesets[ts][itCKE]; 248 | timing.tCKEc = ParamInClks(tt_timesets[ts][itCKE], tt_timesets[ts][itCK_min]); 249 | timing.tCPDEDc = tt_timesets[ts][itCPDEDc]; 250 | timing.tPD = tt_timesets[ts][itCKE]; 251 | timing.tPDc = ParamInClks(tt_timesets[ts][itCKE], tt_timesets[ts][itCK_min]); 252 | // tRDPDEN/tWRPDEN are calculated dynamically. 253 | timing.tACTPDENc = tt_timesets[ts][itACTPDENc]; 254 | timing.tPREPDENc = tt_timesets[ts][itPREPDENc]; 255 | timing.tREFPDENc = tt_timesets[ts][itREFPDENc]; 256 | timing.tMRSPDENc = timing.tMODc; 257 | timing.tMRSPDEN = tt_timesets[ts][itMOD]; 258 | // Initialization timing. 259 | timing.tPWRUP = 100000; 260 | timing.tRESET = 100000; // Stable power @100ns ramp @200us. 261 | timing.tRESETCKE = 100000; // Spec is 500us. 262 | timing.tODTHc = 4; 263 | timing.tZQinitc = tt_timesets[ts][itZQinitc]; 264 | timing.tZQoperc = tt_timesets[ts][itZQoperc]; 265 | timing.tZQCSc = tt_timesets[ts][itZQCSc]; 266 | timing.tZQRTT = 44_000; 267 | timing.tZQRTTc = ParamInClks(timing.tZQRTT, tt_timesets[ts][itCK_min]); 268 | // Write leveling. 269 | timing.tWLMRDc = 40; 270 | timing.tWLDQSENc = 25; 271 | timing.tWLS = tt_timesets[ts][itWLS]; 272 | timing.tWLSc = ParamInClks(tt_timesets[ts][itWLS], tt_timesets[ts][itCK_min]); 273 | timing.tWLH = tt_timesets[ts][itWLH]; 274 | timing.tWLHc = ParamInClks(tt_timesets[ts][itWLH], tt_timesets[ts][itCK_min]); 275 | timing.tWLO_min = 0; 276 | timing.tWLOc_min = 0; 277 | timing.tWLO_max = 7500; 278 | timing.tWLOc_max = ParamInClks(timing.tWLO_max, tt_timesets[ts][itCK_min]); 279 | timing.tWLOE_min = 0; 280 | timing.tWLOEc_min = 0; 281 | timing.tWLOEc_max = ParamInClks(timing.tWLOE_max, tt_timesets[ts][itCK_min]); 282 | timing.tWLO_nominal = (timing.tWLO_min + timing.tWLO_max)/2; 283 | timing.tWLOE_nominal = (timing.tWLOE_min + timing.tWLOE_max)/2; 284 | // ODT Timing. 285 | timing.tAON = 0; 286 | timing.tAON_min = tt_timesets[ts][itAON_min]; 287 | timing.tAON_max = tt_timesets[ts][itAON_max]; 288 | timing.tAOF = 0; 289 | timing.tAOFp = 50; 290 | timing.tAOFp_min = 30; 291 | timing.tAOFp_max = 70; 292 | timing.tADCp = 50; 293 | timing.tADCp_min = 30; 294 | timing.tADCp_max = 70; 295 | timing.tAONPD = 5000; 296 | timing.tAONPDc = 5000/tt_timesets[ts][itCK_min]; // Do not round ntCK up. 297 | timing.tAONPD_min = 1000; 298 | timing.tAONPD_max = 10000; 299 | timing.tAOFPD = 5000; 300 | timing.tAOFPDc = 5000/tt_timesets[ts][itCK_min]; // Do not round ntCK up. 301 | timing.tAOFPD_min = 1000; 302 | timing.tAOFPD_max = 10000; 303 | timing.tAOFASp = 50; // Async time for ODT forced off (read). 304 | timing.tAONASp_max = 20; // Async ODT turn on/off. 305 | // Read preamble training. 306 | timing.tSDO_max = timing.tMOD + 9000; 307 | timing.tSDOc_max = ParamInClks(timing.tSDO_max, tt_timesets[ts][itCK_min]); 308 | timing.tSDO = 7000; 309 | timing.tSDOc = ParamInClks(timing.tSDO, tt_timesets[ts][itCK_min]); 310 | // Gear down setup. 311 | timing.tSYNC_GEARc = (0 == (timing.tMODc % 2)) ? timing.tMODc + 4 : timing.tMODc + 5; 312 | timing.tCMD_GEARc = (0 == (timing.tMODc % 2)) ? timing.tMODc : timing.tMODc + 1; 313 | timing.tGD_TRANSITIONc = MAX_WL; 314 | // Maximum power saving setup. 315 | timing.tMPED = timing.tMOD + timing.tCPDEDc*tt_timesets[ts][itCK_min]; 316 | timing.tCKMPE = timing.tMOD + timing.tCPDEDc*tt_timesets[ts][itCK_min]; 317 | timing.tCKMPX = timing.tCKSRX; 318 | timing.tMPX_H = 2*tt_timesets[ts][itCK_min]; 319 | timing.tMPEDc = ParamInClks(timing.tMPED, tt_timesets[ts][itCK_min]); 320 | timing.tCKMPEc = ParamInClks(timing.tCKMPE, tt_timesets[ts][itCK_min]); 321 | timing.tCKMPXc = ParamInClks(timing.tCKMPX, tt_timesets[ts][itCK_min]); 322 | timing.tXMPc = timing.tXSc; 323 | timing.tXMPDLLc = timing.tXMPc + timing.tXSDLLc; 324 | // CAL setup. 325 | timing.tCAL_min = 3750; 326 | timing.tCALc_min = ParamInClks(timing.tCAL_min, tt_timesets[ts][itCK_min]); 327 | // Boundary scan. 328 | timing.tBSCAN_Enable = 100000; 329 | timing.tBSCAN_Valid = 20000; 330 | // Per project settings. 331 | timing.tWLO_project = 6300; 332 | endtask 333 | 334 | task LoadTiming(); 335 | $display("Loading timesets for '%m' @%0t", $time); 336 | // All timesets initialize to UNLOADED. 337 | for (int i=0;i max_tCK) 408 | max_tCK = tt_timesets[ts][itCK_max]; 409 | $display("\tLoaded timeset:%0s", ts.name()); 410 | end else begin 411 | $display("\tTimeset:%0s was not loaded.", ts.name()); 412 | end 413 | end 414 | endtask 415 | 416 | task SetTSArray(UTYPE_time_spec spec, int ts_1875, int ts_1500, int ts_1250, int ts_1072, 417 | int ts_938, int ts_833, int ts_750, int ts_682, int ts_625); 418 | tt_timesets[TS_1875][spec] = ts_1875; 419 | tt_timesets[TS_1500][spec] = ts_1500; 420 | tt_timesets[TS_1250][spec] = ts_1250; 421 | tt_timesets[TS_1072][spec] = ts_1072; 422 | tt_timesets[TS_938][spec] = ts_938; 423 | tt_timesets[TS_833][spec] = ts_833; 424 | tt_timesets[TS_750][spec] = ts_750; 425 | tt_timesets[TS_682][spec] = ts_682; 426 | tt_timesets[TS_625][spec] = ts_625; 427 | endtask 428 | 429 | function bit FindTimesetCeiling(int tck, output UTYPE_TS new_ts); 430 | bit found; 431 | 432 | found = 0; 433 | for (UTYPE_TS ts=ts.first();ts= tt_timesets[ts][itCK_min]))) begin 435 | new_ts = ts; 436 | found = 1; 437 | end 438 | end 439 | return found; 440 | endfunction 441 | 442 | function int ParamInClks(int param_in_ps, int tCK_in_ps); 443 | `ifdef ALLOW_JITTER 444 | int param_in_ck_20fs; 445 | param_in_ck_20fs = (50*param_in_ps) / tCK_in_ps; 446 | if (0 == (param_in_ck_20fs % 50)) 447 | `else 448 | if (0 == (param_in_ps % tCK_in_ps)) 449 | `endif 450 | return (param_in_ps / tCK_in_ps); 451 | else 452 | return ((param_in_ps / tCK_in_ps) + 1); 453 | endfunction 454 | 455 | function int GetTimesetValue(UTYPE_time_spec spec, UTYPE_TS ts=timing.ts_loaded); 456 | return tt_timesets[ts][spec]; 457 | endfunction 458 | -------------------------------------------------------------------------------- /sim/ip/.Xil/.ddr4_ctrl.xcix.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aliyun/alibabacloud-fpga/9973e5b4219c83ef9b96282f5cc1937eaec93e90/sim/ip/.Xil/.ddr4_ctrl.xcix.lock -------------------------------------------------------------------------------- /sim/ip/ddr4_ctrl.xcix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aliyun/alibabacloud-fpga/9973e5b4219c83ef9b96282f5cc1937eaec93e90/sim/ip/ddr4_ctrl.xcix -------------------------------------------------------------------------------- /sim/scripts/import_sim_env.tcl: -------------------------------------------------------------------------------- 1 | # Get current directory, used throughout script 2 | set scriptDir [file dirname [file normalize [info script]]] 3 | set simplatformDir [file dirname $scriptDir] 4 | set hdk_file [file dirname $simplatformDir] 5 | puts $simplatformDir 6 | #set simDir [file dirname $scriptDir] 7 | 8 | ############### import Faas simulation platform ############# 9 | import_files -fileset sim_1 -norecurse ${simplatformDir}/source/aliyun_faas_xdma_driver.sv 10 | import_files -fileset sim_1 -norecurse ${simplatformDir}/source/aliyun_faas_dma_driver.sv 11 | import_files -fileset sim_1 -norecurse ${simplatformDir}/source/aliyun_faas_sim_top.sv 12 | import_files -fileset sim_1 -norecurse ${simplatformDir}/source/aliyun_faas_dma_agent.sv 13 | import_files -fileset sim_1 -norecurse ${simplatformDir}/source/aliyun_faas_driver.sv 14 | import_files -fileset sim_1 -norecurse ${simplatformDir}/source/aliyun_faas_agent.sv 15 | import_files -fileset sim_1 -norecurse ${simplatformDir}/source/aliyun_faas_xdma_agent.sv 16 | import_files -fileset sim_1 -norecurse ${simplatformDir}/source/aliyun_faas_interrupt_driver.sv 17 | import_files -fileset sim_1 -norecurse ${simplatformDir}/source/aliyun_faas_interrupt_agent.sv 18 | import_files -fileset sim_1 -norecurse ${simplatformDir}/source/aliyun_faas_sim_env.sv 19 | import_files -fileset sim_1 -norecurse ${simplatformDir}/source/aliyun_faas_interfaces.sv 20 | import_files -fileset sim_1 -norecurse ${simplatformDir}/source/aliyun_faas_alite_driver.sv 21 | import_files -fileset sim_1 -norecurse ${simplatformDir}/source/aliuyun_faas_sim_tb.sv 22 | import_files -fileset sim_1 -norecurse ${simplatformDir}/source/aliyun_faas_ddr_ref_model.sv 23 | import_files -fileset sim_1 -norecurse ${simplatformDir}/source/aliyun_faas_base_pkg.sv 24 | import_files -fileset sim_1 -norecurse ${simplatformDir}/source/aliyun_faas_alite_agent.sv 25 | import_files -fileset sim_1 -norecurse ${simplatformDir}/source/aliyun_faas_card_model.sv 26 | 27 | set_property file_type {Verilog Header} [get_files aliyun_faas_xdma_driver.sv] 28 | set_property file_type {Verilog Header} [get_files aliyun_faas_dma_driver.sv] 29 | set_property file_type {Verilog Header} [get_files aliyun_faas_dma_agent.sv] 30 | set_property file_type {Verilog Header} [get_files aliyun_faas_driver.sv] 31 | set_property file_type {Verilog Header} [get_files aliyun_faas_agent.sv] 32 | set_property file_type {Verilog Header} [get_files aliyun_faas_xdma_agent.sv] 33 | set_property file_type {Verilog Header} [get_files aliyun_faas_interrupt_driver.sv] 34 | set_property file_type {Verilog Header} [get_files aliyun_faas_interrupt_agent.sv] 35 | set_property file_type {Verilog Header} [get_files aliyun_faas_sim_env.sv] 36 | set_property file_type {Verilog Header} [get_files aliyun_faas_interfaces.sv] 37 | set_property file_type {Verilog Header} [get_files aliyun_faas_alite_driver.sv] 38 | set_property file_type {Verilog Header} [get_files aliyun_faas_base_pkg.sv] 39 | set_property file_type {Verilog Header} [get_files aliyun_faas_alite_agent.sv] 40 | 41 | ############### import ddr_ref_model files ############# 42 | import_files -fileset sim_1 -norecurse ${simplatformDir}/ddr_ref_model/timing_tasks.sv 43 | import_files -fileset sim_1 -norecurse ${simplatformDir}/ddr_ref_model/StateTableCore.sv 44 | import_files -fileset sim_1 -norecurse ${simplatformDir}/ddr_ref_model/StateTable.sv 45 | import_files -fileset sim_1 -norecurse ${simplatformDir}/ddr_ref_model/proj_package.sv 46 | import_files -fileset sim_1 -norecurse ${simplatformDir}/ddr_ref_model/MemoryArray.sv 47 | import_files -fileset sim_1 -norecurse ${simplatformDir}/ddr_ref_model/interface.sv 48 | import_files -fileset sim_1 -norecurse ${simplatformDir}/ddr_ref_model/ddr_model.sv 49 | import_files -fileset sim_1 -norecurse ${simplatformDir}/ddr_ref_model/ddr4_sdram_model_wrapper.sv 50 | import_files -fileset sim_1 -norecurse ${simplatformDir}/ddr_ref_model/ddr4_model.sv 51 | import_files -fileset sim_1 -norecurse ${simplatformDir}/ddr_ref_model/arch_package.sv 52 | import_files -fileset sim_1 -norecurse ${simplatformDir}/ddr_ref_model/arch_defines.v 53 | 54 | set_property file_type {Verilog Header} [get_files StateTableCore.sv] 55 | set_property file_type {Verilog Header} [get_files timing_tasks.sv] 56 | set_property file_type {Verilog Header} [get_files arch_defines.v] 57 | set_property file_type {Verilog Header} [get_files StateTable.sv] 58 | set_property file_type {Verilog Header} [get_files MemoryArray.sv] 59 | set_property file_type {Verilog Header} [get_files ddr4_sdram_model_wrapper.sv] 60 | set_property file_type {Verilog Header} [get_files arch_package.sv] 61 | 62 | 63 | 64 | ############### import ddr ctrl ip ############# 65 | import_ip ${simplatformDir}/ip/ddr4_ctrl.xcix 66 | 67 | ############### import ddr config file ############# 68 | import_files -fileset sim_1 -norecurse ${hdk_file}/hw/sources/config/config.v 69 | set_property file_type {Verilog Header} [get_files config.v] 70 | -------------------------------------------------------------------------------- /sim/source/aliuyun_faas_sim_tb.sv: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////////// 2 | // Company: aliyun 3 | // Engineer: Yuqi 4 | // 5 | // Description: faas simulation platfrom testbench 6 | // 7 | // Dependencies: 8 | // 9 | // Revision: V1.0 10 | // Revision 0.01 -File Created 11 | // Additional Comments: 12 | // 13 | ////////////////////////////////////////////////////////////////////////////////// 14 | `ifndef FAAS_SIM_TB 15 | `define FAAS_SIM_TB 16 | `include "aliyun_faas_base_pkg.sv" 17 | `include "aliyun_faas_interfaces.sv" 18 | `include "aliyun_faas_sim_env.sv" 19 | `endif 20 | program aliuyun_faas_sim_tb( 21 | axi_lite.tb alite_driver, 22 | axi4.master_tb xdma_driver, 23 | axi4.slave_tb dma_driver, 24 | faas_interrupt.tb int_driver, 25 | 26 | ddr_axi4.slave c0_ddr4_if, 27 | ddr_axi4.slave c1_ddr4_if, 28 | ddr_axi4.slave c2_ddr4_if, 29 | ddr_axi4.slave c3_ddr4_if 30 | ); 31 | //=================================================================================== 32 | //members 33 | //=================================================================================== 34 | aliyun_faas_sim_env faas_sim_env; 35 | //=================================================================================== 36 | //platform init 37 | //=================================================================================== 38 | initial 39 | begin 40 | faas_sim_env=new(alite_driver, 41 | xdma_driver, 42 | dma_driver, 43 | int_driver, 44 | c0_ddr4_if, 45 | c1_ddr4_if, 46 | c2_ddr4_if, 47 | c3_ddr4_if 48 | ); 49 | faas_sim_env.build(); 50 | faas_sim_env.run(); 51 | end 52 | //=================================================================================== 53 | //user application 54 | //=================================================================================== 55 | initial 56 | begin 57 | int state; 58 | logic [31:0] rdata; 59 | faas_sim_env.faas_wait_for_ddr_cal_done(); //about 5.2us 60 | //user code 61 | //xdma_test(); 62 | //ddr_access_test(); 63 | //dma_test(); 64 | //$stop(); 65 | interrupt_test(); 66 | end 67 | //=================================================================================== 68 | //interrupt action 69 | //=================================================================================== 70 | initial 71 | begin 72 | interrupt_ack(); 73 | //user code 74 | 75 | end 76 | //=================================================================================== 77 | //xdma test simulation 78 | //=================================================================================== 79 | task xdma_test(); 80 | byte unsigned wdata[],rdata[]; 81 | int state; 82 | wdata=new[4096]; 83 | foreach (wdata[i]) 84 | wdata[i]=$random()%256; 85 | foreach (wdata[i]) 86 | $display("wadata[%d]=%h",i,wdata[i]); 87 | //copy data from host to cl 88 | faas_sim_env.faas_xdma_write(wdata,'h0,0,state); 89 | $display("xdma write data complete,state code:%d",state); 90 | //copy data from cl to host 91 | faas_sim_env.faas_xdma_read('h0,4096,0,0,rdata,state); 92 | $display("xdma read data complete,state code:%d",state); 93 | //data check 94 | foreach(wdata[i]) 95 | begin 96 | if(wdata[i]!=rdata[i]) 97 | begin 98 | $display("data error:wdata[%d]=%d\t,rdata[%d]=%d",i,wdata[i],i,rdata[i]); 99 | $stop; 100 | end 101 | end 102 | $display ("TEST PASSED!"); 103 | endtask 104 | //=================================================================================== 105 | //DDR ACCESS TEST DEMO 106 | //=================================================================================== 107 | task ddr_access_test(); 108 | `define DDR_BASE 32'h00000 109 | `define PRBS_START `DDR_BASE + 32'h1C 110 | `define PRBS_STOP `DDR_BASE + 32'h20 111 | `define PRBS_CLPT `DDR_BASE + 32'h28 112 | `define PRBS_ERR `DDR_BASE + 32'h30 113 | 114 | `define C0_TXCMD_CNT `DDR_BASE + 32'h40 115 | `define C0_RXCMD_CNT `DDR_BASE + 32'h44 116 | `define C1_TXCMD_CNT `DDR_BASE + 32'h48 117 | `define C1_RXCMD_CNT `DDR_BASE + 32'h4c 118 | `define C2_TXCMD_CNT `DDR_BASE + 32'h50 119 | `define C2_RXCMD_CNT `DDR_BASE + 32'h54 120 | `define C3_TXCMD_CNT `DDR_BASE + 32'h58 121 | `define C3_RXCMD_CNT `DDR_BASE + 32'h5c 122 | 123 | int state; 124 | logic [`ALITE_RDATA_WIDTH-1:0] rdata; 125 | 126 | //start prbs test 127 | faas_sim_env.faas_alite_write(`PRBS_START,32'hf,0,state); 128 | $display("PRBS_START WRITE COMPLETE,STATE CODE:%d",state); 129 | #2us; 130 | //stop prbs test 131 | faas_sim_env.faas_alite_write(`PRBS_STOP,32'hf,0,state); 132 | $display("PRBS_STOP WRITE COMPLETE,STATE CODE:%d",state); 133 | //tx and rx count 134 | faas_sim_env.faas_alite_read(`C0_TXCMD_CNT,0,state,rdata); 135 | $display("DDR0 tx counts:%d",rdata); 136 | faas_sim_env.faas_alite_read(`C0_RXCMD_CNT,0,state,rdata); 137 | $display("DDR0 rx counts:%d",rdata); 138 | faas_sim_env.faas_alite_read(`C1_TXCMD_CNT,0,state,rdata); 139 | $display("DDR1 tx counts:%d",rdata); 140 | faas_sim_env.faas_alite_read(`C1_RXCMD_CNT,0,state,rdata); 141 | $display("DDR1 rx counts:%d",rdata); 142 | faas_sim_env.faas_alite_read(`C2_TXCMD_CNT,0,state,rdata); 143 | $display("DDR2 tx counts:%d",rdata); 144 | faas_sim_env.faas_alite_read(`C2_RXCMD_CNT,0,state,rdata); 145 | $display("DDR2 rx counts:%d",rdata); 146 | faas_sim_env.faas_alite_read(`C3_TXCMD_CNT,0,state,rdata); 147 | $display("DDR3 tx counts:%d",rdata); 148 | faas_sim_env.faas_alite_read(`C3_RXCMD_CNT,0,state,rdata); 149 | $display("DDR3 rx counts:%d",rdata); 150 | endtask 151 | //=================================================================================== 152 | //DMA TEST DEMO 153 | //=================================================================================== 154 | task dma_test(); 155 | `define BASE 32'h10000 156 | `define H2F `BASE + 8'h14 157 | `define F2H `BASE + 8'h1C 158 | `define H2F_RST `BASE + 8'h18 159 | `define F2H_RST `BASE + 8'h20 160 | `define ADDR_LOW `BASE + 8'h24 161 | `define ADDR_HIGH `BASE + 8'h28 162 | `define LEN `BASE + 8'h2C 163 | `define COUNT `BASE + 8'h30 164 | `define SIZE `BASE + 8'h34 165 | `define REPEAT_NUM `BASE + 8'h38 166 | `define TRANS_MODE `BASE + 8'h50 167 | `define PKG_NUM `BASE + 8'h54 168 | `define CLR_ERR `BASE + 8'h58 169 | `define MODE `BASE + 8'h5c 170 | `define MAXSIZE_LOW `BASE + 8'h60 171 | `define MAXSIZE_HIGH `BASE + 8'h64 172 | `define TX_COUNT `BASE + 8'h80 173 | `define RX_COUNT `BASE + 8'h88 174 | `define ERR_COUNT `BASE + 8'h84 175 | `define SEND_CYC_HIGH `BASE + 8'h8c 176 | `define SEND_CYC_LOW `BASE + 8'h90 177 | `define REC_CYC_HIGH `BASE + 8'h8c 178 | `define REC_CYC_LOW `BASE + 8'h90 179 | 180 | //TRANSFER MODE [7:4] IS LEN, TRANS_MODE [3:0] IS SIZE. LEN=4BITS SIZE=3BITS. 181 | `define MODE_64 32'h06 // len 1 (b0000) * size 64B (b110) 182 | `define MODE_128 32'h16 // len 2 (b0001) * size 64B (b110) 183 | `define MODE_192 32'h26 184 | `define MODE_256 32'h36 // len 4 (b0011) * size 64B (b110) 185 | `define MODE_320 32'h46 186 | `define MODE_384 32'h56 187 | `define MODE_448 32'h66 188 | `define MODE_512 32'h76 // len 8 (b0111) * size 64B (b110) 189 | `define MODE_576 32'h86 190 | `define MODE_640 32'h96 191 | `define MODE_704 32'ha6 192 | `define MODE_768 32'hb6 193 | `define MODE_832 32'hc6 194 | `define MODE_896 32'hd6 195 | `define MODE_960 32'he6 196 | `define MODE_1024 32'hf6 // len 16 (b1111) * size 64B (b110) 197 | 198 | logic[31:0] tx_pkg,rx_pkg,err_count; 199 | logic[63:0] sned_cyc_count,rec_cyc_count; 200 | int state; 201 | 202 | // configure pci_register to start backdoor host memory access via PCIeM 203 | faas_sim_env.faas_alite_write(`H2F_RST,32'h1,0,state); 204 | faas_sim_env.faas_alite_write(`F2H_RST,32'h1,0,state); 205 | faas_sim_env.faas_alite_write(`ADDR_LOW,32'h0,0,state); 206 | faas_sim_env.faas_alite_write(`ADDR_HIGH,32'h0,0,state); 207 | faas_sim_env.faas_alite_write(`MODE,32'h0,0,state); 208 | $display("START NORMAL TEST"); 209 | faas_sim_env.faas_alite_write(`TRANS_MODE,`MODE_1024,0,state); 210 | faas_sim_env.faas_alite_write(`PKG_NUM,32'h10,0,state); 211 | //start writing data to host memory 212 | faas_sim_env.faas_alite_write(`F2H,32'h1,0,state); 213 | #2us; 214 | //start reading data from host memory 215 | faas_sim_env.faas_alite_write(`H2F,32'h1,0,state); 216 | #2us; 217 | faas_sim_env.faas_alite_read(`TX_COUNT,0,state,tx_pkg); 218 | faas_sim_env.faas_alite_read(`RX_COUNT,0,state,rx_pkg); 219 | faas_sim_env.faas_alite_read(`SEND_CYC_HIGH,0,state,sned_cyc_count[63:32]); 220 | faas_sim_env.faas_alite_read(`SEND_CYC_LOW,0,state,sned_cyc_count[31:0]); 221 | faas_sim_env.faas_alite_read(`REC_CYC_HIGH,0,state,rec_cyc_count[63:32]); 222 | faas_sim_env.faas_alite_read(`REC_CYC_LOW,0,state,rec_cyc_count[31:0]); 223 | $display("size:%d\ntx pkg number:%d\nrx_pkg_num=%d\ntx speed:%f GB/s\nrx speed:%f GB/s",64*(1+(`MODE_1024>>4)),tx_pkg,rx_pkg,64*(1+(`MODE_1024>>4))*tx_pkg/sned_cyc_count/3.3,64*(1+(`MODE_1024>>4))*tx_pkg/rec_cyc_count/3.3); 224 | endtask 225 | //=================================================================================== 226 | //INTERRUPT TEST DEMO 227 | //=================================================================================== 228 | task interrupt_test(); 229 | int state; 230 | faas_sim_env.faas_int_enable(); 231 | faas_sim_env.faas_alite_write(32'h60,32'h2,0,state); 232 | $display("trig interrupt 1"); 233 | endtask 234 | 235 | task interrupt_ack(); 236 | int state; 237 | logic [31:0] FAAS_VERSION; 238 | //event int_ack; 239 | @(faas_sim_env.interrupt_trig[1]); 240 | faas_sim_env.faas_alite_read(32'h0,1,state,FAAS_VERSION); 241 | $display ("FAAS VERSION is %h",FAAS_VERSION); 242 | faas_sim_env.faas_int_flag_clear(1); 243 | #500ns; 244 | faas_sim_env.faas_int_close(); 245 | #10ns; 246 | endtask 247 | 248 | endprogram 249 | -------------------------------------------------------------------------------- /sim/source/aliyun_faas_agent.sv: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////////// 2 | // Company: aliyun 3 | // Engineer: Yuqi 4 | // 5 | // Description: faas simulation platfrom agent layer ,include the interrupt ,alite,xdma 6 | // dma agent layer 7 | // 8 | // Dependencies: 9 | // 10 | // Revision: V1.0 11 | // Revision 0.01 - File Created 12 | // Additional Comments: 13 | // 14 | ////////////////////////////////////////////////////////////////////////////////// 15 | `ifndef FAAS_AGENT 16 | `define FAAS_AGENT 17 | `include "aliyun_faas_alite_agent.sv" 18 | `include "aliyun_faas_dma_agent.sv" 19 | `include "aliyun_faas_xdma_agent.sv" 20 | `include "aliyun_faas_interrupt_agent.sv" 21 | `endif 22 | class aliyun_faas_agent; 23 | //=================================================================================== 24 | //members 25 | //=================================================================================== 26 | //mailbox between agent and driver alite channel 27 | mailbox a2d_alite_write_cmd_req; 28 | mailbox d2a_alite_write_cmd_ack; 29 | mailbox a2d_alite_read_cmd_req; 30 | mailbox d2a_alite_read_cmd_ack; 31 | //mailbox between user and agent alite channel 32 | mailbox u2a_alite_write_cmd_req; 33 | mailbox a2u_alite_write_cmd_ack; 34 | mailbox u2a_alite_read_cmd_req; 35 | mailbox a2u_alite_read_cmd_ack; 36 | //mailbox between interrupt and agent 37 | mailbox i2a_alite_write_cmd_req; 38 | mailbox a2i_alite_write_cmd_ack; 39 | mailbox i2a_alite_read_cmd_req; 40 | mailbox a2i_alite_read_cmd_ack; 41 | //mailbox between agent and driver xdma channel 42 | mailbox a2d_xdma_write_req; 43 | mailbox d2a_xdma_write_ack; 44 | mailbox a2d_xdma_read_req; 45 | mailbox d2a_xdma_read_ack; 46 | //mailbox between user and agent xdma channel 47 | mailbox u2a_xdma_write_req; 48 | mailbox a2u_xdma_write_ack; 49 | mailbox u2a_xdma_read_req; 50 | mailbox a2u_xdma_read_ack; 51 | //mailbox between interrupt and agent xdma channel 52 | mailbox i2a_xdma_write_req; 53 | mailbox a2i_xdma_write_ack; 54 | mailbox i2a_xdma_read_req; 55 | mailbox a2i_xdma_read_ack; 56 | //mailbox between agent and driver dma channel 57 | mailbox d2a_dma_write_req; 58 | mailbox a2d_dma_write_ack; 59 | mailbox d2a_dma_read_req; 60 | mailbox a2d_dma_read_ack; 61 | //mailbox between user and agent dma channel 62 | mailbox u2a_dma_write_req; 63 | mailbox a2u_dma_write_ack; 64 | mailbox u2a_dma_read_req; 65 | mailbox a2u_dma_read_ack; 66 | //mailbox between user and interrupt dma channel 67 | mailbox i2a_dma_write_req; 68 | mailbox a2i_dma_write_ack; 69 | mailbox i2a_dma_read_req; 70 | mailbox a2i_dma_read_ack; 71 | //mailbox between driver and agent interrupt channel 72 | mailbox d2a_int_req; 73 | mailbox a2d_int_ack; 74 | //mailbox between interrupt and agent interrupt channel 75 | mailbox a2i_int_req; 76 | mailbox i2a_int_ack; 77 | //mailbox between user and agent,used to open or close interrupt enable interrupt channel 78 | mailbox u2a_int_req; 79 | //sub agent members 80 | aliyun_faas_alite_agent alite_agent_layer; 81 | aliyun_faas_xdma_agent xdma_agent_layer; 82 | aliyun_faas_dma_agent dma_agent_layer; 83 | aliyun_faas_interrupt_agent int_agnet_alyer; 84 | //=================================================================================== 85 | //constructor 86 | //=================================================================================== 87 | function new(); 88 | alite_agent_layer=new(); 89 | xdma_agent_layer=new(); 90 | dma_agent_layer=new(); 91 | int_agnet_alyer=new(); 92 | endfunction 93 | //=================================================================================== 94 | //build 95 | //=================================================================================== 96 | function build(); 97 | alite_agent_layer.a2d_write_cmd_req=a2d_alite_write_cmd_req; 98 | alite_agent_layer.d2a_write_cmd_ack=d2a_alite_write_cmd_ack; 99 | alite_agent_layer.a2d_read_cmd_req=a2d_alite_read_cmd_req; 100 | alite_agent_layer.d2a_read_cmd_ack=d2a_alite_read_cmd_ack; 101 | alite_agent_layer.u2a_write_cmd_req=u2a_alite_write_cmd_req; 102 | alite_agent_layer.a2u_write_cmd_ack=a2u_alite_write_cmd_ack; 103 | alite_agent_layer.u2a_read_cmd_req=u2a_alite_read_cmd_req; 104 | alite_agent_layer.a2u_read_cmd_ack=a2u_alite_read_cmd_ack; 105 | alite_agent_layer.i2a_write_cmd_req=i2a_alite_write_cmd_req; 106 | alite_agent_layer.a2i_write_cmd_ack=a2i_alite_write_cmd_ack; 107 | alite_agent_layer.i2a_read_cmd_req=i2a_alite_read_cmd_req; 108 | alite_agent_layer.a2i_read_cmd_ack=a2i_alite_read_cmd_ack; 109 | 110 | xdma_agent_layer.a2d_xdma_write_req=a2d_xdma_write_req; 111 | xdma_agent_layer.d2a_xdma_write_ack=d2a_xdma_write_ack; 112 | xdma_agent_layer.a2d_xdma_read_req=a2d_xdma_read_req; 113 | xdma_agent_layer.d2a_xdma_read_ack=d2a_xdma_read_ack; 114 | xdma_agent_layer.u2a_xdma_write_req=u2a_xdma_write_req; 115 | xdma_agent_layer.a2u_xdma_write_ack=a2u_xdma_write_ack; 116 | xdma_agent_layer.u2a_xdma_read_req=u2a_xdma_read_req; 117 | xdma_agent_layer.a2u_xdma_read_ack=a2u_xdma_read_ack; 118 | xdma_agent_layer.i2a_xdma_write_req=i2a_xdma_write_req; 119 | xdma_agent_layer.a2i_xdma_write_ack=a2i_xdma_write_ack; 120 | xdma_agent_layer.i2a_xdma_read_req=i2a_xdma_read_req; 121 | xdma_agent_layer.a2i_xdma_read_ack=a2i_xdma_read_ack; 122 | 123 | dma_agent_layer.d2a_dma_write_req=d2a_dma_write_req; 124 | dma_agent_layer.a2d_dma_write_ack=a2d_dma_write_ack; 125 | dma_agent_layer.d2a_dma_read_req=d2a_dma_read_req; 126 | dma_agent_layer.a2d_dma_read_ack=a2d_dma_read_ack; 127 | dma_agent_layer.u2a_dma_write_req=u2a_dma_write_req; 128 | dma_agent_layer.a2u_dma_write_ack=a2u_dma_write_ack; 129 | dma_agent_layer.u2a_dma_read_req=u2a_dma_read_req; 130 | dma_agent_layer.a2u_dma_read_ack=a2u_dma_read_ack; 131 | dma_agent_layer.i2a_dma_write_req=i2a_dma_write_req; 132 | dma_agent_layer.a2i_dma_write_ack=a2i_dma_write_ack; 133 | dma_agent_layer.i2a_dma_read_req=i2a_dma_read_req; 134 | dma_agent_layer.a2i_dma_read_ack=a2i_dma_read_ack; 135 | 136 | int_agnet_alyer.d2a_int_req=d2a_int_req; 137 | int_agnet_alyer.a2d_int_ack=a2d_int_ack; 138 | int_agnet_alyer.a2i_int_req=a2i_int_req; 139 | int_agnet_alyer.i2a_int_ack=i2a_int_ack; 140 | int_agnet_alyer.u2a_int_req=u2a_int_req; 141 | 142 | alite_agent_layer.build(); 143 | xdma_agent_layer.build(); 144 | dma_agent_layer.build(); 145 | int_agnet_alyer.build(); 146 | endfunction 147 | //=================================================================================== 148 | //run phase 149 | //=================================================================================== 150 | task run(); 151 | fork 152 | alite_agent_layer.run(); 153 | xdma_agent_layer.run(); 154 | dma_agent_layer.run(); 155 | int_agnet_alyer.run(); 156 | join_none 157 | endtask 158 | endclass 159 | -------------------------------------------------------------------------------- /sim/source/aliyun_faas_alite_agent.sv: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////////// 2 | // Company: aliyun 3 | // Engineer: Yuqi 4 | // 5 | // Description: faas simulation platfrom alite agent layer 6 | // 7 | // Dependencies: 8 | // 9 | // Revision: V1.0 10 | // Revision 0.01 - File Created 11 | // Additional Comments: 12 | // 13 | ////////////////////////////////////////////////////////////////////////////////// 14 | class aliyun_faas_alite_agent; 15 | //=================================================================================== 16 | //members 17 | //=================================================================================== 18 | //mailbox between agent and driver 19 | mailbox a2d_write_cmd_req; 20 | mailbox d2a_write_cmd_ack; 21 | mailbox a2d_read_cmd_req; 22 | mailbox d2a_read_cmd_ack; 23 | //mailbox between user and agent 24 | mailbox u2a_write_cmd_req; 25 | mailbox a2u_write_cmd_ack; 26 | mailbox u2a_read_cmd_req; 27 | mailbox a2u_read_cmd_ack; 28 | //mailbox between interrupt and agent 29 | mailbox i2a_write_cmd_req; 30 | mailbox a2i_write_cmd_ack; 31 | mailbox i2a_read_cmd_req; 32 | mailbox a2i_read_cmd_ack; 33 | //=================================================================================== 34 | //constructor 35 | //=================================================================================== 36 | function new(); 37 | 38 | endfunction 39 | //=================================================================================== 40 | //build 41 | //=================================================================================== 42 | function build(); 43 | 44 | endfunction 45 | //=================================================================================== 46 | //run phase 47 | //=================================================================================== 48 | task run(); 49 | fork 50 | alite_write_cmd_req_process(); 51 | alite_write_cmd_ack_process(); 52 | alite_read_cmd_req_process(); 53 | alite_read_cmd_ack_process(); 54 | join_none 55 | endtask 56 | //=================================================================================== 57 | //write_cmd__req_process 58 | //=================================================================================== 59 | task alite_write_cmd_req_process(); 60 | alite_write_package alite_wcache; 61 | while(`TRUE) 62 | begin 63 | if(u2a_write_cmd_req.num()) //detect the request from the user 64 | begin 65 | u2a_write_cmd_req.get(alite_wcache); 66 | a2d_write_cmd_req.put(alite_wcache); 67 | end 68 | if(i2a_write_cmd_req.num()) //detect the request from the interrupt 69 | begin 70 | i2a_write_cmd_req.get(alite_wcache); 71 | a2d_write_cmd_req.put(alite_wcache); 72 | end 73 | #1; 74 | end 75 | endtask 76 | //=================================================================================== 77 | //write_cmd_ack_process 78 | //=================================================================================== 79 | task alite_write_cmd_ack_process(); 80 | alite_write_package alite_wcache; 81 | while(`TRUE) 82 | begin 83 | d2a_write_cmd_ack.get(alite_wcache); 84 | if(alite_wcache.write_flag==0) //if the package is to user 85 | a2u_write_cmd_ack.put(alite_wcache); 86 | else //if the packeage is to interrupt 87 | a2i_write_cmd_ack.put(alite_wcache); 88 | end 89 | endtask 90 | //=================================================================================== 91 | //read_cmd_req_process 92 | //=================================================================================== 93 | task alite_read_cmd_req_process(); 94 | alite_read_package alite_rcache; 95 | while(`TRUE) 96 | begin 97 | if(u2a_read_cmd_req.num()) //detect the request from the user 98 | begin 99 | u2a_read_cmd_req.get(alite_rcache); 100 | a2d_read_cmd_req.put(alite_rcache); 101 | end 102 | if(i2a_read_cmd_req.num()) //detect the request from the interrupt 103 | begin 104 | i2a_read_cmd_req.get(alite_rcache); 105 | a2d_read_cmd_req.put(alite_rcache); 106 | end 107 | #1; 108 | end 109 | endtask 110 | //=================================================================================== 111 | //read_cmd_ack_process 112 | //=================================================================================== 113 | task alite_read_cmd_ack_process(); 114 | alite_read_package alite_rcache; 115 | while(`TRUE) 116 | begin 117 | d2a_read_cmd_ack.get(alite_rcache); 118 | if(alite_rcache.read_flag==0) //return the result to the user 119 | a2u_read_cmd_ack.put(alite_rcache); 120 | if(alite_rcache.read_flag==1) //return the result to the interrupt 121 | a2i_read_cmd_ack.put(alite_rcache); 122 | end 123 | endtask 124 | 125 | endclass 126 | 127 | -------------------------------------------------------------------------------- /sim/source/aliyun_faas_alite_driver.sv: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////////// 2 | // Company: aliyun 3 | // Engineer: Yuqi 4 | // 5 | // Description: faas simulation platfrom alite bus driver,used to read and write the axi-lite bus. 6 | // 7 | // Dependencies: 8 | // 9 | // Revision: V1.0 10 | // Revision 0.01 - File Created 11 | // Additional Comments: 12 | // 13 | ////////////////////////////////////////////////////////////////////////////////// 14 | class aliyun_faas_alite_driver; 15 | //=================================================================================== 16 | //members 17 | //=================================================================================== 18 | mailbox write_cmd_req; 19 | mailbox write_cmd_ack; 20 | mailbox read_cmd_req; 21 | mailbox read_cmd_ack; 22 | virtual axi_lite#(.AWADDR_WIDTH(`ALITE_AWADDR_WIDTH), 23 | .AWPORT_WIDTH(`ALITE_AWPORT_WIDTH), 24 | .WDATA_WIDTH(`ALITE_WDATA_WIDTH), 25 | .WSTRB_WIDTH(`ALITE_WSTRB_WIDTH), 26 | .BRESP_WIDTH(`ALITE_BRESP_WIDTH), 27 | .ARADDR_WIDTH(`ALITE_ARADDR_WIDTH), 28 | .ARPORT_WIDTH(`ALITE_ARPORT_WIDTH), 29 | .RDATA_WIDTH(`ALITE_RDATA_WIDTH), 30 | .RRESP_WIDTH(`ALITE_RRESP_WIDTH)).tb alite_driver; 31 | //methods 32 | //=================================================================================== 33 | //alite_write address operation 34 | //=================================================================================== 35 | task alite_write_addr(input logic [`ALITE_AWADDR_WIDTH-1:0] write_addr); 36 | @(posedge alite_driver.axi_lite_clk) 37 | begin 38 | alite_driver.axi_lite_awvalid<=1'b1; 39 | alite_driver.axi_lite_awaddr<=write_addr; 40 | end 41 | fork 42 | begin 43 | while(~alite_driver.axi_lite_awready) 44 | begin 45 | @(posedge alite_driver.axi_lite_clk); 46 | end 47 | end 48 | begin 49 | if(`AXI_LITE_CHECK_ENABLE) 50 | repeat(`ALITE_AWADDR_TIMEOUT) 51 | begin 52 | @(posedge alite_driver.axi_lite_clk); 53 | end 54 | else 55 | while(`TRUE); 56 | end 57 | join_any 58 | if(~alite_driver.axi_lite_awready) 59 | begin 60 | $display("CRITICAL ERROR: The disign might have an error in alite write address channel"); 61 | $stop; 62 | end 63 | else begin 64 | @(posedge alite_driver.axi_lite_clk) 65 | begin 66 | alite_driver.axi_lite_awvalid<=1'b0; 67 | alite_driver.axi_lite_awaddr<='d0; 68 | end 69 | end 70 | endtask 71 | //=================================================================================== 72 | //alite_write data operation 73 | //=================================================================================== 74 | task alite_write_data(input logic [`ALITE_WDATA_WIDTH-1:0] write_data); 75 | //@(posedge alite_driver.axi_lite_clk) 76 | begin 77 | alite_driver.axi_lite_wvalid<=1'b1; 78 | alite_driver.axi_lite_wstrb<={`ALITE_WSTRB_WIDTH{1'b1}}; 79 | alite_driver.axi_lite_wdata<=write_data; 80 | end 81 | fork 82 | begin 83 | while(~alite_driver.axi_lite_wready) 84 | begin 85 | @(posedge alite_driver.axi_lite_clk); 86 | end 87 | end 88 | begin 89 | if(`AXI_LITE_CHECK_ENABLE) 90 | repeat(`ALITE_WDATA_TIMEOUT) 91 | begin 92 | @(posedge alite_driver.axi_lite_clk); 93 | end 94 | else 95 | while(`TRUE); 96 | end 97 | join_any 98 | if(~alite_driver.axi_lite_wready) 99 | begin 100 | $display("CRITICAL ERROR:The disign might have an error in alite write data channel"); 101 | $stop; 102 | end 103 | else begin 104 | @(posedge alite_driver.axi_lite_clk) 105 | begin 106 | alite_driver.axi_lite_wvalid<=1'b0; 107 | alite_driver.axi_lite_wstrb<={`ALITE_WSTRB_WIDTH{1'b0}}; 108 | alite_driver.axi_lite_wdata<='d0; 109 | end 110 | end 111 | endtask 112 | //=================================================================================== 113 | //alite_write bresp operation 114 | //=================================================================================== 115 | task alite_write_bresp(output logic[`ALITE_BRESP_WIDTH-1:0] write_resp); 116 | //@(posedge alite_driver.axi_lite_clk) 117 | begin 118 | alite_driver.axi_lite_bready<=1'b1; 119 | end 120 | fork 121 | begin 122 | while(~alite_driver.axi_lite_bvalid) 123 | begin 124 | @(posedge alite_driver.axi_lite_clk); 125 | end 126 | end 127 | begin 128 | if(`AXI_LITE_CHECK_ENABLE) 129 | repeat(`ALITE_BRESP_TIMEOUT) 130 | begin 131 | @(posedge alite_driver.axi_lite_clk); 132 | end 133 | else 134 | while(`TRUE); 135 | end 136 | join_any 137 | if(~alite_driver.axi_lite_bvalid) 138 | begin 139 | $display("CRITICAL ERROR:The disign might have an error in alite write bresp channel"); 140 | $stop; 141 | end 142 | else 143 | begin 144 | @(posedge alite_driver.axi_lite_clk) 145 | begin 146 | alite_driver.axi_lite_bready<=1'b0; 147 | write_resp=alite_driver.axi_lite_bresp; 148 | end 149 | end 150 | endtask 151 | //=================================================================================== 152 | //alite_write method 153 | //=================================================================================== 154 | task alite_write_operation(); 155 | alite_write_package write_data_cache; 156 | while(1) 157 | begin 158 | write_cmd_req.get(write_data_cache); //get write cmd from the agent 159 | alite_write_addr(write_data_cache.write_addr); //write address operation 160 | alite_write_data(write_data_cache.write_data); //write data operation 161 | alite_write_bresp(write_data_cache.write_state); //write bresp operation 162 | write_cmd_ack.put(write_data_cache); //retrun the result to the agent 163 | end 164 | endtask 165 | //=================================================================================== 166 | //alite_read address operation 167 | //=================================================================================== 168 | task alite_read_addr_opertaion(input [`ALITE_ARADDR_WIDTH-1:0] read_addr); 169 | @(posedge alite_driver.axi_lite_clk) 170 | begin 171 | alite_driver.axi_lite_arvalid<=1'b1; 172 | alite_driver.axi_lite_araddr<=read_addr; 173 | end 174 | fork 175 | begin 176 | while(~alite_driver.axi_lite_arready) 177 | begin 178 | @(posedge alite_driver.axi_lite_clk); 179 | end 180 | end 181 | begin 182 | if(`AXI_LITE_CHECK_ENABLE) 183 | repeat(`ALITE_ARADDR_TIMEOUT) 184 | begin 185 | @(posedge alite_driver.axi_lite_clk); 186 | end 187 | else 188 | while(`TRUE); 189 | end 190 | join_any 191 | if(~alite_driver.axi_lite_arready) 192 | begin 193 | $display("CRITICAL ERROR:The disign might have an error in alite read address channel"); 194 | $stop; 195 | end 196 | else begin 197 | @(posedge alite_driver.axi_lite_clk) 198 | begin 199 | alite_driver.axi_lite_arvalid<=1'b0; 200 | alite_driver.axi_lite_araddr<='d0; 201 | end 202 | end 203 | endtask 204 | //=================================================================================== 205 | //alite_read data and state operation 206 | //=================================================================================== 207 | task alite_read_data_operation(output [`ALITE_RDATA_WIDTH-1:0] read_data,output [`ALITE_RRESP_WIDTH-1:0] read_state); 208 | //@(posedge alite_driver.axi_lite_clk) 209 | begin 210 | alite_driver.axi_lite_rready<=1'b1; 211 | end 212 | fork 213 | begin 214 | while(~alite_driver.axi_lite_rvalid) 215 | begin 216 | @(posedge alite_driver.axi_lite_clk); 217 | end 218 | end 219 | begin 220 | if(`AXI_LITE_CHECK_ENABLE) 221 | repeat(`ALITE_RDATA_TIMEOUT) 222 | begin 223 | @(posedge alite_driver.axi_lite_clk); 224 | end 225 | else 226 | while(`TRUE); 227 | end 228 | join_any 229 | if(~alite_driver.axi_lite_rvalid) 230 | begin 231 | $display("CRITICAL ERROR:The disign might have an error in alite read data channel"); 232 | $stop; 233 | end 234 | else 235 | begin 236 | @(posedge alite_driver.axi_lite_clk) 237 | begin 238 | read_data=alite_driver.axi_lite_rdata; 239 | read_state=alite_driver.axi_lite_rresp; 240 | alite_driver.axi_lite_rready<=1'b0; 241 | end 242 | end 243 | endtask 244 | //=================================================================================== 245 | //alite_read method 246 | //=================================================================================== 247 | task alite_read_operation(); 248 | alite_read_package read_cache; 249 | while(1) 250 | begin 251 | read_cmd_req.get(read_cache); //get the read command from the agent 252 | alite_read_addr_opertaion(read_cache.read_addr); //read address operation 253 | alite_read_data_operation(read_cache.read_data,read_cache.read_state); //read data and state opeation 254 | read_cmd_ack.put(read_cache); //return the result to the agent 255 | end 256 | endtask 257 | //=================================================================================== 258 | //constructor 259 | //=================================================================================== 260 | function new( virtual axi_lite#(.AWADDR_WIDTH(`ALITE_AWADDR_WIDTH), 261 | .AWPORT_WIDTH(`ALITE_AWPORT_WIDTH), 262 | .WDATA_WIDTH(`ALITE_WDATA_WIDTH), 263 | .WSTRB_WIDTH(`ALITE_WSTRB_WIDTH), 264 | .BRESP_WIDTH(`ALITE_BRESP_WIDTH), 265 | .ARADDR_WIDTH(`ALITE_ARADDR_WIDTH), 266 | .ARPORT_WIDTH(`ALITE_ARPORT_WIDTH), 267 | .RDATA_WIDTH(`ALITE_RDATA_WIDTH), 268 | .RRESP_WIDTH(`ALITE_RRESP_WIDTH)).tb alite_driver); 269 | this.alite_driver=alite_driver; 270 | endfunction 271 | //=================================================================================== 272 | //build phase 273 | //global reset the axi-lite bus 274 | //=================================================================================== 275 | task build(); 276 | alite_driver.axi_lite_awvalid <='d0; 277 | alite_driver.axi_lite_awaddr <='d0; 278 | alite_driver.axi_lite_awport <='d0; 279 | alite_driver.axi_lite_wvalid <='d0; 280 | alite_driver.axi_lite_wdata <='d0; 281 | alite_driver.axi_lite_wstrb <='d0; 282 | alite_driver.axi_lite_bready <='d0; 283 | alite_driver.axi_lite_arvalid <='d0; 284 | alite_driver.axi_lite_araddr <='d0; 285 | alite_driver.axi_lite_arport <='d0; 286 | alite_driver.axi_lite_rready <='d0; 287 | alite_driver.axi_lite_reset(`ALITE_RESET_CYCLE); 288 | endtask 289 | //=================================================================================== 290 | //run phase 291 | //=================================================================================== 292 | task run(); 293 | fork 294 | alite_read_operation(); 295 | alite_write_operation(); 296 | join_none 297 | endtask 298 | 299 | endclass 300 | -------------------------------------------------------------------------------- /sim/source/aliyun_faas_base_pkg.sv: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////////// 2 | // Company: aliyun 3 | // Engineer: Yuqi 4 | // 5 | // Description: faas simulation platfrom base package,include base config and some data struct 6 | // 7 | // Dependencies: 8 | // 9 | // Revision: V1.0 10 | // Revision 0.01 - File Created 11 | // Additional Comments: 12 | // 13 | ////////////////////////////////////////////////////////////////////////////////// 14 | `define TRUE 1 15 | `define FALSE 0 16 | //=================================================================================== 17 | //axi_lite bus config 18 | //=================================================================================== 19 | `ifndef ALITE_BASE_PKG 20 | `define ALITE_BASE_PKG 21 | `define ALITE_AWADDR_WIDTH 32 22 | `define ALITE_AWPORT_WIDTH 3 23 | `define ALITE_WDATA_WIDTH 32 24 | `define ALITE_WSTRB_WIDTH 4 25 | `define ALITE_BRESP_WIDTH 2 26 | `define ALITE_ARADDR_WIDTH 32 27 | `define ALITE_ARPORT_WIDTH 3 28 | `define ALITE_RDATA_WIDTH 32 29 | `define ALITE_RRESP_WIDTH 2 30 | `define AXI_LITE_CHECK_ENABLE `TRUE 31 | `define ALITE_AWADDR_TIMEOUT 10000 //unit:cycle; 32 | `define ALITE_WDATA_TIMEOUT 10000 //unit:cycle; 33 | `define ALITE_BRESP_TIMEOUT 10000 //unit:cycle; 34 | `define ALITE_ARADDR_TIMEOUT 10000 //unit:cycle; 35 | `define ALITE_RDATA_TIMEOUT 10000 //unit:cycle; 36 | `define ALITE_RESET_CYCLE 1 //unit::cycle 37 | //=================================================================================== 38 | //axi_lite data class 39 | //=================================================================================== 40 | class alite_write_package; 41 | logic [`ALITE_AWADDR_WIDTH-1:0] write_addr; 42 | logic [`ALITE_WDATA_WIDTH-1:0] write_data; 43 | logic [`ALITE_BRESP_WIDTH-1:0] write_state; 44 | logic write_flag; //0:user channel,1:interrupt channel 45 | function new(input [`ALITE_AWADDR_WIDTH-1:0] waddr, 46 | input [`ALITE_WDATA_WIDTH-1:0] wdata, 47 | input flag 48 | ); 49 | this.write_addr=waddr; 50 | this.write_data=wdata; 51 | this.write_flag=flag; 52 | endfunction 53 | endclass 54 | 55 | class alite_read_package; 56 | logic [`ALITE_ARADDR_WIDTH-1:0] read_addr; 57 | logic [`ALITE_RDATA_WIDTH-1:0] read_data; 58 | logic [`ALITE_RRESP_WIDTH-1:0] read_state; 59 | logic read_flag; //0:user channel,1:interrupt channel 60 | function new(input [`ALITE_ARADDR_WIDTH-1:0] raddr, 61 | input flag 62 | ); 63 | this.read_addr=raddr; 64 | this.read_flag=flag; 65 | endfunction 66 | endclass 67 | `endif 68 | //=================================================================================== 69 | //xdma base package 70 | //=================================================================================== 71 | `ifndef XDMA_BASE_PKG 72 | `define XDMA_BASE_PKG 73 | 74 | `define XDMA_ARADDR_WIDTH 64 75 | `define XDMA_ARBURST_WIDTH 2 76 | `define XDMA_ARCACHE_WIDTH 4 77 | `define XDMA_ARLOCK_WIDTH 1 78 | `define XDMA_ARPORT_WIDTH 3 79 | `define XDMA_ARQOS_WIDTH 4 80 | `define XDMA_ARREGION_WIDTH 4 81 | `define XDMA_ARID_WIDTH 4 82 | `define XDMA_ARLEN_WIDTH 8 83 | `define XDMA_ARSIZE_WIDTH 3 84 | `define XDMA_AWADDR_WIDTH 64 85 | `define XDMA_AWBURST_WIDTH 2 86 | `define XDMA_AWCACHE_WIDTH 4 87 | `define XDMA_AWLOCK_WIDTH 1 88 | `define XDMA_AWPORT_WIDTH 3 89 | `define XDMA_AWQOS_WIDTH 4 90 | `define XDMA_AWREGION_WIDTH 4 91 | `define XDMA_AWID_WIDTH 4 92 | `define XDMA_AWLEN_WIDTH 8 93 | `define XDMA_AWSIZE_WIDTH 3 94 | `define XDMA_BID_WIDTH 4 95 | `define XDMA_BRESP_WIDTH 2 96 | `define XDMA_RDATA_WIDTH 512 97 | `define XDMA_RID_WIDTH 4 98 | `define XDMA_RRESP_WIDTH 2 99 | `define XDMA_WDATA_WIDTH 512 100 | `define XDMA_WSTRB_WIDTH 64 101 | 102 | `define XDMA_AWSIZE 'b110 103 | `define XDMA_AWBURST 'b01 104 | `define XDMA_AWLEN_MAX 4096/(2**`XDMA_AWSIZE)-1 105 | `define XDMA_ARSIZE 'b110 106 | `define XDMA_ARBURST 'b01 107 | `define XDMA_ARLEN_MAX 4096/(2**`XDMA_ARSIZE)-1 108 | 109 | 110 | `define XDMA_CHECK_ENABLE `TRUE 111 | `define XDMA_AWADDR_TIMEOUT 10000 //unit:cycle 112 | `define XDMA_WDATA_TIMEOUT 10000 //unit:cycle 113 | `define XDMA_BRESP_TIMEOUT 10000 //unit:cycle 114 | `define XDMA_ARADDR_TIMEOUT 10000 //unit:cycle 115 | `define XDMA_RESET_CYCLE 1 //unit:cycle 116 | class xdma_write_pkg; 117 | logic [`XDMA_AWADDR_WIDTH-1:0] awaddr; 118 | byte unsigned wdata[$]; 119 | logic [`XDMA_BRESP_WIDTH-1:0] write_state; 120 | logic [`XDMA_AWLEN_WIDTH-1:0] awlen; 121 | logic [(2**`XDMA_AWSIZE*8)-1:0] wdata_align[$]; 122 | logic [`XDMA_AWLEN_WIDTH-1:0] last_pkg_size; 123 | logic write_flag; //0:user channel,1:interrupt channel 124 | 125 | 126 | //constructor 127 | function new(input logic [`XDMA_AWADDR_WIDTH-1:0] awaddr, 128 | input byte unsigned wdata[$], 129 | input flag 130 | ); 131 | this.awaddr=awaddr; 132 | this.wdata=wdata; 133 | this.write_flag=flag; 134 | endfunction 135 | //align the data 136 | function data_pack(); 137 | if(wdata.size()%(2**`XDMA_AWSIZE)) 138 | begin 139 | this.awlen=wdata.size()/(2**`XDMA_AWSIZE)+1; 140 | this.last_pkg_size=wdata.size()%(2**`XDMA_AWSIZE); 141 | for(int i=0;i<(2**`XDMA_AWSIZE-this.last_pkg_size);i=i+1) 142 | begin 143 | this.wdata.push_back(0); 144 | end 145 | end 146 | else 147 | begin 148 | this.awlen=wdata.size()/(2**`XDMA_AWSIZE); 149 | this.last_pkg_size=2**`XDMA_AWSIZE; 150 | end 151 | for(int i=0;i>(8*i); 210 | this.index++; 211 | end 212 | endfunction 213 | endclass 214 | `endif 215 | //=================================================================================== 216 | //dma base package 217 | //=================================================================================== 218 | `ifndef DMA_BASE_PKG 219 | `define DMA_BASE_PKG 220 | 221 | `define DMA_ARADDR_WIDTH 64 222 | `define DMA_ARBURST_WIDTH 2 223 | `define DMA_ARID_WIDTH 5 224 | `define DMA_ARLEN_WIDTH 8 225 | `define DMA_ARSIZE_WIDTH 3 226 | `define DMA_AWADDR_WIDTH 64 227 | `define DMA_AWBURST_WIDTH 2 228 | `define DMA_AWID_WIDTH 5 229 | `define DMA_AWLEN_WIDTH 8 230 | `define DMA_AWSIZE_WIDTH 3 231 | `define DMA_BID_WIDTH 5 232 | `define DMA_BRESP_WIDTH 2 233 | `define DMA_RDATA_WIDTH 512 234 | `define DMA_RID_WIDTH 5 235 | `define DMA_RRESP_WIDTH 2 236 | `define DMA_WDATA_WIDTH 512 237 | `define DMA_WSTRB_WIDTH 64 238 | 239 | `define DMA_RESET_CYCLE 1 240 | //dma data package,used to transfer data between agent and application layer 241 | class dma_data_pkg; 242 | byte unsigned wdata[]; 243 | logic [`DMA_AWADDR_WIDTH-1:0] base_addr; 244 | int length; 245 | logic state; //0:failed,1:succeed 246 | function new(); 247 | 248 | endfunction 249 | //addr check 250 | function addr_check(); 251 | if((wdata.size()+base_addr)>=(2**(`DMA_AWADDR_WIDTH))) 252 | begin 253 | $display("CRITICAL ERROR: the dma operation address is invalid"); 254 | $stop; 255 | end 256 | endfunction 257 | endclass 258 | //dma write data pkg 259 | class dma_write_pkg; 260 | logic [`DMA_AWADDR_WIDTH-1:0] awaddr; 261 | byte unsigned wdata[]; 262 | logic [12:0] payload_size; 263 | logic [12:0] index; 264 | byte unsigned byte_nums_per_cycle; 265 | logic [`DMA_BRESP_WIDTH-1:0] write_state; 266 | 267 | function new(input logic [`DMA_AWADDR_WIDTH-1:0] awaddr, 268 | input logic [`DMA_AWSIZE_WIDTH-1:0] awsize, 269 | input logic [`DMA_AWLEN_WIDTH-1:0 ] awlen 270 | ); 271 | 272 | this.awaddr=awaddr; 273 | this.wdata=new[2**(awsize)*(awlen+1)]; 274 | this.payload_size=2**(awsize)*(awlen+1); 275 | this.index=0; 276 | this.byte_nums_per_cycle=2**(awsize); 277 | endfunction 278 | //data process from the dma wdata channel 279 | function logic data_process(input logic [`DMA_WDATA_WIDTH-1:0] data, 280 | input logic [`DMA_WSTRB_WIDTH-1:0] wstrb); 281 | if(this.index+byte_nums_per_cycle>this.payload_size) //check the nums of the data transfer 282 | begin 283 | $display("payload_size=%d\tindex=%d\tbyte_nums_per_cycle=%d",payload_size,index,byte_nums_per_cycle); 284 | return `FALSE; 285 | end 286 | else 287 | begin 288 | for(byte unsigned i=0;i0) 114 | begin 115 | begin 116 | xdma_driver.axi4_wdata<=wdata.pop_front(); 117 | xdma_driver.axi4_wvalid<='b1; 118 | if(length==1) 119 | begin 120 | xdma_driver.axi4_wstrb<=(2**last_pkg_size-1); 121 | xdma_driver.axi4_wlast<=1'b1; 122 | end 123 | else 124 | begin 125 | xdma_driver.axi4_wstrb<=({2**`XDMA_AWSIZE{1'b1}}); 126 | xdma_driver.axi4_wlast<=1'b0; 127 | end 128 | end 129 | 130 | @(posedge xdma_driver.axi4_clk); 131 | fork 132 | begin //check the wready state 133 | while(~xdma_driver.axi4_wready) 134 | @(posedge xdma_driver.axi4_clk); 135 | end 136 | // begin //time out check 137 | // if(`XDMA_CHECK_ENABLE) 138 | // begin 139 | // repeat (`XDMA_WDATA_TIMEOUT) 140 | // begin 141 | // @(posedge xdma_driver.axi4_clk); 142 | // end 143 | // end 144 | // else 145 | // while(`TRUE); 146 | // end 147 | join_any 148 | if(~xdma_driver.axi4_wready) 149 | begin 150 | $display("CRITICAL ERROR:The design might have an error in xdma wdata channel"); 151 | $stop; 152 | end 153 | else 154 | length=length-1'b1; 155 | end 156 | xdma_driver.axi4_wdata<='d0; 157 | xdma_driver.axi4_wvalid<='b0; 158 | xdma_driver.axi4_wstrb<='d0; 159 | xdma_driver.axi4_wlast<='b0; 160 | endtask 161 | //=================================================================================== 162 | //xdma bresp channel operation 163 | //=================================================================================== 164 | task xdma_bresp_op(output [`XDMA_BRESP_WIDTH-1:0] write_state); 165 | begin 166 | xdma_driver.axi4_bready<=1'b1; 167 | end 168 | //@(posedge xdma_driver.axi4_clk); 169 | fork 170 | begin //check the bvalid state 171 | while(~xdma_driver.axi4_bvalid) 172 | @(posedge xdma_driver.axi4_clk); 173 | end 174 | begin 175 | if(`XDMA_CHECK_ENABLE) 176 | begin 177 | repeat (`XDMA_BRESP_TIMEOUT) 178 | begin 179 | @(posedge xdma_driver.axi4_clk); 180 | end 181 | end 182 | else 183 | while(`TRUE); 184 | end 185 | join_any 186 | if(~xdma_driver.axi4_bvalid) 187 | begin 188 | $display("CRITICAL ERROR:The design might have an error in xdma bresp channel"); 189 | $stop; 190 | end 191 | else 192 | begin 193 | @(posedge xdma_driver.axi4_clk); 194 | xdma_driver.axi4_bready<=1'b0; 195 | write_state=xdma_driver.axi4_bresp; 196 | end 197 | endtask 198 | //=================================================================================== 199 | //xdma write channel operation 200 | //=================================================================================== 201 | task xdma_write_op(); 202 | xdma_write_pkg xdma_write_cache; 203 | while(`TRUE) 204 | begin 205 | xdma_write_req.get(xdma_write_cache); //get write request from the agent 206 | xdma_write_cache.data_pack(); //align the data 207 | xdma_awaddr_op(xdma_write_cache.awaddr,xdma_write_cache.awlen); 208 | xdma_wdata_op(xdma_write_cache.wdata_align,xdma_write_cache.awlen,xdma_write_cache.last_pkg_size); 209 | xdma_bresp_op(xdma_write_cache.write_state); 210 | xdma_write_ack.put(xdma_write_cache); 211 | end 212 | endtask 213 | //=================================================================================== 214 | //xdma raddr channel operation 215 | //=================================================================================== 216 | task xdma_raddr_op(xdma_read_araddr_pkg araddr_cmd); 217 | @(posedge xdma_driver.axi4_clk) 218 | begin 219 | xdma_driver.axi4_arbusrt<=`XDMA_ARBURST; 220 | xdma_driver.axi4_araddr<=araddr_cmd.araddr; 221 | xdma_driver.axi4_arid<=araddr_cmd.arid; 222 | xdma_driver.axi4_arlen<=araddr_cmd.arlen_cal(); 223 | xdma_driver.axi4_arsize<=`XDMA_ARSIZE; 224 | xdma_driver.axi4_arvalid<=1'b1; 225 | end 226 | fork 227 | begin //wait for the arready high 228 | while(~xdma_driver.axi4_arready) 229 | @(posedge xdma_driver.axi4_clk); 230 | end 231 | begin 232 | if(`XDMA_CHECK_ENABLE) 233 | begin 234 | repeat (`XDMA_ARADDR_TIMEOUT) 235 | begin 236 | @(posedge xdma_driver.axi4_clk); 237 | end 238 | end 239 | else 240 | while(`TRUE); 241 | end 242 | join_any 243 | if(~xdma_driver.axi4_arready) 244 | begin 245 | $display("CRITICAL ERROR:The design might have an error in xdma araddr channel"); 246 | $stop; 247 | end 248 | else 249 | begin 250 | @(posedge xdma_driver.axi4_clk); 251 | xdma_driver.axi4_arbusrt<=`XDMA_ARBURST; 252 | xdma_driver.axi4_araddr<=araddr_cmd.araddr; 253 | xdma_driver.axi4_arid<=araddr_cmd.arid; 254 | xdma_driver.axi4_arlen<='d0; 255 | xdma_driver.axi4_arsize<=`XDMA_ARSIZE; 256 | xdma_driver.axi4_arvalid<=1'b0; 257 | end 258 | endtask 259 | //=================================================================================== 260 | //xdma rdata channel operation 261 | //=================================================================================== 262 | task xdma_rdata_op(); 263 | while(`TRUE) 264 | begin 265 | @(posedge xdma_driver.axi4_clk) 266 | begin 267 | if(xdma_driver.axi4_rvalid) 268 | begin 269 | if(xdma_rdata[xdma_driver.axi4_rid]==null) 270 | begin 271 | $display ("There are no read request for the rid=%d in xdma channel",xdma_driver.axi4_rid); 272 | $stop(); 273 | end 274 | xdma_rdata[xdma_driver.axi4_rid].rdata_process(xdma_driver.axi4_rdata); 275 | if(xdma_driver.axi4_rlast) //return the data recived to agent 276 | begin 277 | xdma_rdata[xdma_driver.axi4_rid].state=xdma_driver.axi4_rresp; 278 | xdma_read_ack.put(xdma_rdata[xdma_driver.axi4_rid]); 279 | xdma_rdata[xdma_driver.axi4_rid]=null; //clear the data object to recive the new data package 280 | end 281 | end 282 | end 283 | end 284 | endtask 285 | //=================================================================================== 286 | //xdma readchannel operation 287 | //=================================================================================== 288 | task xdam_read_op(); 289 | fork 290 | begin//read_raddr_opeation 291 | xdma_read_araddr_pkg read_request; 292 | while(`TRUE) 293 | begin 294 | xdma_read_req.get(read_request); 295 | xdma_rdata[read_request.arid]=new(read_request.araddr,read_request.arid,read_request.length,read_request.read_flag); 296 | xdma_raddr_op(read_request); 297 | end 298 | end 299 | begin 300 | xdma_rdata_op(); 301 | end 302 | join_none 303 | endtask 304 | //=================================================================================== 305 | //constructor 306 | //=================================================================================== 307 | function new(virtual axi4#( 308 | .ARADDR_WIDTH(`XDMA_ARADDR_WIDTH), 309 | .ARBURST_WIDTH(`XDMA_ARBURST_WIDTH), 310 | .ARCACHE_WIDTH(`XDMA_ARCACHE_WIDTH), 311 | .ARLOCK_WIDTH(`XDMA_ARLOCK_WIDTH), 312 | .ARPORT_WIDTH(`XDMA_ARPORT_WIDTH), 313 | .ARQOS_WIDTH(`XDMA_ARQOS_WIDTH), 314 | .ARREGION_WIDTH(`XDMA_ARREGION_WIDTH), 315 | .ARID_WIDTH(`XDMA_ARID_WIDTH), 316 | .ARLEN_WIDTH(`XDMA_ARLEN_WIDTH), 317 | .ARSIZE_WIDTH(`XDMA_ARSIZE_WIDTH), 318 | .AWADDR_WIDTH(`XDMA_AWADDR_WIDTH), 319 | .AWBURST_WIDTH(`XDMA_AWBURST_WIDTH), 320 | .AWCACHE_WIDTH(`XDMA_AWCACHE_WIDTH), 321 | .AWLOCK_WIDTH(`XDMA_AWLOCK_WIDTH), 322 | .AWPORT_WIDTH(`XDMA_AWPORT_WIDTH), 323 | .AWQOS_WIDTH(`XDMA_AWQOS_WIDTH), 324 | .AWREGION_WIDTH(`XDMA_AWREGION_WIDTH), 325 | .AWID_WIDTH(`XDMA_AWID_WIDTH), 326 | .AWLEN_WIDTH(`XDMA_AWLEN_WIDTH), 327 | .AWSIZE_WIDTH(`XDMA_AWSIZE_WIDTH), 328 | .BID_WIDTH(`XDMA_BID_WIDTH), 329 | .BRESP_WIDTH(`XDMA_BRESP_WIDTH), 330 | .RDATA_WIDTH(`XDMA_RDATA_WIDTH), 331 | .RID_WIDTH(`XDMA_RID_WIDTH), 332 | .RRESP_WIDTH(`XDMA_RRESP_WIDTH), 333 | //.RUSER_WIDTH(), 334 | .WDATA_WIDTH(`XDMA_WDATA_WIDTH), 335 | .WSTRB_WIDTH(`XDMA_WSTRB_WIDTH) 336 | //.WUSER_WIDTH() 337 | ).master_tb xdma_driver); 338 | this.xdma_driver=xdma_driver; 339 | endfunction 340 | //=================================================================================== 341 | //build phase 342 | //=================================================================================== 343 | task build(); 344 | xdma_driver.axi4_araddr<='d0; 345 | xdma_driver.axi4_arbusrt<='d0; 346 | xdma_driver.axi4_arid<='d0; 347 | xdma_driver.axi4_arlen<='d0; 348 | xdma_driver.axi4_arcache<='d0; 349 | xdma_driver.axi4_arlock<='d0; 350 | xdma_driver.axi4_arport<='d0; 351 | xdma_driver.axi4_arqos<='d0; 352 | xdma_driver.axi4_arregion<='d0; 353 | xdma_driver.axi4_arsize<='d0; 354 | xdma_driver.axi4_arvalid<='d0; 355 | xdma_driver.axi4_awaddr<='d0; 356 | xdma_driver.axi4_awburst<='d0; 357 | xdma_driver.axi4_awcache<='d0; 358 | xdma_driver.axi4_awid<='d0; 359 | xdma_driver.axi4_awlen<='d0; 360 | xdma_driver.axi4_awlock<='d0; 361 | xdma_driver.axi4_awport<='d0; 362 | xdma_driver.axi4_awqos<='d0; 363 | xdma_driver.axi4_awregion<='d0; 364 | xdma_driver.axi4_awsize<='d0; 365 | xdma_driver.axi4_awvalid<='d0; 366 | xdma_driver.axi4_bready<='d0; 367 | xdma_driver.axi4_wdata<='d0; 368 | xdma_driver.axi4_wlast<='d0; 369 | xdma_driver.axi4_wstrb<='d0; 370 | xdma_driver.axi4_wvalid<='d0; 371 | xdma_driver.axi4_wuser<='d0; 372 | xdma_driver.axi4_rready<='d1; 373 | xdma_driver.axi4_reset(`XDMA_RESET_CYCLE); 374 | endtask 375 | 376 | //=================================================================================== 377 | //run phase 378 | //=================================================================================== 379 | task run(); 380 | fork 381 | xdam_read_op(); 382 | xdma_write_op(); 383 | join_none 384 | endtask 385 | endclass 386 | --------------------------------------------------------------------------------