🌍首页
📁归档
⏳时光机
🚩友链
📫留言
📧订阅
🌟推荐
📕考研课程
🏜️ 免费壁纸
❤ 捐助本站
💰资助名单
🎵音乐实验
Search
1
【NPN/PNP三极管】放大电路饱和失真和截止失真的区别
20,307 阅读
2
论文写作中如何把word/wps里面所有数字和字母替换为新罗马字体
10,816 阅读
3
【高数】形心计算公式讲解大全
9,157 阅读
4
Vivado-FPGA Verilog烧写固化教程
8,240 阅读
5
【概论】一阶矩、二阶矩原点矩,中心矩区别与概念
7,937 阅读
🪶微语&随笔
励志美文
我的随笔
工作办公
📡电子&通信
嵌入式&系统
通信&信息处理
编程&脚本笔记
⌨️IC&系统
FPGA&ASIC
VLSI&IC验证
EDA&虚拟机
💻电子&计算机
IP&SOC设计
机器学习
软硬件算法
登录
/
注册
FPGA&ASIC(共62篇)
找到
62
篇与
FPGA&ASIC
相关的结果
- 第 5 页
2022-06-21
【8】Verilog练习-串口数据发送
摘要本文介绍了Verilog语言编写的串口数据发送模块,包括模块的代码实现和测试平台。模块通过状态机控制数据发送,支持波特率调整,并通过测试平台验证了其功能。关键词:Verilog, 串口通信, UART发送, 串口数据发送, UART_TXer理论: 图片 图片 代码: //串口发送模块 `timescale 1ns/10ps module UART_TXer( clk, res, data_in, en_data_in, TX, rdy ); input clk; input res; input[7:0] data_in;//准备发送的数据; input en_data_in;//发送使能; output TX;//输出使能 output rdy;//空闲标志,0表示空闲; reg[3:0] state;//主状态机寄存器; reg[9:0] send_buf;//发送寄存器 assign TX=send_buf[0];//连接TX; reg[9:0] send_flag;//用于判断右移结束; reg[12:0] con;//用于计算波特周期 reg rdy; always@(posedge clk or negedge res) if(~res)begin state<=0;send_buf<=1;con<=0;send_flag<=10'b10_0000_0000;rdy<=0; end else begin case(state) 0://等待使能信号; begin if(en_data_in)begin send_buf={1'b1,data_in,1'b0}; send_flag<=10'b10_0000_0000; rdy<=1; state<=1; end end 1://串口发送,寄存器右移; begin if(con==5000-1)begin con<=0; end else begin con<=con+1; end if(con==5000-1)begin send_buf[8:0]<=send_buf[9:1]; send_flag[8:0]<=send_flag[9:1]; end if(send_flag[0])begin rdy<=0; state<=0; end end endcase end endmodule //----testbench of UART_TXer--- module UART_TXer_tb; reg clk,res; reg[7:0] data_in; reg en_data_in; wire TX; wire rdy; UART_TXer UART_TXer( //同名例化; clk, res, data_in, en_data_in, TX, rdy ); initial begin clk<=0;res<=0;data_in<=8'h7f;en_data_in<=0; #17 res<=1; #30 en_data_in<=1; #10 en_data_in<=0; #10000 $stop; end always #5 clk<=~clk; endmodule结果: 图片
FPGA&ASIC
# ASIC/FPGA
刘航宇
4年前
0
517
3
2022-06-15
【7】Verilog练习-串口数据接收
摘要本文介绍了使用Verilog编写的串口数据接收模块,包括原理、程序代码和测试平台。该模块通过状态机接收串口数据,并在接收完成后产生使能脉冲。关键词:Verilog, 串口数据接收, UART_Rxer, 状态机, 串口通信原理: 图片 图片 图片 图片 程序 //串口数据接收 `timescale 1ns/10ps module UART_Rxer( clk, res, RX, data_out, en_data_out ); input clk; input res; input RX; output[7:0] data_out;//接收字节输出; output en_data_out;//输出使能; reg[7:0] data_out; reg[7:0] state;//主状态机; reg[12:0] con;//用于计算比特宽度; reg[3:0] con_bits;//用于计算比特数; reg RX_delay;//RX的延时; reg en_data_out; always@(posedge clk or negedge res) if(~res)begin state<=0;con<=0;con_bits<=0;RX_delay<=0; data_out<=0;en_data_out<=0; end else begin RX_delay<=RX; case(state) 0://等空闲; begin if(con==5000-1)begin //24M/4800=5000 con<=0; end else begin con<=con+1; end if(con==0)begin if(RX)begin con_bits<=con_bits+1; end else begin con_bits<=0; end if(con_bits==12)begin//连续12个1,说明处于空闲状态 state<=1; end end end 1://等起始位; begin en_data_out<=0; if(~RX&RX_delay)begin state<=2; end end 2://收最低位b0;T=5000;1.5T=7500 begin if(con==7500-1)begin con<=0; data_out[0]<=RX; state<=3; end else begin con<=con+1; end end 3://收最低位b1; begin if(con==5000-1)begin con<=0; data_out[1]<=RX; state<=4; end else begin con<=con+1; end end 4://收最低位b2; begin if(con==5000-1)begin con<=0; data_out[2]<=RX; state<=5; end else begin con<=con+1; end end 5://收最低位b3; begin if(con==5000-1)begin con<=0; data_out[3]<=RX; state<=6; end else begin con<=con+1; end end 6://收最低位b4; begin if(con==5000-1)begin con<=0; data_out[4]<=RX; state<=7; end else begin con<=con+1; end end 7://收最低位b5; begin if(con==5000-1)begin con<=0; data_out[5]<=RX; state<=8; end else begin con<=con+1; end end 8://收最低位b6; begin if(con==5000-1)begin con<=0; data_out[6]<=RX; state<=9; end else begin con<=con+1; end end 9://收最低位b7; begin if(con==5000-1)begin con<=0; data_out[7]<=RX; state<=10; end else begin con<=con+1; end end 10://产生使能脉冲 begin en_data_out<=1; state<=1; end default:// begin state<=0; con<=0; con_bits<=0; en_data_out<=0; end endcase end endmodule //----testbench of UART_Rxer-- module UART_Rxer_tb; reg clk,res; wire RX; wire[7:0] data_out; wire en_data_out; reg[25:0] RX_send;//里面装有串口字节发送数据; assign RX=RX_send[0];//连接RX reg[12:0] con; UART_Rxer UART_Rxer( .clk(clk), .res(res), .RX(RX), .data_out(data_out), .en_data_out(en_data_out) ); initial begin clk<=0;res<=0;RX_send<={1'b1,8'haa,1'b0,16'hffff}; con<=0; #17 res<=1; #4000000 $stop; end always #5 clk<=~clk; always@(posedge clk)begin if(con==5000-1)begin con<=0; end else begin con<=con+1; end if(con==0)begin RX_send[24:0]<=RX_send[25:1]; RX_send[25]<=RX_send[0]; end end endmodule现象 图片
FPGA&ASIC
刘航宇
4年前
0
543
3
【6】Verilog练习-三角波梯形波发生器
摘要本文介绍了使用Verilog语言实现的三角波和梯形波发生器的设计。首先,通过模块`tri_gen`实现了基本的三角波发生器,然后通过增加状态和计数器改进为梯形波发生器。文中还提供了测试模块`tri_gen_tb`来验证波形输出。关键词:Verilog, 三角波发生器, 梯形波发生器, Verilog代码, 测试平台三角波发生器理论 图片 代码 //三角波发生器 `timescale 1ns/10ps module tri_gen( clk, res, d_out ); input clk; input res; output[8:0] d_out; reg state; reg[8:0] d_out; always@(posedge clk or negedge res) if(~res) begin state<=0;d_out<=0; end else begin case(state) 0://上升 begin d_out<=d_out+1; if(d_out==299)begin state<=1; end end 1://下降 begin d_out<=d_out-1; if(d_out==1)begin state<=0; end end endcase end endmodule //------testbench of tri_gen---- module tri_gen_tb; reg clk,res; wire[8:0] d_out; tri_gen U1( .clk(clk), .res(res), .d_out(d_out) ); initial begin clk<=0;res<=0; #17 res<=1; #8000 $stop; end always #5 clk<=~clk; endmodule现象 图片 梯形波发生器 //三角波发生器->改进为梯形波 `timescale 1ns/10ps module tri_gen( clk, res, d_out ); input clk; input res; output[8:0] d_out; reg[1:0] state;//3个状态2位,不在是原来的1bit reg[8:0] d_out; reg[7:0] con;//计数器,记录平顶周期个数 always@(posedge clk or negedge res) if(~res) begin state<=0;d_out<=0;con<=0; end else begin case(state) 0://上升 begin d_out<=d_out+1; if(d_out==299)begin state<=1; end end 1://平顶 begin if(con==200) begin state<=2; con<=0; end else begin con<=con+1; end end 2://下降 begin d_out<=d_out-1; if(d_out==1)begin state<=0; end end default://3状态 begin state<=0; con<=0; end endcase end endmodule //------testbench of tri_gen---- module tri_gen_tb; reg clk,res; wire[8:0] d_out; tri_gen U1( .clk(clk), .res(res), .d_out(d_out) ); initial begin clk<=0;res<=0; #17 res<=1; #20000 $stop; end always #5 clk<=~clk; endmodule现象 图片
FPGA&ASIC
刘航宇
4年前
0
834
3
2022-05-25
【5】Verilog练习-相邻16点相加
摘要本文介绍了使用Verilog语言实现的相邻16点相加模块,包括模块的代码、测试平台以及运行结果。该模块通过采样时钟和采样信号,对16个相邻点进行累加,并输出累加结果。关键词:Verilog, 相邻16点相加, 代码示例, 信号处理, 累加计算图片 图片 代码 //相邻16点相加 `timescale 1ns/10ps module sigma_16p( clk, res, data_in, syn_in, data_out, syn_out ); input clk,res; input[7:0] data_in;//采样信号 input syn_in;//采样时钟 output[11:0] data_out;//累加结果输出 output syn_out;//累加结果同步脉冲 reg syn_in_n1;//syn_in的反向延时 wire syn_pulse;//采样时钟上升沿识别脉冲 assign syn_pulse=syn_in&syn_in_n1; reg[3:0] con_syn;//采样时钟循环计数器 wire[7:0] comp_8;//补码 wire[11:0] d_12;//升位结果 assign comp_8=data_in[7]?{data_in[7],~data_in[6:0]+1}:data_in;//补码运算 assign d_12={comp_8[7],comp_8[7],comp_8[7],comp_8[7],comp_8}; reg[11:0] sigma;//累加计算 reg[11:0] data_out; reg syn_out; always@(posedge clk or negedge res) if(~res)begin syn_in_n1<=0;con_syn<=0;sigma<=0;data_out<=0;syn_out<=0; end else begin syn_in_n1<=~syn_in; if(syn_pulse)begin con_syn<=con_syn+1; end if(syn_pulse)begin if(con_syn==15)begin sigma<=d_12; data_out<=sigma; syn_out<=1; end else begin sigma<=sigma+d_12; end end else begin syn_out<=0; end end endmodule //-----testbench of sigma_16p--- module sigma_16p_tb; reg clk,res; reg[7:0] data_in; reg syn_in; wire[11:0] data_out; wire syn_out; sigma_16p sigma_16p( .clk(clk), .res(res), .data_in(data_in), .syn_in(syn_in), .data_out(data_out), .syn_out(syn_out) ); initial begin clk<=0;res<=0;data_in=1;syn_in<=0; #17 res<=1; #50000 $stop; end always #5 clk<=~clk; always #100 syn_in<=~syn_in; endmodule现象 图片
FPGA&ASIC
刘航宇
4年前
0
476
1
【4】Verilog练习-秒计数器设计
摘要本文介绍了使用Verilog语言设计的秒计数器,包括秒脉冲分频计数器和秒脉冲尖的生成,以及秒数的计数和循环。同时,展示了测试平台和数码管显示的扩展应用。关键词:Verilog, 秒计数器, 设计, 仿真, 数码管秒计数器设计 图片 代码 //秒计数器,0-9循环 `timescale 1ns/10ps module s_counter( clk, res, s_num ); input clk; input res; output[3:0] s_num; parameter frequency_clk=24;//24MHZ; reg[24:0] con_t;//秒脉冲分频计数器; reg s_pulse;//秒脉冲尖; reg[3:0] s_num; always@(posedge clk or negedge res) if(~res)begin con_t<=0;s_pulse<=0;s_num<=0; end else begin //if(con_t==frequency_clk*1000000-1)begin if(con_t==frequency_clk*1000-1)begin//仿真便于观察 con_t<=0; end else begin con_t<=con_t+1; end if(con_t==0)begin s_pulse<=1; end else begin s_pulse<=0; end if(s_pulse) begin if(s_num==9)begin s_num<=0; end else begin s_num<=s_num+1; end end end endmodule //-----testbench of s_counter--- module s_counter_tb; reg clk,res; wire[3:0] s_num; s_counter s_counter( .clk(clk), .res(res), .s_num(s_num) ); initial begin clk<=0;res<=0; #17 res<=1; #1000000 $stop; end always #5 clk<=~clk; endmodule现象 图片 扩展:数码管 图片 图片
FPGA&ASIC
刘航宇
4年前
0
477
2
2022-05-23
【3】Verilog练习-时序逻辑与伪随机码发生器设计和仿真
摘要本文介绍了Verilog语言在时序逻辑和伪随机码发生器设计和仿真中的应用。通过示例代码展示了计数器和伪随机码发生器的实现,并进行了仿真验证。关键词:Verilog, 时序逻辑, 伪随机码发生器, 仿真, Verilog代码时序逻辑代码与仿真 图片 代码 //计数器 `timescale 1ns/10ps module counter( clk, res, y ); input clk; input res; output[7:0] y; reg[7:0] y; wire[7:0] sum;//+1运算的结果; assign sum=y+1;//组合逻辑部分; always@(posedge clk or negedge res) if(~res)begin y<=0; end else begin y<=sum; end endmodule //----testbench of counter---- module counter_tb; reg clk,res; wire[7:0] y; counter counter( .clk(clk), .res(res), .y(y) ); initial begin clk<=0;res<=0; #17 res<=1; #6000 $stop; end always #5 clk<=~clk; endmodule现象 图片 模拟显示 图片 伪随机码发生器 图片 代码 //四级伪随机码发生器; `timescale 1ns/10ps module m_gen( clk, res, y ); input clk; input res; output y; reg[3:0] d; assign y=d[0]; always@(posedge clk or negedge res) if(~res)begin d<=4'b1111; end else begin d[2:0]<=d[3:1];//右移一位; d[3]<=d[3]+d[0];//模二加; end endmodule //----testbench of m_gen---- module m_gen_tb; reg clk,res; wire y; m_gen m_gen( .clk(clk), .res(res), .y(y) ); initial begin clk<=0;res<=0; #17 res<=1; #600 $stop; end always #5 clk<=~clk; endmodule现象 图片
FPGA&ASIC
刘航宇
4年前
0
548
1
2022-05-21
【2】Verilog练习-补码转化与7段译码逻辑设计
摘要本文介绍了Verilog语言中补码转化和7段译码逻辑的设计。首先展示了补码转化的Verilog代码,包括模块定义和测试平台。接着,展示了7段译码逻辑的Verilog代码,包括模块定义和测试平台。关键词:Verilog, 补码转化, 7段译码逻辑, Verilog代码, 译码器设计补码转化 图片 程序 //补码转化逻辑 `timescale 1ns/10ps module comp_conv( a, a_comp ); input[7:0] a; output[7:0] a_comp; //wire[6:0] b;//按位取反的幅度位 //wire[7:0] y;//负数的补码; //assign b=~a[6:0]; //assign y[6:0]=b+1;//按位取反+1 //assign y[6:0]=~a[6:0]+1;//按位取反+1 //assign y[7]=a[7];//符号位不变 //assign y={a[7],~a[6:0]+1}; //assign a_comp=a[7]?y:a;//二选一 assign a_comp=a[7]?{a[7],~a[6:0]+1}:a;//二选一 endmodule //----testbench of comp_conv--- module comp_conv_tb; reg[7:0] a_in; wire[7:0] y_out; comp_conv comp_conv( .a(a_in), .a_comp(y_out) ); initial begin a_in<=0; #3000 $stop; end always #10 a_in<=a_in+1; endmodule现象 图片 7段译码逻辑设计 图片 代码: //七段码译码器 `timescale 1ns/10ps module seg_dec( num, a_g ); input[3:0] num; output[6:0] a_g;//a_g-->{a,b,c,d,e,f,g} reg[6:0] a_g; always@(num)begin case(num) 4'd0: begin a_g<=7'b111_1110; end 4'd1: begin a_g<=7'b011_0000; end 4'd2: begin a_g<=7'b110_1101; end 4'd3: begin a_g<=7'b111_1100; end 4'd4: begin a_g<=7'b011_0011; end 4'd5: begin a_g<=7'b101_1011; end 4'd6: begin a_g<=7'b101_1111; end 4'd7: begin a_g<=7'b111_0000; end 4'd8: begin a_g<=7'b111_1111; end 4'd9: begin a_g<=7'b111_1011; end default: begin a_g<=7'b000_0001; end//中杠 endcase end endmodule //----testbench of seg_dec--- module seg_dec_tb; reg[3:0] num_in; wire[6:0] a_g_out; seg_dec seg_dec( .num(num_in), .a_g(a_g_out) ); initial begin num_in<=0; #200 $stop; end always #10 num_in<=num_in+1; endmodule现象 图片
FPGA&ASIC
刘航宇
4年前
0
707
3
2022-05-17
【2】Verilog练习-组合逻辑电路多路选择器
摘要本文介绍了Verilog语言在组合逻辑电路多路选择器设计中的应用,包括二选一和多路选择逻辑的设计与测试。通过实例展示了如何使用always语句块实现组合逻辑,并提供了相应的测试代码和结果。关键词:Verilog, 组合逻辑, 多路选择器, 逻辑设计, 硬件描述语言目录 二选一逻辑设计 多路选择逻辑设计 二选一逻辑设计 图片 图片 程序 //二选一逻辑设计 `timescale 1ns/10ps module fn_sw( a, b, sel, y ); input a; input b; input sel; output y; //assign y=sel?(a^b):(a&b); //用always语句块实现组合逻辑; reg y; always@(a or b or sel) if(sel==1)begin y<=a^b; end else begin y<=a&b; end endmodule //---testbench of fn_sw---- module fn_sw_tb; reg a,b,sel;//输入reg型 wire y;//输出wire型 fn_sw fn_sw( .a(a), .b(b), .sel(sel), .y(y) ); initial begin a<=0;b<=0;sel<=0; #10 a<=0;b<=0;sel<=1; #10 a<=0;b<=1;sel<=0; #10 a<=1;b<=0;sel<=0; #10 a<=1;b<=0;sel<=1; #10 a<=1;b<=1;sel<=0; #10 a<=1;b<=1;sel<=1; #10 $stop; end endmodule现象 图片 多路选择逻辑设计 图片 代码 //四选一逻辑设计 `timescale 1ns/10ps module fn_sw_4( a, b, sel, y ); input a; input b; input[1:0] sel; output y; reg y; always@(a or b or sel)begin case(sel) 2'b00:begin y<=a&b;end 2'b01:begin y<=a|b;end 2'b10:begin y<=a^b;end 2'b11:begin y<=~(a^b);end endcase end endmodule //-----testbench of fn_sw_4-- module fn_sw_4_tb; reg[3:0] absel; wire y; fn_sw_4 fn_sw_4( .a(absel[0]), .b(absel[1]), .sel(absel[3:2]), .y(y) ); initial begin absel<=0; #300 $stop; end always #10 absel<=absel+1; endmodule现象 图片
FPGA&ASIC
刘航宇
4年前
0
780
2
2022-05-16
【4】Verilog-基础语法2
摘要本文介绍了Verilog的基础语法,包括表达式、操作数、操作符、算术操作符、关系操作符、等价操作符、逻辑操作符、按位操作符、移位操作符、拼接操作符、条件操作符以及Verilog编译指令。关键词:Verilog, 表达式, 操作符, 编译指令, 按位操作目录 表达式 Verilog 编译指令 表达式 表达式由操作符和操作数构成,其目的是根据操作符的意义得到一个计算结果。表达式可以在出现数值的任何地方使用。例如: a^b ; //a与b进行异或操作 address[9:0] + 10'b1 ; //地址累加 flag1 && flag2 ; //逻辑与操作操作数 操作数可以是任意的数据类型,只是某些特定的语法结构要求使用特定类型的操作数。 操作数可以为常数,整数,实数,线网,寄存器,时间,位选,域选,存储器及函数调用等。 module test; //实数 real a, b, c; c = a + b ; //寄存器 reg [3:0] cprmu_1, cprmu_2 ; always @(posedge clk) begin cprmu_2 = cprmu_1 ^ cprmu_2 ; end //函数 reg flag1 ; flag = calculate_result(A, B); //非法操作数 reg [3:0] res; wire [3:0] temp; always@ (*)begin res = cprmu_2 – cprmu_1 ; //temp = cprmu_2 – cprmu_1 ; //不合法,always块里赋值对象不能是wire型 end endmodule操作符 Verilog 中提供了大约 9 种操作符,分别是算术、关系、等价、逻辑、按位、归约、移位、拼接、条件操作符。 大部分操作符与 C 语言中类似。同类型操作符之间,除条件操作符从右往左关联,其余操作符都是自左向右关联。圆括号内表达式优先执行。例如下面每组的 2 种写法都是等价的。 图片 不同操作符之间,优先级是不同的。下表列出了操作符优先级从高至低的排列顺序。当没有圆括号时,Verilog 会根据操作符优先级对表达式进行计算。为了避免由操作符优先级导致的计算混乱,在不确定优先级时,建议用圆括号将表达式区分开来。 图片 算术操作符 算术操作符包括单目操作符和双目操作符。 双目操作符对 2 个操作数进行算术运算,包括乘()、除(/)、加(+)、减(-)、求幂(*)、取模(%)。 reg [3:0] a, b; reg [4:0] c ; a = 4'b0010 ; b = 4'b1001 ; c = a+b; //结果为c=b'b1011 c = a/b; //结果为c=4,取整如果操作数某一位为 X,则计算结果也会全部出现 X。例如: b = 4'b100x ; c = a+b ; //结果为c=4'bxxxx对变量进行声明时,要根据变量的操作符对变量的位宽进行合理声明,不要让结果溢出。上述例子中,相加的 2 个变量位宽为 4bit,那么结果寄存器变量位宽最少为 5bit。否则,高位将被截断,导致结果高位丢失。无符号数乘法时,结果变量位宽应该为 2 个操作数位宽之和。 reg [3:0] mula ; reg [1:0] mulb; reg [5:0] res ; mula = 4'he ; mulb = 2'h3 ; res = mula * mulb ; //结果为res=6'h2a, 数据结果没有丢失位数 和 - 也可以作为单目操作符来使用,表示操作数的正负性。此类操作符优先级最高。 -4 //表示负4 +3 //表示正3 负数表示时,可以直接在十进制数字前面增加一个减号 -,也可以指定位宽。因为负数使用二进制补码来表示,不指定位宽来表示负数,编译器在转换时,会自动分配位宽,从而导致意想不到的结果。例如: mula = -4'd4 ; mulb = 2 ; res = mula * mulb ; //计算结果为res=-6'd8, 即res=6'h38,正常 res = mula * (-'d4) ; //(4的32次幂-4) * 2, 结果异常关系操作符 关系操作符有大于(>),小于(<),大于等于(>=),小于等于(<=)。 关系操作符的正常结果有 2 种,真(1)或假(0)。 如果操作数中有一位为 x 或 z,则关系表达式的结果为 x 。 A = 4 ; B = 3 ; X = 3'b1xx ; A > B //为真 A <= B //为假 A >= Z //为X,不确定等价操作符 等价操作符包括逻辑相等(==),逻辑不等(!=),全等(===),非全等(!==)。 等价操作符的正常结果有 2 种:为真(1)或假(0)。 逻辑相等/不等操作符不能比较 x 或 z,当操作数包含一个 x 或 z,则结果为不确定值。 全等比较时,如果按位比较有相同的 x 或 z,返回结果也可以为 1,即全等比较可比较 x 或 z。所以,全等比较的结果一定不包含 x。举例如下: A = 4 ; B = 8'h04 ; C = 4'bxxxx ; D = 4'hx ; A == B //为真 A == (B + 1) //为假 A == C //为X,不确定 A === C //为假,返回值为0 C === D //为真,返回值为1逻辑操作符 逻辑操作符主要有 3 个:&&(逻辑与), ||(逻辑或),!(逻辑非)。 逻辑操作符的计算结果是一个 1bit 的值,0 表示假,1 表示真,x 表示不确定。 如果一个操作数不为 0,它等价于逻辑 1;如果一个操作数等于 0,它等价于逻辑 0。如果它任意一位为 x 或 z,它等价于 x。 如果任意一个操作数包含 x,逻辑操作符运算结果不一定为 x。 逻辑操作符的操作数可以为变量,也可以为表达式。例如: A = 3; B = 0; C = 2'b1x ; A && B // 为假 A || B // 为真 ! A // 为假 ! B // 为真 A && C // 为X,不确定 A || C // 为真,因为A为真 (A==2) && (! B) //为真,此时第一个操作数为表达式按位操作符 按位操作符包括:取反(~),与(&),或(|),异或(^),同或(~^)。 按位操作符对 2 个操作数的每 1bit 数据进行按位操作。 如果 2 个操作数位宽不相等,则用 0 向左扩展补充较短的操作数。 取反操作符只有一个操作数,它对操作数的每 1bit 数据进行取反操作。 下图给出了按位操作符的逻辑规则。 图片 A = 4'b0101 ; B = 4'b1001 ; C = 4'bx010 ; ~A //4'b1010 A & B //4'b0001 A | B //4'b1101 A^B //4'b1100 A ~^ B //4'b0011 B | C //4'b1011 B&C //4'bx000移位操作符 移位操作符包括左移(<<),右移(>>),算术左移(<<<),算术右移(>>>)。 移位操作符是双目操作符,两个操作数分别表示要进行移位的向量信号(操作符左侧)与移动的位数(操作符右侧)。 算术左移和逻辑左移时,右边低位会补 0。 逻辑右移时,左边高位会补 0;而算术右移时,左边高位会补充符号位,以保证数据缩小后值的正确性。 A = 4'b1100 ; B = 4'b0010 ; A = A >> 2 ; //结果为 4'b0011 A = A << 1; //结果为 4'b1000 A = A <<< 1 ; //结果为 4'b1000 C = B + (A>>>2); //结果为 2 + (-4/4) = 1, 4'b0001拼接操作符 拼接操作符用大括号 {,} 来表示,用于将多个操作数(向量)拼接成新的操作数(向量),信号间用逗号隔开。 拼接符操作数必须指定位宽,常数的话也需要指定位宽。例如: A = 4'b1010 ; B = 1'b1 ; Y1 = {B, A[3:2], A[0], 4'h3 }; //结果为Y1='b1100_0011 Y2 = {4{B}, 3'd4}; //结果为 Y2=7'b111_1100 Y3 = {32{1'b0}}; //结果为 Y3=32h0,常用作寄存器初始化时匹配位宽的赋初值条件操作符 条件表达式有 3 个操作符,结构描述如下: condition_expression ? true_expression : false_expression 计算时,如果 condition_expression 为真(逻辑值为 1),则运算结果为 true_expression;如果 condition_expression 为假(逻辑值为 0),则计算结果为 false_expression。 assign hsel = (addr[9:8] == 2'b0) ? hsel_p1 : hsel_p2 ; //当信号 addr 高 2bit 为 0 时,hsel 赋值为 hsel_p1; 否则,将 hsel_p2 赋值给 hsel。 其实,条件表达式类似于 2 路(或多路)选择器,其描述方式完全可以用 if-else 语句代替。 当然条件操作符也能进行嵌套,完成一个多次选择的逻辑。例如 assign hsel = (addr[9:8] == 2'b00) ? hsel_p1 : (addr[9:8] == 2'b01) ? hsel_p2 : (addr[9:8] == 2'b10) ? hsel_p3 : (addr[9:8] == 2'b11) ? hsel_p4 ;Verilog 编译指令 以反引号 ` 开始的某些标识符是 Verilog 系统编译指令。 编译指令为 Verilog 代码的撰写、编译、调试等提供了极大的便利。 下面介绍下完整的 8 种编译指令,其中前 4 种使用频率较高。 `define `undef 在编译阶段,`define 用于文本替换,类似于 C 语言中的 #define。 一旦 `define 指令被编译,其在整个编译过程中都会有效。例如,在一个文件中定义: `define DATA_DW 32 则在另一个文件中也可以直接使用 DATA_DW `define S $stop; //用`S来代替系统函数$stop; (包括分号) `define WORD_DEF reg [31:0] //可以用`WORD_DEF来声明32bit寄存器变量`undef 用来取消之前的宏定义,例如 `define DATA_DW 32 …… reg [DATA_DW-1:0] data_in ; …… `undef DATA_DW `ifdef, `ifndef, `elsif, `else, `endif`ifdef MCU51 parameter DATA_DW = 8 ; `elsif WINDOW parameter DATA_DW = 64 ; `else parameter DATA_DW = 32 ; `endif图片 当然,也可用 `ifndef 来设置条件编译,表示如果没有相关的宏定义,则执行相关语句。 下面例子中,如果定义了 WINDOW,则使用第二种参数说明。如果没有定义 WINDOW,则使用第一种参数说明。 `ifndef WINDOW parameter DATA_DW = 32 ; `else parameter DATA_DW = 64 ; `endif`include 使用 `include 可以在编译时将一个 Verilog 文件内嵌到另一个 Verilog 文件中,作用类似于 C 语言中的 #include 结构。该指令通常用于将全局或公用的头文件包含在设计文件里。 文件路径既可以使用相对路径,也可以使用绝对路径。 `include "../../param.v" `include "header.v"`timescale 在 Verilog 模型中,时延有具体的单位时间表述,并用 `timescale 编译指令将时间单位与实际时间相关联。 该指令用于定义时延、仿真的单位和精度,格式为: `timescale time_unit / time_precisiontime_unit 表示时间单位,time_precision 表示时间精度,它们均是由数字以及单位 s(秒),ms(毫秒),us(微妙),ns(纳秒),ps(皮秒)和 fs(飞秒)组成。时间精度可以和时间单位一样,但是时间精度大小不能超过时间单位大小,例如下面例子中,输出端 Z 会延迟 5.21ns 输出 A&B 的结果。 `timescale 1ns/100ps //时间单位为1ns,精度为100ps,合法 //`timescale 100ps/1ns //不合法 module AndFunc(Z, A, B); output Z; input A, B ; assign #5.207 Z = A & B endmodule图片 `timescale 10ns/1ns module test; reg A, B ; wire OUTZ ; initial begin A = 1; B = 0; # 1.28 B = 1; # 3.1 A = 0; end AndFunc u_and(OUTZ, A, B) ; endmodule在模块 AndFunc 中,5.207 对应 5.21ns。 在模块 test 中,1.28 对应 13ns,3.1 对应 31ns。 但是,当仿真 test 时,由于 AndFunc 中的最小精度为 100ps,因此 test 中的时延精度将进行重新调整。13ns 将对应 130100ps,31ns 将对应 310100ps。仿真时,时延精度也会使用 100ps。仿真时间单位大小没有影响。 如果有并行子模块,子模块间的 `timescale 并不会相互影响。 例如在模块 test 中再例化一个子模块 OrFunc。仿真 test 时,OrFunc 中的 #5.207 延时依然对应 52ns。 //子模块: `timescale 10ns/1ns //时间单位为1ns,精度为100ps,合法 module OrFunc(Z, A, B); output Z; input A, B ; assign #5.207 Z = A | B endmodule //顶层模块: `timescale 10ns/1ns module test; reg A, B ; wire OUTZ ; wire OUTX ; initial begin A = 1; B = 0; # 1.28 B = 1; # 3.1 A = 0; end AndFunc u_and(OUTZ, A, B) ; OrFunc u_and(OUTX, A, B) ; endmodule此例中,仿真 test 时,OrFunc 中的 #5.207 延时依然对应 52ns。 `timescale 的时间精度设置是会影响仿真时间的。时间精度越小,仿真时占用内存越多,实际使用的仿真时间就越长。所以如果没有必要,应尽量将时间精度设置的大一些。 `default_nettype 该指令用于为隐式的线网变量指定为线网类型,即将没有被声明的连线定义为线网类型。 `default_nettype wand该实例定义的缺省的线网为线与类型。因此,如果在此指令后面的任何模块中的连线没有说明,那么该线网被假定为线与类型。 `default_nettype none该实例定义后,将不再自动产生 wire 型变量。 例如下面第一种写法编译时不会报 Error,第二种写法编译将不会通过。 //Z1 无定义就使用,系统默认Z1为wire型变量,有 Warning 无 Error module test_and( input A, input B, output Z); assign Z1 = A & B ; endmodule//Z1无定义就使用,由于编译指令的存在,系统会报Error,从而检查出书写错误 `default_nettype none module test_and( input A, input B, output Z); assign Z1 = A & B ; endmodule图片 `celldefine module ( input clk, input rst, output clk_pll, output flag); …… endmodule `endcelldefine图片
FPGA&ASIC
刘航宇
4年前
0
1,228
1
【1】Verilog练习-基本门电路反相器&与非门
摘要本文介绍了Verilog语言中基本门电路的设计,包括反相器和与非门,并提供了相应的代码示例和测试用例。通过这些示例,读者可以了解如何使用Verilog实现基本的逻辑门电路。关键词:Verilog, 反相器, 与非门, 代码示例, 电路设计目录 反相器 多位反相器 与非门 多位与非门 反相器 图片 //反相器设计 `timescale 1ns/10ps //1ns时间单位,10ps精度 module inv( A, Y ); input A; output Y; assign Y=~A; endmodule //---testbench of inv-- module inv_tb; //testbench无端口不写括号 reg aa; //输入 wire yy; //输出 inv inv( .A(aa), .Y(yy) ); //异名例化 initial begin aa<=0; #10 aa<=1; //过10个时间单位timescale #10 aa<=0; #10 aa<=1; #10 $stop; end endmodule现象: 图片 多位反相器 图片 与非门 l378lznf.png图片 代码 //与非门 `timescale 1ns/10ps module nand_gate( A, B, Y ); input A; input B; output Y; assign Y=~(A&B); endmodule //------testbench of nand_gate-- module nand_gate_tb; reg aa,bb; //输入定义为reg wire yy; nand_gate nand_gate( .A(aa), .B(bb), .Y(yy) ); initial begin aa<=0;bb<=0; //用箭头等号对应实际电路 #10 aa<=1;bb<=1; #10 aa<=0;bb<=1; #10 aa<=1;bb<=0; #10 aa<=0;bb<=0; #10 $stop; end endmodule现象 l379jg44.png图片 多位与非门 l379koe9.png图片 代码 //与非门 `timescale 1ns/10ps module nand_gate_4bits( A, B, Y ); input[3:0] A; input[3:0] B; output[3:0] Y; assign Y=~(A&B); endmodule //------testbench of nand_gate-- module nand_gate_4bits_tb; reg[3:0] aa,bb; //输入定义为reg wire[3:0] yy; nand_gate_4bits nand_gate_4bits( .A(aa), .B(bb), .Y(yy) ); initial begin aa<=4'b0000;bb<=4'b1111; //用箭头等号对应实际电路 #10 aa<=4'b1110;bb<=4'b0011; #10 aa<=4'b0110;bb<=4'b0111; #10 aa<=4'b0111;bb<=4'b1110; #10 aa<=4'b1101;bb<=4'b1111; #10 $stop; end endmodulel379uc5u.png图片
FPGA&ASIC
刘航宇
4年前
0
725
2
2022-05-14
【3】Verilog-基础语法1
摘要本文介绍了Verilog的基础语法,包括标识符与关键字、数值种类、数据类型(如线网、寄存器、向量、整数、实数、时间、数组、存储器、参数和字符串)等,为Verilog编程提供了基础。关键词:Verilog, 语法基础, 标识符, 关键字, 数据类型目录 标识符与关键字 数值种类字符串表示方法 Verilog 数据类型 标识符与关键字 标识符(identifier)可以是任意一组字母、数字、$ 符号和 _(下划线)符号的合,但标识符的第一个字符必须是字母或者下划线,不能以数字或者美元符开始。 另外,标识符是区分大小写的。 关键字是 Verilog 中预留的用于定义语言结构的特殊标识符。 Verilog 中关键字全部为小写。 reg [3:0] counter ; //reg 为关键字, counter 为标识符 input clk; //input 为关键字,clk 为标识符 input CLK; //CLK 与 clk是 2 个不同的标识符数值种类 Verilog HDL 有下列四种基本的值来表示硬件电路中的电平逻辑: 0:逻辑 0 或 "假" 1:逻辑 1 或 "真" x 或 X:未知 z 或 Z:高阻 x 意味着信号数值的不确定,即在实际电路里,信号可能为 1,也可能为 0。 z 意味着信号处于高阻状态,常见于信号(input, reg)没有驱动时的逻辑结果。例如一个 pad 的 input 呈现高阻状态时,其逻辑值和上下拉的状态有关系。上拉则逻辑值为 1,下拉则为 0 。 整数数值表示方法 数字声明时,合法的基数格式有 4 中,包括:十进制('d 或 'D),十六进制('h 或 'H),二进制('b 或 'B),八进制('o 或 'O)。数值可指明位宽,也可不指明位宽。 指明位宽 4'b1011 // 4bit 数值 32'h3022_c0de // 32bit 的数值其中,下划线 _ 是为了增强代码的可读性。 不指明位宽 一般直接写数字时,默认为十进制表示,例如下面的 3 种写法是等效的: counter = 'd100 ; //一般会根据编译器自动分频位宽,常见的为32bit counter = 100 ; counter = 32'h64 ;负数表示 通常在表示位宽的数字前面加一个减号来表示负数。例如 -6'd15 -15-15 在 5 位二进制中的形式为 5'b10001, 在 6 位二进制中的形式为 6'b11_0001。 需要注意的是,减号放在基数和数字之间是非法的,例如下面的表示方法是错误的: 4'd-2 //非法说明实数表示方法 实数表示方法主要有两种方式: 十进制 30.123 6.0 3.0 0.001 科学计数法 1.2e4 //大小为12000 1_0001e4 //大小为100010000 1E-3 //大小为0.001 字符串表示方法 字符串是由双引号包起来的字符队列。字符串不能多行书写,即字符串中不能包含回车符。Verilog 将字符串当做一系列的单字节 ASCII 字符队列。例如,为存储字符串 "ee.ac.cn", 需要 14*8bit 的存储单元。例如: reg [0: 14*8-1] str ; initial begin str = "ee.ac.cn"; end Verilog 数据类型 Verilog 最常用的 2 种数据类型就是线网(wire)与寄存器(reg),其余类型可以理解为这两种数据类型的扩展或辅助。 线网(wire) wire 类型表示硬件单元之间的物理连线,由其连接的器件输出端连续驱动。如果没有驱动元件连接到 wire 型变量,缺省值一般为 "Z"。举例如下: wire interrupt ; wire flag1, flag2 ; wire gnd = 1'b0 ;线网型还有其他数据类型,包括 wand,wor,wri,triand,trior,trireg 等。这些数据类型用的频率不是很高,这里不做介绍。 寄存器(reg) 寄存器(reg)用来表示存储单元,它会保持数据原有的值,直到被改写。声明举例如下: reg clk_temp; reg flag1, flag2 ;例如在 always 块中,寄存器可能被综合成边沿触发器,在组合逻辑中可能被综合成 wire 型变量。寄存器不需要驱动源,也不一定需要时钟信号。在仿真时,寄存器的值可在任意时刻通过赋值操作进行改写。例如: reg rstn ; initial begin rstn = 1'b0 ; #100 ; //延时 rstn = 1'b1 ; end向量 当位宽大于 1 时,wire 或 reg 即可声明为向量的形式。例如: reg [3:0] counter ; //声明4bit位宽的寄存器counter wire [32-1:0] gpio_data; //声明32bit位宽的线型变量gpio_data wire [8:2] addr ; //声明7bit位宽的线型变量addr,位宽范围为8:2 reg [0:31] data ; //声明32bit位宽的寄存器变量data, 最高有效位为0对于上面的向量,我们可以指定某一位或若干相邻位,作为其他逻辑使用。例如: wire [9:0] data_low = data[0:9] ; addr_temp[3:2] = addr[8:7] + 1'b1 ;Verilog 支持可变的向量域选择,例如: reg [31:0] data1 ; reg [7:0] byte1 [3:0]; integer j ; always@* begin for (j=0; j<=3;j=j+1) begin byte1[j] = data1[(j+1)*8-1 : j*8]; //把data1[7:0]…data1[31:24]依次赋值给byte1[0][7:0]…byte[3][7:0] end endVerillog 还支持指定 bit 位后固定位宽的向量域选择访问。 [bit+: width] : 从起始 bit 位开始递增,位宽为 width。 [bit-: width] : 从起始 bit 位开始递减,位宽为 width。 //下面 2 种赋值是等效的 A = data1[31-: 8] ; A = data1[31:24] ; //下面 2 种赋值是等效的 B = data1[0+ : 8] ; B = data1[0:7] ;对信号重新进行组合成新的向量时,需要借助大括号。例如: wire [31:0] temp1, temp2 ; assign temp1 = {byte1[0][7:0], data1[31:8]}; //数据拼接 assign temp2 = {32{1'b0}}; //赋值32位的数值0 整数,实数,时间寄存器变量 整数,实数,时间等数据类型实际也属于寄存器类型。 整数(integer) 整数类型用关键字 integer 来声明。声明时不用指明位宽,位宽和编译器有关,一般为32 bit。reg 型变量为无符号数,而 integer 型变量为有符号数。例如: reg [31:0] data1 ; reg [3:0] byte1 [7:0]; //数组变量,后续介绍 integer j ; //整型变量,用来辅助生成数字电路 always@* begin for (j=0; j<=3;j=j+1) begin byte1[j] = data1[(j+1)*8-1 : j*8]; //把data1[7:0]…data1[31:24]依次赋值给byte1[0][7:0]…byte[3][7:0] end end此例中,integer 信号 j 作为辅助信号,将 data1 的数据依次赋值给数组 byte1。综合后实际电路里并没有 j 这个信号,j 只是辅助生成相应的硬件电路。 实数(real) 实数用关键字 real 来声明,可用十进制或科学计数法来表示。实数声明不能带有范围,默认值为 0。如果将一个实数赋值给一个整数,则只有实数的整数部分会赋值给整数。例如: real data1 ; integer temp ; initial begin data1 = 2e3 ; data1 = 3.75 ; end initial begin temp = data1 ; //temp 值的大小为3 end时间(time) Verilog 使用特殊的时间寄存器 time 型变量,对仿真时间进行保存。其宽度一般为 64 bit,通过调用系统函数 $time 获取当前仿真时间。例如: time current_time ; initial begin #100 ; current_time = $time ; //current_time 的大小为 100 end数组 在 Verilog 中允许声明 reg, wire, integer, time, real 及其向量类型的数组。 数组维数没有限制。线网数组也可以用于连接实例模块的端口。数组中的每个元素都可以作为一个标量或者向量,以同样的方式来使用,形如:<数组名>[<下标>]。对于多维数组来讲,用户需要说明其每一维的索引。例如: integer flag [7:0] ; //8个整数组成的数组 reg [3:0] counter [3:0] ; //由4个4bit计数器组成的数组 wire [7:0] addr_bus [3:0] ; //由4个8bit wire型变量组成的数组 wire data_bit[7:0][5:0] ; //声明1bit wire型变量的二维数组 reg [31:0] data_4d[11:0][3:0][3:0][255:0] ; //声明4维的32bit数据变量数组下面显示了对数组元素的赋值操作: flag [1] = 32'd0 ; //将flag数组中第二个元素赋值为32bit的0值 counter[3] = 4'hF ; //将数组counter中第4个元素的值赋值为4bit 十六进制数F,等效于counter[3][3:0] = 4'hF,即可省略宽度; assign addr_bus[0] = 8'b0 ; //将数组addr_bus中第一个元素的值赋值为0 assign data_bit[0][1] = 1'b1; //将数组data_bit的第1行第2列的元素赋值为1,这里不能省略第二个访问标号,即 assign data_bit[0] = 1'b1; 是非法的。 data_4d[0][0][0][0][15:0] = 15'd3 ; //将数组data_4d中标号为[0][0][0][0]的寄存器单元的15~0bit赋值为3虽然数组与向量的访问方式在一定程度上类似,但不要将向量和数组混淆。向量是一个单独的元件,位宽为 n;数组由多个元件组成,其中每个元件的位宽为 n 或 1。它们在结构的定义上就有所区别。 存储器 存储器变量就是一种寄存器数组,可用来描述 RAM 或 ROM 的行为。例如: reg membit[0:255] ; //256bit的1bit存储器 reg [7:0] mem[0:1023] ; //1Kbyte存储器,位宽8bit mem[511] = 8'b0 ; //令第512个8bit的存储单元值为0参数 参数用来表示常量,用关键字 parameter 声明,只能赋值一次。例如: parameter data_width = 10'd32 ; parameter i=1, j=2, k=3 ; parameter mem_size = data_width * 10 ;但是,通过实例化的方式,可以更改参数在模块中的值。此部分以后会介绍。 局部参数用 localparam 来声明,其作用和用法与 parameter 相同,区别在于它的值不能被改变。所以当参数只在本模块中调用时,可用 localparam 来说明。 字符串 字符串保存在 reg 类型的变量中,每个字符占用一个字节(8bit)。因此寄存器变量的宽度应该足够大,以保证不会溢出。 字符串不能多行书写,即字符串中不能包含回车符。如果寄存器变量的宽度大于字符串的大小,则使用 0 来填充左边的空余位;如果寄存器变量的宽度小于字符串大小,则会截去字符串左边多余的数据。例如,为存储字符串 "ee.ac.cn", 需要 14*8bit 的存储单元: reg [0: 14*8-1] str ; initial begin str = "ee.ac.cn"; end 有一些特殊字符在显示字符串中有特殊意义,例如换行符,制表符等。如果需要在字符串中显示这些特殊的字符,则需要在前面加前缀转义字符 \ 。例如下表所示: 图片 其实,在 SystemVerilog(主要用于 Verilog 仿真的编程语言)语言中,已经可以直接用关键字 string 来表示字符串变量类型,这为 Verilog 的仿真带来了极大的便利。有兴趣的学者可以简单学习下 SystemVerilog。
FPGA&ASIC
刘航宇
4年前
0
1,474
2
2022-05-14
【2】Verilog-项目设计方法
摘要Verilog设计采用自上而下方法,先定义顶层模块,再分解设计至底层功能块。设计流程包括需求分析、功能划分、文本描述、功能仿真、逻辑综合、布局布线、时序仿真,最后下载至FPGA/CPLD或制造ASIC芯片。关键词:Verilog, 设计方法, 顶层模块, 逻辑综合, 时序仿真目录 设计方法 设计流程需求分析 功能划分 文本描述 功能仿真(前仿真) 逻辑综合 布局布线 时序仿真(后仿真) FPGA/CPLD 下载或 ASIC 制造工艺生产 设计方法 Verilog 的设计多采用自上而下的设计方法(top-down)。即先定义顶层模块功能,进而分析要构成顶层模块的必要子模块;然后进一步对各个模块进行分解、设计,直到到达无法进一步分解的底层功能块。这样,可以把一个较大的系统,细化成多个小系统,从时间、工作量上分配给更多的人员去设计,从而提高了设计速度,缩短了开发周期。 l35lheq6.png图片 设计流程 l35ligw8.png图片 Verilog 的设计流程,一般包括以下几个步骤: 需求分析 工作人员需要对用户提出的功能要求进行分析理解,做出电路系统的整体规划,形成详细的技术指标,确定初步方案。例如,要设计一个电子屏,需要考虑供电方式、工作频率、产品体积、成本、功耗等,电路实现采用 ASIC 还是选用 FPGA/CPLD 器件等。 功能划分 正确地分析了用户的电路需求后,就可以进行逻辑功能的总体设计,设计整个电路的功能、接口和总体结构,考虑功能模块的划分和设计思路,各子模块的接口和时序(包括接口时序和内部信号的时序)等,向项目组成员合理分配子模块设计任务。 文本描述 可以用任意的文本编辑器,也可以用专用的 HDL 编辑环境,对所需求的数字电路进行设计建模,保存为 .v 文件。 功能仿真(前仿真) 对建模文件进行编译,对模型电路进行功能上的仿真验证,查找设计的错误并修正。 此时的仿真验证并没有考虑到信号的延迟等一些 timing 因素,只是验证逻辑上的正确性。 逻辑综合 综合(synthesize),就是在标准单元库和特定的设计约束的基础上,将设计的高层次描述(Verilog 建模)转换为门级网表的过程。逻辑综合的目的是产生物理电路门级结构,并在逻辑、时序上进行一定程度的优化,寻求逻辑、面积、功耗的平衡,增强电路的可测试性。 但不是所有的 Verilog 语句都是可以综合成逻辑单元的,例如时延语句。 布局布线 根据逻辑综合出的网表与约束文件,利用厂家提供的各种基本标准单元库,对门级电路进行布局布线。至此,已经将 Verilog 设计的数字电路,设计成由标准单元库组成的数字电路。 时序仿真(后仿真) 布局布线后,电路模型中已经包含了时延信息。利用在布局布线中获得的精确参数,用仿真软件验证电路的时序。单元器件的不同、布局布线方案都会给电路的时序造成影响,严重时会出现错误。出错后可能就需要重新修改 RTL(寄存器传输级描述,即 Verilog 初版描述),重复后面的步骤。这样的过程可能反复多次,直至错误完全排除。 FPGA/CPLD 下载或 ASIC 制造工艺生产 完成上面所有步骤后,就可以通过开发工具将设计的数字电路目标文件下载到 FPGA/CPLD 芯片中,然后在电路板上进行调试、验证。 如果要在 ASIC 上实现,则需要制造芯片。一般芯片制造时,也需要先在 FPGA 板卡上进行逻辑功能的验证。
FPGA&ASIC
刘航宇
4年前
0
378
1
上一页
1
...
4
5
6
下一页