Modelsim独立仿真vivado的IP

最近一直在做local dimming项目的FPGA硬件实现,算法的其中一步就是直方图统计,即数字图像的某一灰度级的像素数,这个直方图的源码找了半天才搞到,就在<<牟新刚周晓郑晓亮著: 基千FPGA的数字图像处理原理及应用>>这一本书有详细的描述。但有了这个代码,还得查看直方图处理的效果,那我只有搭建仿真查看,但modelsim一直出错,提示直方图模块调用的双口ram不存在,于是下面介绍modelsim独立仿真带有vivado的IP的解决办法。

后面还会附上我一直在用的仿真脚本,十分方便!

一:实现步骤

第一步在vivado中编译仿真库,将编译后的仿真库放在自己新建的文件夹,如D:/xilinx/xlib,我已经编译好了,如下图

第二步,找到编译库路径下的modelsim.ini文件,即下面右图中的红框文件,去掉只读属性,打开后选择包含编译库的代码,图2中的63-72即vivado中包含的编译库,复制后粘贴到modelsim10.5安装根目录下的modelsim.ini文件中,如第三张图中的83-94行,即为粘贴注释的,为了以后避免和alter及ISE14.7等编译库混合,用分号注释加上分割线,下次用到其他的编译库则注释就行。保存后勾选只读属性,如下图所示

第三步,仿真带IP核的文件前提是你在vivado生成了IP核,如下图所示,找到下面红框中的两个文件路径,复制后这两个文件加入到仿真工程路径D:\3FPGA_project\02LCD_project\histogram_sim\rtl,如下面的第二张图所示

第四步:在modelsim中独立仿真,我一般是用脚本,即do文件的形式,通过编译do文件tb_top.do和波形添加do文件tb_top_wave.do实现自动仿真,这样相对于手工的形式可以避免很多体力活,先打开modelsim切换路径到sim下,直接在modelsim中输入do tb_top.do就可加载波形,如下图所示:

第五步,波形显示

二:源码

1.设计模块源码histogram_2d的源码,已经将其中的双口ram的IP核调用和其中一些代码注释(报错的),因为书中的vivado版本比较老,故不能仿真运行,会报错。

  1. 1 `timescale 1ns/1ns
  2. 2
  3. 3 module histogram_2d(
  4. 4 rst_n,
  5. 5 clk,
  6. 6 din_valid,
  7. 7 din,
  8. 8 dout,
  9. 9 vsync,
  10. 10 dout_valid,
  11. 11 rdyOutput,
  12. 12 //`ifdef Equalize
  13. 13 hist_cnt_addr,
  14. 14 hist_cnt_out,
  15. 15 //`endif
  16. 16 //`ifdef LinearTransfer
  17. 17 lowCnt,
  18. 18 highCnt,
  19. 19 lowIndex,
  20. 20 highIndex,
  21. 21 //`endif
  22. 22 int_flag
  23. 23 );
  24. 24
  25. 25 parameter DW = 14;
  26. 26 parameter IH = 512;
  27. 27 parameter IW = 640;
  28. 28 parameter TW = 32;
  29. 29
  30. 30 localparam TOTAL_CNT = IW * IH;
  31. 31 localparam HALF_WIDTH = (TW>>1);
  32. 32
  33. 33 input rst_n;
  34. 34 input clk;
  35. 35 input din_valid;
  36. 36 input [DW-1:0]din;
  37. 37 input rdyOutput;
  38. 38
  39. 39 output reg [HALF_WIDTH:0]dout;
  40. 40 input vsync;
  41. 41 output reg dout_valid;
  42. 42 output reg int_flag;
  43. 43
  44. 44 //`ifdef LinearTransfer
  45. 45 input [TW-1:0]lowCnt;
  46. 46 input [TW-1:0]highCnt;
  47. 47 output reg[DW-1:0]lowIndex;
  48. 48 output reg[DW-1:0]highIndex;
  49. 49 //`endif
  50. 50
  51. 51 //`ifdef Equalize
  52. 52 input [DW-1:0]hist_cnt_addr;
  53. 53 output reg [TW-1:0]hist_cnt_out;
  54. 54 //`endif
  55. 55
  56. 56 reg vsync_r;
  57. 57 reg dvalid_r;
  58. 58 reg dvalid_r2;
  59. 59 reg [DW-1:0]din_r;
  60. 60 reg [DW-1:0]din_r2;
  61. 61 wire hsync_fall;
  62. 62 wire hsync_rise;
  63. 63 reg [9:0]hsync_count;
  64. 64 reg count_en;
  65. 65 wire [DW-1:0]mux_addr_b;
  66. 66 wire [DW-1:0]mux_addr_b2;
  67. 67 wire [TW-1:0]q_a;
  68. 68 wire [TW-1:0]q_b;
  69. 69 reg [TW-1:0]counter;
  70. 70 wire [TW-1:0]count_value;
  71. 71 wire rst_cnt;
  72. 72 wire inc_en;
  73. 73 wire we_a;
  74. 74 wire we_b;
  75. 75 wire we_b_l;
  76. 76 reg we_b_h;
  77. 77
  78. 78 reg int_r;
  79. 79
  80. 80 wire [DW-1:0]addr_a;
  81. 81 wire [DW-1:0]clr_addr;
  82. 82 reg [DW-1:0]clr_addr_r;
  83. 83 reg [DW:0]out_pixel;
  84. 84
  85. 85 reg count_all;
  86. 86 //reg count_all_r;
  87. 87 reg count_en_r;
  88. 88
  89. 89 reg [TW-1:0]hist_cnt;
  90. 90 wire rstOutput;
  91. 91
  92. 92
  93. 93 wire [TW-1:0]dataTmp2;
  94. 94 wire clr_flag;
  95. 95
  96. 96 assign #1 hsync_fall = dvalid_r & (~(din_valid));
  97. 97 assign #1 hsync_rise = (~(dvalid_r)) & din_valid;
  98. 98
  99. 99 always @(posedge clk or negedge rst_n)
  100. 100 if (((~(rst_n))) == 1'b1)
  101. 101 hsync_count <= #1 {10{1'b0}};
  102. 102 else
  103. 103 begin
  104. 104 if (vsync_r == 1'b1)
  105. 105 hsync_count <= #1 {10{1'b0}};
  106. 106 else if (hsync_fall == 1'b1)
  107. 107 hsync_count <= hsync_count + 10'b1;
  108. 108 end
  109. 109
  110. 110 always @(posedge clk or negedge rst_n)
  111. 111 if (((~(rst_n))) == 1'b1)
  112. 112 count_en <= #1 1'b0;
  113. 113 else
  114. 114 begin
  115. 115 if (hsync_count >= IH)
  116. 116 count_en <= #1 1'b0;
  117. 117 else if (hsync_rise == 1'b1)
  118. 118 count_en <= #1 1'b1;
  119. 119 else
  120. 120 count_en <= #1 count_en;
  121. 121 end
  122. 122
  123. 123 assign mux_addr_b = ((count_en == 1'b1)) ? din_r :
  124. 124 clr_addr;
  125. 125 assign mux_addr_b2 = ((count_en == 1'b1)) ? din_r :
  126. 126 clr_addr_r;
  127. 127
  128. 128
  129. 129 always @(posedge clk)
  130. 130 begin
  131. 131 din_r2 <= #1 din_r;
  132. 132 dvalid_r2 <= #1 dvalid_r;
  133. 133 end
  134. 134
  135. 135 always @(posedge clk)
  136. 136 begin
  137. 137 if (rst_cnt == 1'b1)
  138. 138 counter <= #1 {{TW-1{1'b0}},1'b1};
  139. 139 else if (inc_en == 1'b1)
  140. 140 counter <= #1 counter + {{TW-1{1'b0}},1'b1};
  141. 141 else
  142. 142 counter <= #1 counter;
  143. 143 end
  144. 144
  145. 145 assign #1 rst_cnt = (((din_r != din_r2) | ((dvalid_r2 == 1'b1) & (dvalid_r == 1'b0)))) ? 1'b1 :
  146. 146 1'b0;
  147. 147 assign #1 inc_en = (((din_r == din_r2) & (dvalid_r2 == 1'b1))) ? 1'b1 :
  148. 148 1'b0;
  149. 149
  150. 150 assign #1 we_a = ((((din_r != din_r2) & (dvalid_r2 == 1'b1)) | ((dvalid_r2 == 1'b1) & (dvalid_r == 1'b0)))) ? 1'b1 :
  151. 151 1'b0;
  152. 152 assign #1 count_value = ((count_en == 1'b1)) ? counter + q_b :
  153. 153 {TW{1'b0}};
  154. 154
  155. 155 assign #1 addr_a = din_r2;
  156. 156
  157. 157 assign dataTmp2 = {TW{1'b0}};
  158. 158
  159. 159 // hist_buffer dpram_bin_l(
  160. 160 // .address_a(addr_a), //addra
  161. 161 // .address_b(mux_addr_b), //addrb
  162. 162 // .clock(clk),
  163. 163 // .data_a(count_value[HALF_WIDTH - 1:0]), //dina
  164. 164 // .data_b(dataTmp2[HALF_WIDTH - 1:0]),
  165. 165 // .wren_a(we_a),
  166. 166 // .wren_b(we_b_l),
  167. 167 // .q_a(q_a[HALF_WIDTH - 1:0]), //douta
  168. 168 // .q_b(q_b[HALF_WIDTH - 1:0]) //doutb
  169. 169 // );
  170. 170 //
  171. 171 hist_buffer dpram_bin_l (
  172. 172 .clka(clk), // input wire clka
  173. 173 .ena(1), // input wire ena
  174. 174 .wea(we_a), // input wire [0 : 0] wea
  175. 175 .addra(addr_a[9 : 0]), // input wire [9 : 0] addra
  176. 176 .dina(count_value[HALF_WIDTH - 1:0]), // input wire [31 : 0] dina
  177. 177 .douta(q_a[HALF_WIDTH - 1:0]), // output wire [31 : 0] douta
  178. 178 .clkb(clk), // input wire clkb
  179. 179 .enb(1), // input wire enb
  180. 180 .web(we_b_l), // input wire [0 : 0] web
  181. 181 .addrb(mux_addr_b[9 : 0]), // input wire [9 : 0] addrb
  182. 182 .dinb(0), // input wire [31 : 0] dinb
  183. 183 .doutb(q_b[HALF_WIDTH - 1:0]) // output wire [31 : 0] doutb
  184. 184 );
  185. 185 //
  186. 186 // defparam dpram_bin_l.AW = DW;
  187. 187 // defparam dpram_bin_l.DW = HALF_WIDTH;
  188. 188
  189. 189 // hist_buffer dpram_bin_h(
  190. 190 // .address_a(addr_a),
  191. 191 // .address_b(mux_addr_b2),
  192. 192 // .clock(clk),
  193. 193 // .data_a(count_value[TW - 1:HALF_WIDTH]),
  194. 194 // .data_b(dataTmp2[TW - 1:HALF_WIDTH]),
  195. 195 // .wren_a(we_a),
  196. 196 // .wren_b(we_b_h),
  197. 197 // .q_a(q_a[TW - 1:HALF_WIDTH]),
  198. 198 // .q_b(q_b[TW - 1:HALF_WIDTH])
  199. 199 // );
  200. 200
  201. 201 hist_buffer dpram_bin_h (
  202. 202 .clka(clk), // input wire clka
  203. 203 .ena(1), // input wire ena
  204. 204 .wea(we_a), // input wire [0 : 0] wea
  205. 205 .addra(addr_a[9 : 0]), // input wire [9 : 0] addra
  206. 206 .dina(count_value[TW - 1:HALF_WIDTH]), // input wire [31 : 0] dina
  207. 207 .douta(q_a[TW - 1:HALF_WIDTH]), // output wire [31 : 0] douta
  208. 208 .clkb(clk), // input wire clkb
  209. 209 .enb(1), // input wire enb
  210. 210 .web(we_b_h), // input wire [0 : 0] web
  211. 211 .addrb(mux_addr_b2[9 : 0]), // input wire [9 : 0] addrb
  212. 212 .dinb(0), // input wire [31 : 0] dinb
  213. 213 .doutb(q_b[TW - 1:HALF_WIDTH]) // output wire [31 : 0] doutb
  214. 214 );
  215. 215
  216. 216 // defparam dpram_bin_h.AW = DW;
  217. 217 // defparam dpram_bin_h.DW = HALF_WIDTH;
  218. 218
  219. 219 always @(posedge clk or negedge rst_n)
  220. 220 if (((~(rst_n))) == 1'b1)
  221. 221 count_en_r <= #1 1'b0;
  222. 222 else
  223. 223 count_en_r <= #1 count_en;
  224. 224
  225. 225 assign rstOutput = count_en_r | (~(rdyOutput));
  226. 226
  227. 227 reg [DW-1:0]lowIndex_tmp;
  228. 228 reg [DW-1:0]highIndex_tmp;
  229. 229 reg [DW-1:0]highIndex_tmp2;
  230. 230 reg bFindMax;
  231. 231 reg bFindMin;
  232. 232
  233. 233 always @(posedge clk or negedge rst_n)
  234. 234 if ((~(rst_n)) == 1'b1)
  235. 235 begin
  236. 236 lowIndex_tmp <= {DW{1'b0}};
  237. 237 highIndex_tmp <= {DW{1'b1}};
  238. 238 bFindMin <= 1'b0;
  239. 239 bFindMax <= 1'b0;
  240. 240 highIndex_tmp2 <= {DW{1'b0}};
  241. 241 end
  242. 242 else
  243. 243 begin
  244. 244 if (vsync_r == 1'b0 & vsync == 1'b1)
  245. 245 begin
  246. 246 lowIndex_tmp <= {DW{1'b0}};
  247. 247 highIndex_tmp <= {DW{1'b1}};
  248. 248 highIndex_tmp2 <= {DW{1'b0}};
  249. 249 lowIndex <= lowIndex_tmp;
  250. 250 if (bFindMax == 1'b1)
  251. 251 highIndex <= highIndex_tmp;
  252. 252 else
  253. 253 highIndex <= highIndex_tmp2;
  254. 254 bFindMin <= 1'b0;
  255. 255 bFindMax <= 1'b0;
  256. 256 end
  257. 257 else
  258. 258 begin
  259. 259 if (out_pixel[0] == 1'b1)
  260. 260 begin
  261. 261 if ((~(q_b == {HALF_WIDTH{1'b0}})))
  262. 262 highIndex_tmp2 <= clr_addr - 4'h1;
  263. 263 if ((hist_cnt >= lowCnt) & bFindMin == 1'b0)
  264. 264 begin
  265. 265 lowIndex_tmp <= clr_addr - 4'h1;
  266. 266 bFindMin <= 1'b1;
  267. 267 end
  268. 268 if (hist_cnt >= (TOTAL_CNT - highCnt) & bFindMax == 1'b0)
  269. 269 begin
  270. 270 highIndex_tmp <= clr_addr - 4'h1;
  271. 271 bFindMax <= 1'b1;
  272. 272 end
  273. 273 end
  274. 274 end
  275. 275 end
  276. 276
  277. 277 // hist_buffer hist_cnt_buf(
  278. 278 // .address_a(out_pixel_r2),
  279. 279 // .address_b(hist_cnt_addr),
  280. 280 // .clock(clk),
  281. 281 // .data_a(hist_cnt),
  282. 282 // .data_b(),
  283. 283 // .wren_a(dout_valid),
  284. 284 // .wren_b(1'b0),
  285. 285 // .q_a(),
  286. 286 // .q_b(hist_cnt_temp)
  287. 287 // );
  288. 288 // defparam hist_cnt_buf.AW = DW;
  289. 289 // defparam hist_cnt_buf.DW = TW;
  290. 290
  291. 291 hist_buffer hist_cnt_buf (
  292. 292 .clka(clk), // input wire clka
  293. 293 .ena(1), // input wire ena
  294. 294 .wea(dout_valid), // input wire [0 : 0] wea
  295. 295 .addra(out_pixel[9:0]), // input wire [9 : 0] addra
  296. 296 .dina(hist_cnt), // input wire [31 : 0] dina
  297. 297 .douta(), // output wire [31 : 0] douta
  298. 298 .clkb(clk), // input wire clkb
  299. 299 .enb(1), // input wire enb
  300. 300 .web(0), // input wire [0 : 0] web
  301. 301 .addrb(hist_cnt_addr[9:0]), // input wire [9 : 0] addrb
  302. 302 .dinb(0), // input wire [31 : 0] dinb //data_b
  303. 303 .doutb(hist_cnt_temp) // output wire [31 : 0] doutb
  304. 304 );
  305. 305
  306. 306 endmodule

histogram_2d

2.原创的脚本文件

A添加信号和显示波形的tb_top_wave.do

  1. 1 #添加信号和显示其波形
  2. 2 onerror {resume}
  3. 3 quietly WaveActivateNextPane {} 0
  4. 4 add wave -noupdate -divider {input paramters}
  5. 5 add wave -noupdate -radix unsigned /tb_top/CLK_FREQ
  6. 6 add wave -noupdate -radix unsigned /tb_top/CLK_PERIOD
  7. 7
  8. 8 add wave -noupdate -divider {histogram_2d input}
  9. 9 add wave -noupdate /tb_top/inst_hist/clk
  10. 10 add wave -noupdate /tb_top/inst_hist/rst_n
  11. 11 add wave -noupdate /tb_top/inst_hist/din_valid
  12. 12 add wave -noupdate /tb_top/inst_hist/din
  13. 13
  14. 14 add wave -noupdate -divider {histogram_2d output}
  15. 15 add wave -noupdate /tb_top/inst_hist/dout
  16. 16 add wave -noupdate /tb_top/inst_hist/vsync
  17. 17 add wave -noupdate /tb_top/inst_hist/dout_valid
  18. 18
  19. 19 add wave -noupdate -divider {end signal}
  20. 20
  21. 21 TreeUpdate [SetDefaultTree]
  22. 22 WaveRestoreCursors {{Cursor 1} {912366093 ps} 0}
  23. 23 configure wave -namecolwidth 150
  24. 24 configure wave -valuecolwidth 100
  25. 25 configure wave -justifyvalue left
  26. 26 configure wave -signalnamewidth 0
  27. 27 configure wave -snapdistance 10
  28. 28 configure wave -datasetprefix 0
  29. 29 configure wave -rowmargin 4
  30. 30 configure wave -childrowmargin 2
  31. 31 configure wave -gridoffset 0
  32. 32 configure wave -gridperiod 1
  33. 33 configure wave -griddelta 40
  34. 34 configure wave -timeline 0
  35. 35 configure wave -timelineunits ns
  36. 36 update
  37. 37 WaveRestoreZoom {891247063 ps} {925431255 ps}

tb_top_wave.do

B新建work库,编译.v文件和启动顶层仿真文件,及执行添加信号和显示波形的tb_top_wave.do的编译do文件tb_top.do

  1. 1 #不需要新建modelsim工程,直接运行.do文件就可以仿真
  2. 2 quit -sim
  3. 3 #新建work库
  4. 4 vlib work
  5. 5
  6. 6 #将work库映射到当前工作目录
  7. 7 #vmap [-help] [-c] [-del] [<logical_name>] [<path>]
  8. 8 vmap work
  9. 9
  10. 10 #编译所有.v文件到work工作库
  11. 11 #-work <path> Specify library WORK
  12. 12 #-vlog01compat Ensure compatibility with Std 1364-2001
  13. 13 #-incr Enable incremental compilation
  14. 14 #"rtl/*.v" 当前工作目录下的rtl文件夹中的所有.v文件,支持相对路径,但是要加双引号“”
  15. 15 #vlog
  16. 16
  17. 17 vlog -work work -vlog01compat -incr "../testbench/prim_sim.v"
  18. 18 vlog -work work -vlog01compat -incr "../testbench/tb_top.v"
  19. 19
  20. 20 vlog -work work -vlog01compat -incr "../rtl/histogram_2d.v"
  21. 21 vlog -work work -vlog01compat -incr "../rtl/*.v"
  22. 22 #vlog -work work -vlog01compat -incr "../rtl/uart_master_src/*.v"
  23. 23
  24. 24
  25. 25 #编译所有.vhd文件
  26. 26 #-work <path> Specify library WORK
  27. 27 #-93 Enable support for VHDL 1076-1993
  28. 28 #-2002 Enable support for VHDL 1076-2002
  29. 29 #vcom
  30. 30
  31. 31 #启动仿真顶层文件
  32. 32 #-L <libname> Search library for design units instantiated from Verilog and for VHDL default component binding
  33. 33 #+nowarn<CODE | Number> Disable specified warning message (Example: +nowarnTFMPC)
  34. 34 #-t [1|10|100]fs|ps|ns|us|ms|sec Time resolution limit VHDL default: resolution setting from .ini file)
  35. 35 # (Verilog default: minimum time_precision in the design)
  36. 36 #-novopt Force incremental mode (pre-6.0 behavior)
  37. 37
  38. 38 vsim +nowarnTFMPC -L work -novopt -l tb_top.log work.tb_top
  39. 39
  40. 40 #产生一个wave log format(WLF)......
  41. 41 log -r /*
  42. 42
  43. 43 #打开wave窗口
  44. 44 view wave
  45. 45
  46. 46 #添加仿真信号
  47. 47 #在已经添加好信号和设置好格式的wave窗口,点击【File】->【Save Fomat】
  48. 48 #存为任意名字的.do文件,该文件包含了加载哪些信号及其显示格式的命令
  49. 49 do tb_top_wave.do
  50. 50
  51. 51 #设置运行时间
  52. 52 run -all
  53. 53
  54. 54 #dataflow调试
  55. 55 #具体方法是在仿真后执行命令 view dataflow 就可以打开dataflow文件,
  56. 56 #在dataflow的窗口菜单中点击add中的view all nets就可以观察到各个模块之间的逻辑联系,
  57. 57 #模块一般都为initial模块、always模块、assign模块等等。点击中一个模块,则这个模块变为红色。
  58. 58 #这时候在view菜单下点击show wave就可以在窗口下方弹出wave窗口,
  59. 59 #不同的是这个wave窗口所显示的信号变量仅为点击中的模块所包括的信号变量,
  60. 60 #这时候也可以点击仿真run –all小图标来仿真有关这个模块的输入输出关系。
  61. 61 #view dataflow

tb_top.do

三,总结

本文通过实践得出,不同于下面的博客。书中的设计思路及网上资料很有帮助,但具体细节实现上会碰到问题。故多尝试自己动手编写代码实现,多借鉴别人的算法框架和思路。

参考博客:

https://www.cnblogs.com/ninghechuan/p/8305925.html

Modelsim独立仿真Vivado Clocking Wizard IP Core

https://cloud.tencent.com/developer/article/1529571

modelsim 独立仿真vivado的IP核及仿真脚本的更多相关文章

  1. 调用altera IP核的仿真流程—下

    调用altera IP核的仿真流程—下 编译 在 WorkSpace 窗口的 counter_tst.v上点击右键,如果选择Compile selected 则编译选中的文件,Compile All是 ...

  2. 调用altera IP核的仿真流程—上

    调用altera IP核的仿真流程—上 在学习本节内容之后,请详细阅读<基于modelsim-SE的简单仿真流程>,因为本节是基于<基于modelsim-SE的简单仿真流程>的 ...

  3. Altera三速以太网IP核快速仿真与使用(上篇)

    对于比较高级的ip核,altera一般都会提供仿真案例,网上有关于这个IP核的各种仿真方法,但都比较繁琐,前几日,朋友跟我分享了一个比较快速高效的仿真方法,这个方法也是他摸索折腾了一段时间才总结出来的 ...

  4. Mdoelsim10.4怎么脚本单独仿真ISE14.7 IP核

    软件版本: Modelsim10.4SE ISE14.7 仿真IP:时钟管理IP(clock wizard)   流程: 1.对于Modelsim10.4SE,并不自带Xilinx家的仿真库,因此首先 ...

  5. altera DDR2 IP核之仿真

    在生成的IP核文件夹下,有一个testbench文件夹,里面包含了一个example测试激励和DDR2仿真模型. 如下 20 -rw-r--r-- 1 Administrator 197121 171 ...

  6. 用Modelsim SE 直接仿真 Altera(Intel PSG) IP核 需要注意的问题

    如果我们直接用Modelsim SE仿真 Altera IP核,首先会进入Quartus II目录下找到IP核对应的仿真库源文件,然后在Modelsim SE中进行编译,添加到Modelsim SE的 ...

  7. Lattice 的 DDR IP核使用调试笔记之DDR 的 仿真

    —— 远航路上ing 整理于 博客园.转载请标明出处. 在上节建立完工程之后,要想明确DDR IP的使用细节,最好是做仿真.然后参考仿真来控制IP 核. 仿真的建立: 1.在IP核内的以下路径找到以下 ...

  8. System Generator 生成IP核在Vivado中进行调用

    System Generator 生成IP核在Vivado中进行调用 1.首先在Simulink中搭建硬件模型 2.查看仿真结果 3.资源分析与时序分析 4.启动vivado,关联生成的IP核 5.调 ...

  9. 如何用ModelsimSE仿真IP核-以PLL为例

    我们之前介绍了如何使用Modelsim SE进行仿真和利用do文件的仿真方法,但是其中待仿真的模块是我们自己编写的Verilog模块,但是在实际工作中,我们的设计中会经常用到FPGA厂商给我们提供的现 ...

随机推荐

  1. Lidar激光雷达市场

    Lidar激光雷达市场 近年来,激光雷达技术在飞速发展,从一开始的激光测距技术,逐步发展了激光测速.激光扫描成像.激光多普勒成像等技术,如今在无人驾驶.AGV.机器人等领域已相继出现激光雷达的身影. ...

  2. ALD和CVD晶体管薄膜技术

    ALD和CVD晶体管薄膜技术 现代微处理器内的晶体管非常微小,晶体管中的一些关键薄膜层甚至只有几个原子的厚度,光是英文句点的大小就够容纳一百万个晶体管还绰绰有余.ALD 是使这些极细微结构越来越普遍的 ...

  3. python_request的安装及模拟json的post请求及带参数的get请求

    一.Requests模块安装 安装方式一:执行 pip install -U requests 联网安装requests 安装方式二:进入https://pypi.org/project/reques ...

  4. 《精通 ASP.NET Core MVC (第七版)》开始发售

    学习 Web 开发技术很难吗?没有适合的学习资料,确实很枯燥,很难.如果有一本如同良师益友的优秀图书辅助,就很轻松,一点也不难! 对于优秀的技术图书来说,必须从读者的角度来编写,而不是从作者的角度来编 ...

  5. Java 并发基础知识

    一.什么是线程和进程? 进程: 是程序的一次执行过程,是系统运行程序的基本单元(就比如打开某个应用,就是开启了一个进程),因此进程是动态的.系统运行一个程序即是一个程序从创建.运行到消亡的过程. 在 ...

  6. jquery给动态生成的元素绑定事件,on函数

    首先先解释一下什么是动态生成的元素:动态生成的元素即我们用jquery的内部插入函数append()所生成的html代码.相对的也有静态生成的元素:即直接编写在页面的html代码. 下面通过例子来讲解 ...

  7. 如果你这么去理解HashMap就会发现它真的很简单

    Java中的HashMap相信大家都不陌生,也是大家编程时最常用的数据结构之一,各种面试题更是恨不得掘地三尺的去问HashMap.HashTable.ConcurrentHashMap,无论面试题多么 ...

  8. 【NLP学习其二】什么是隐马尔可夫模型HMM?

    概念 隐马尔可夫模型描述的是两个时序序列联合分布p(x,y)的概率模型,其中包含了两个序列: x序列外界可见(外界指的是观测者),称为观测序列(obsevation seuence) y序列外界不可见 ...

  9. ASW 工作流最佳实践(二):使用 ASW 并发调用函数

    在音视频转码.ETL 作业处理.基因数据处理等诸多场景中,我们都可以通过工作流并行调用云函数,将任务进行并行处理,大大提高任务处理的吞吐量,满足应用场景的高实时性.高并发能力. 在<使用 ASW ...

  10. redis实现分布式锁天然的缺陷

    redis分布式锁基本原理 采用 redis 实现分布式锁,主要是利用其单线程命令执行的特性,一般是 setnx, 只会有一个线程会执行成功,也就是只有一个线程能成功获取锁: 看着很完美 看看可能有什 ...