官方视频: 04-第四讲-初识Verilog_哔哩哔哩_bilibili
- 引脚状态:0(0 或 假)、1(1 或 真)、x/X(未知)、z/Z(高阻)
-
- 输入 input wire //是bool类型,用于去绑定FPGA的引脚
- input wire[7:0] //是byte类型
-
- 输出 output wire //是bool类型
- output wire[7:0] //是byte类型
-
- 电线 wire //导线 wire[0:0]一根导线
- wire[7:0]八根电线
-
- 寄存器 reg // bool类型的寄存器
- reg[63:0] // long类型的寄存器,64bit
-
- 使用always和initial语句时一定是reg型,使用assign时一定是wire型
-
- 指定bit num[7:4] // 8bit取高4位
-
- 上升沿 posedge
- 下降沿 negedge
-
- 局部参数 parameter 定义的是局部参数,所以只在本模块中有效。
- 初始化 initial begin 、、、、end 上电只独立运行一次【只用于测试平台】
-
- 时序逻辑 always【右侧为 run运行条件】 //如 always@(*)这个(*)表示模块内任一引脚变化都true
- @表示时序触发,由晶振时钟事件
-
- 副本世界 begin //在仿真中 begin...end 块中的内容都是顺序执行的
-
- 硬件流 assign //硬件流不受晶振时钟控制,由硬件逻辑门直接给出结果。【组合逻辑】
- //===A=====================
- module io_def( );// 最小的程序,只有名字,没参数,没方法体
-
- endmodule
-
- //===B=====================
- module io_def(input FPGA_CLK_50M_b5,input key1_k18,input key2_n17 );// 名字,参数,没方法体
-
- endmodule
-
- 因为参数太多,会一行写不下,所以改用以下写法
- module io_def // 模块名字,参数,没方法体
- (
- input FPGA_CLK_50M_b5,
- input key1_k18,
- input key2_n17,
- input key3_n18,
- input key4_h17,
- //
- output led1_d15,
- output led2_c15,
- output led3_a12,
- output led4_b12,
-
- output beep_h13 //【注】最后一个参数不加逗号
- );
-
- endmodule
-
- //===C=====================
- module io_def // 模块名字,参数,方法体
- (
- input FPGA_CLK_50M_b5,
- input key1_k18,
- input key2_n17,
- input key3_n18,
- input key4_h17,
- //
- output led1_d15,
- output led2_c15,
- output led3_a12,
- output led4_b12,
-
- output beep_h13 //【注】最后一个参数不加逗号
- );
- //【】以下是方法体,FPGA的特性是程序都是并联运行。
- assign led1_d15 = ~key1_k18; //程序1
- assign led2_c15 = ~key2_n17; //程序2
- assign led3_a12 = ~key3_n18; //程序3
- assign led4_b12 = FPGA_CLK_50M_b5; //程序4
-
- endmodule
程序下载后,可以看到LED4是微亮,因为晶振是50MHz的,同时按3个按钮对应3个灯,并不会出现单片机那样,因为程序没运行到那,按键没反应。
看下LED3显示1秒亮1次的程序
- //======================================================
- module io_def // 模块名字,参数,方法体
- (
- input FPGA_CLK_50M_b5,
- input key1_k18,
- input key2_n17,
- input key3_n18,
- input key4_h17,
- //
- output led1_d15,
- output led2_c15,
- output reg led3_a12,
- output led4_b12,
-
- output beep_h13 //【注】最后一个参数不加逗号
- );
- //【】以下是变量
- reg a;
- reg[31:0] b;
-
-
- //【】以下是方法体,FPGA的特性是程序都是并联运行。
- assign led1_d15 = ~key1_k18; //程序1
- assign led2_c15 = ~key2_n17; //程序2
- // assign led3_a12 = ~key3_n18; //程序3
- assign led4_b12 = FPGA_CLK_50M_b5; //程序4
-
- //【】以下是时序方法体
- always@(posedge FPGA_CLK_50M_b5) //【死循环】@敏感【触发条件:上升沿 clk】【运行副本】
- if(b==49_999_999)begin //50Mhz晶振, 49_999_999 是 1秒1次
- b<=0;
- a <= ~a;
- led3_a12 <= a;
- end
- else
- b<=b+1;
-
- endmodule
跟C语言里,函数调用函数一样。
- 设计时分2步:
- 【1】先设计功能块,类似PLC的FB功能块。
- 【2】在测试平台调用FB功能块,调用功能块前,需要先实例化FB功能块。
- 下载程序:下载的是测试平台的程序。
-
- 就像乐高积木,先设计积木的元素,使用的时候,实例化这些积木元素,再拼装成如发动机【测试平台】,
- 最后下载【测试平台】的程序。
-
- //=====================================
- //跟C语言的函数写法一样
- module FB ( 参数1,参数2,参数n);
- FB内部变量1;
- FB内部变量2;
- FB内部变量n;
-
- FB内部方法1; // assign逻辑门
- FB内部方法2; // always时序程序
- FB内部变量n;
- endmodule
-
- //=====================================
- // 调用的时候也是一个同样的方法
- `timescale 1ns/1ns //晶振时钟【节拍】,后面可以用#1000// 1us做延时触发信号
- module tb_FB(); //方法调用方法,所以这个位置的方法不需要参数
- tb_FB内部变量A; //这个位置准备需要的变量
- tb_FB内部变量B;
- tb_FB内部变量N;
-
- //实例化一个FB,叫FB_test,并给新对象赋参数。
- FB FB_test(.参数1(A),.参数2(B),.参数n(N));// 【相当于引脚绑定】
- tb_FB内部方法1; // assign逻辑门
- tb_FB内部方法2; // always时序程序
- tb_FB内部变量n; // 这些方法都是并联运行的程序
- endmodule
- 程序有2种:【1】always 经过晶振时钟运行的程序。由()括号内表达式True时,运行。【时序逻辑】
- 【2】assign 由硬件逻辑门输出结果。不受时间约束【组合逻辑】
-
- //=====测试程序==============================
- `timescale 1ns/1ns //晶振时钟【节拍】
-
- 这里添参数声明和初始化initial等。。。。。
-
- always #10 //触发条件是 10ns后运行
- 这里添加程序1
-
- always @(posedge sys_clk or negedge sys_rst_n) // 运行的触发条件【上升沿sys_clk 】
- 这里添加程序2 或 【下降沿sys_rst_n 】
-
- 这里还可以添加你想要的程序。。。。。
-
- //=====并联程序==============================
- assign out = (sel == 1'b1) ? in1 : in2; //不受时间约束,硬件逻辑门直接给出结果
-
- Verilog 里面变量不叫变量,叫信号。
- 信号分两类: line 和 buffer。 对应组合逻辑和时序逻辑。要想保存状态,就得用时序逻辑。
-
- Verilog里面所有变量跟时钟对齐。所以Verilog代码本质是并行运行的。 各信号之间只跟时钟对齐。
- //=================================================
- wire表示连续信号,【线网型:表示电路间的物理连接; 】
- 在 assign【分配】 语句中assign out = (a & b) | (c & d);
- 在verilog中,wire [15:0] d; 和wire [0:15] d; 的区别在于它们的位顺序不同。
- wire [15:0] d; 表示d是一个16位的wire,其中最高位是d[15],最低位是d;
- 而wire [0:15] d; 表示d是一个16位的wire,其中最高位是d,最低位是d[15]。
- 因此,它们的位顺序是相反的。在使用时需要根据实际情况选择合适的位顺序。
- //=================================================
- reg表示寄存器变量,时序信号。左侧有 always【死循环】 或initial【开始的】
- 示例代码:
- always @(posedge clk) begin //【死循环】@敏感【触发条件:上升沿 clk】【运行副本】
-
- if (reset) begin //【如果 reset】【运行副本】
-
- counter <= 0; // 【计数器counter 非阻塞赋值为 0】,下个晶振上升沿赋值0
-
- end else begin
-
- counter <= counter + 1;
-
- end
-
- end
-
-
有二进制,八进制,十进制,十六进制,字符串
- `b 表示二进制
- `o 表示八进制
- `d 表示十进制
- `h 表示十六进制
- //===============================
- 语法:
- A`BC
- A是数子,表示bit长度
- `B表示进制类型,`b二进制,`o八进制,`d十进制,`h十六进制。
- C表示数值
- //===============================
- 8`表示占用8个bit
- 16`表示占用16bit长度
- _下划线编译器是忽略的。可以提高我们阅读性。
-
- 8`b000_1111; //总长8bit, 二进制 2#00001111,就是0x0F
-
- 8`o12345670; //总长才8个bit的八进制,所以这个值是会被溢出的。
-
- 8`d1234567890; //直接写 16 表示位宽为 32bit 的十进制数 16;
-
- // -15 表示十进制的-15,用二进制补码表示至少需要 5bit,即 1_0001,
- //最高一位为符号位;如果用 6bit 表示,则为 11_0001,
- //同样最高一位为符号位。
-
-
- 32`haaaa_ffff; // 32bit长度的0xaaaaFFFF;
-
-
- //字符串表示方法:需要定义相应大小的存储单元,
- //比如字符串"www.csdn.net"需要12*8bit的存储单元,代码如下:
- reg [12*8-1:0] str; // 12*8-1
- assign str = "www.csdn.net";
-
-
- bdOh// 二进制,十进制,八进制,十六进制
- 二进制
- 8'b0000_1111 //8表示总bit长度,下划线编译器是忽略的。可提高阅读性
-
- 八进制
- 16'o253 //16bit长度,八进制值253
-
- 十进制
- 25'd24 //25bit长度,值24
-
- 十六进制
- 32'haaaa_ffff //表示0xaaaaFFFF
- wire表示连续信号,【硬件连线】
- reg表示时序信号。 【寄存器】
-
- 在Verilog中,最常用的两种数据类型是线网(wire)和寄存器(reg)。除此之外,还有以下几种数据类型:
- 1. 整数类型(integer):用于表示整数值。 0xFFFF
- 2. 实数类型(real):用于表示实数值。 3.1415926
- 3. 时间类型(time):用于表示时间值。
- 4. 参数类型(parameter):用于表示常量值。 parameter IDLE = 3'b001;
- 5. 局部参数类型(localparam):用于表示模块内部的常量值。
- 6. 枚举类型(enum):用于表示一组命名的常量值。
- 除了以上常用的数据类型,还有一些其他的数据类型,
- 如结构体(struct)、联合体(union)等,但使用频率较低。
- Verilog 的内部信号名(又称标识符)使用大写和小写都可以。
- 标识符可以是字母、数字、$(美元符号)和下划线的任意组合,
- 只要第一个字符是字母或者下划线即可。
-
- 标识符区分大小写的。
- _ 编译器忽略【下划线】的,添加在二进制里可以提高我们阅读性
- // 单行注释
- /* 可以多行注释 */
-
- ` 这个esc键帽下的【反撇】是预处理的意思,和C语言的#一样, #define #include
-
- @ 表示时间控制,用于指定模块中的事件发生时间。或者说右侧括号内是敏感事件
- 括号内就是触发条件, always @(*)表示是这个alway块的内容中出现的所有的变量,
- 只要这些变量发生变化这个always块儿就会被触发。这种立即触发的逻辑电路实事上也
- 就是组合逻辑电路。
-
- $ 符号表示系统任务,用于执行一些系统级别的任务,例如打印输出、延时等。
-
- # 传递参数或延时的作用。
- 在例化的时候起传递参数的作用,
- 在always #20 clk = ~clk;是延时20个晶振时钟事件后,clk翻转
-
- = 阻塞赋值,不受晶振时钟约束,由逻辑门直接给出结果
- <= 非阻塞赋值 受晶振时钟控制赋值
-
- +: 变量[起始地址 +: 数据位宽] <–等价于–> 变量[(起始地址+数据位宽-1):起始地址]
-
- {} 拼接或复制的作用。
- { }表示拼接,{第一位,第二位…};
- {{ }}表示复制,{4{a}}等同于{a,a,a,a};
-
- 算术运算符 +、-、*、/、%
- 位运算符 &、|、^、~、<<、>>
- 比较运算符 ==、!=、<、<=、>、>=
- 逻辑运算符 &&、||、!
- 条件运算符 ?:
-
- // 可以实现对一行的注释,
- /*......*/ 多行注释
-
- <小于
- >大于
- <=小于等于
- >=大于或者等于
-
- //当“&”作为一元运算符时表示归约与。&m是将m中所有比特相与,
- 最后的结果为1bit。
- & 与运算
- &4’b1111 = 1&1&1&1 = 1’b1
- &4’b1101 = 1&1&0&1 = 1’b0
-
- 4’b1010&4’b0101 = 4’b0000
- 4’b1101&4’b1111 = 4’b1101
-
- “~&”、“^”、“~^”、“|”、“~|”同理。
- “||”、“= =(逻辑相等)”、“!=(逻辑不等)”同理。
-
- “<<” 左移
- “>>” 右移
- “ ? : ”,它是一个三元运算符
-
- “= =”
- “!=”
- “&&”
- “||”
- 位拼接运算符由一对花括号加逗号组成“{ , }”
-
- Verilog中的特殊符号及其用法如下:
- 1. & :按位与运算符
- 2. | :按位或运算符
- 3. ^ :按位异或运算符
- 4. ~ :按位取反运算符
- 5. << :左移运算符
- 6. >> :右移运算符
- 7. + :加法运算符
- 8. - :减法运算符
- 9. * :乘法运算符
- 10. / :除法运算符
- 11. % :取模运算符
- 12. == :等于运算符
- 13. != :不等于运算符
- 14. < :小于运算符
- 15. > :大于运算符
- 16. <= :小于等于运算符
- 17. >= :大于等于运算符
- 18. && :逻辑与运算符
- 19. || :逻辑或运算符
- 20. ! :逻辑非运算符
- 21. & :位与运算符
- 22. | :位或运算符
- 23. ^ :位异或运算符
- 24. ~ :位取反运算符
- 25. ?: :条件运算符
- 26. {} :括号运算符
- 27. [] :数组下标运算符
- 28. . :结构体成员运算符
- 29. $ :系统任务运算符
-
- --相关问题--:
- 1. Verilog中的常用数据类型有哪些?
- 2. Verilog中的模块有哪些类型?
- 3.
- Verilog中,系统函数是一些内置的函数,可以直接使用,无需定义。
- 下面是一些常用的系统函数及其用法:
-
- 1. $display:用于在仿真过程中输出信息,类似于C语言中的printf函数。用法示例:$display("The value of A is %d", A);
-
- 2. $monitor:用于监视变量的值,当变量的值发生变化时,会自动输出信息。用法示例:$monitor("The value of A is %d", A);
-
- 3. $time:用于获取仿真时间,单位为时钟周期。用法示例:$display("The current simulation time is %d", $time);
-
- 4. $random:用于生成随机数。用法示例:B = $random;
-
- 5. $finish:用于结束仿真过程。用法示例:$finish;
-
- 6. $stop:用于暂停仿真过程。用法示例:$stop;
-
- 7. $readmemb:用于从文件中读取二进制数据。用法示例:$readmemb("filename", memory);
-
- 8. $readmemh:用于从文件中读取十六进制数据。用法示例:$readmemh("filename", memory);
-
- 9. $timeformat:用于设置仿真时间的格式。用法示例:$timeformat(-9, 2, "ns", 10);
-
-
-
- `timescale 1ns/10ps 精度 0.01,#10.11 表示延时 10110ps。 【用于测试平台】
-
- $display //打印信息,自动换行
- $write //打印信息
- $strobe //打印信息,自动换行,最后执行
-
- $monitor //监测变量
- //只要监测的变量(时间、in1, in2, sel, out)发生变化,就会打印出相应的信息
- $monitor("@time %t:in1=%b in2=%b sel=%b out=%b",$time,in1,in2,sel,out);
-
- $stop //暂停仿真
- $finish //结束仿真
-
- $time //时间函数
-
- $random //随机函数
-
- $readmemb //读文件函数
-
- $timeformat(-9, 0, "ns", 6);//设置显示的时间格式,此处表示的是(打印时间单
- //位为纳秒,小数点后打印的小数位为 0 位,时间值
- //后打印的字符串为“ns”,打印的最小数量字符为 6 个)
-
- -9是10的负9次方,是纳秒;
- 0是小数点后面保留几位
- “ns”纳秒
- 6是最短字符串长度
- Verilog是一种硬件描述语言,其中有许多关键字用于组织语言结构。
- 下面是Verilog HDL中使用的关键词,这些保留字是识别语法的关键,
- Verilog一共103个关键字,按照字母顺序排列依次如下:
-
- always、and、assign、automatic、
- begin、buf、bufif0、bufif1、
- case、casex、casez、cell、cmos、config、
- deassign、default、defparam、design、disable、
- edge、else、end、endcase、endconfig、endfunction、endgenerate、endmodule、endprimitive、endspecify、endtable、endtask、event、
- for、force、forever、fork、function、
- generate、genvar、
- highz0、highz1、
- if、ifnone、incdir、include、initial、inout、input、instance、integer、
- join、
- large、liblist、library、localparam、
- macromodule、medium、module、
- nand、negedge、nmos、nor、not、notif0、notif1、
- or、output、
- parameter、pmos、posedge、primitive、pull0、pull1、pulldown、pullup、
- rcmos、real、realtime、reg、release、repeat、rnmos、rpmos、rtran、rtranif0、rtranif1、scalared、small、specify、specparam、strong0、strong1、supply0、supply1、
- table、task、time、tran、tranif0、tranif1、tri、tri0、tri1、triand、trior、trireg、
- vectored、
- wait、wand、weak0、weak1、while、wire、wor、
- xnor、xor。
-
- 这些关键字的具体用法和作用可以根据需要在Verilog的相关文献中查找。
2、常用关键字
关键字 含义
module 模块开始定义
input 输入端口定义
output 输出端口定义
inout 双向端口定义
parameter 信号的参数定义
wire wire信号定义
reg reg信号定义
always 产生reg信号语句的关键字
assign 产生wire信号语句的关键字
begin 语句的起始标志
end 语句的结束标志
posedge/negedge 时序电路的标志
case Case语句起始标记
default Case语句的默认分支标志
endcase Case语句结束标记
if if/else语句标记
else if/else语句标记
for for语句标记
endmodule 模块结束定义
- 功能块:跟C#的class类型一样,是要被实例化的。【汽车图纸和实例化汽车】
-
- //================================================
-
- module flow_led(
- //====参数表===================
- input sys_clk , //系统时钟
- input sys_rst_n, //系统复位,低电平有效
- output reg [3:0] led //4 个 LED 灯
- ); //相当于声明一个函数
-
- //=======以下是函数体内局部变量===========
- //reg define
- reg [23:0] counter; //局部变量 24bit counter
-
- //=======函数方法=======================
- always @(posedge sys_clk or negedge sys_rst_n) // 运行的触发条件【上升沿sys_clk 】
- 或 【下降沿sys_rst_n 】
- begin //创建游戏副本
- if (!sys_rst_n)
- counter <= 24'd0;
- else if (counter < 24'd1000_0000 – 1’d1)
- //else if (counter < 24'd5) //仅用于仿真
- counter <= counter + 1'b1;
- else
- counter <= 24'd0;
- end //游戏副本结束
-
- //通过移位寄存器控制 IO 口的高低电平,从而改变 LED 的显示状态
- always @(posedge sys_clk or negedge sys_rst_n)
- begin
- if (!sys_rst_n)
- led <= 4'b0001;
- else if(counter == 24'd1000_0000 – 1’d1)
- //else if (counter == 24'd5) //仅用于仿真
- led[3:0] <= {led[2:0],led[3]};
- else
- led <= led;
- end
- endmodule
- 功能块加入了对象的概念,所以调用功能块要先实例化。
- //============================================
-
- //initial 语句是不可以被综合的,一般只在 testbench 中表达而不在 RTL 代码中表达
- //initial 块中的语句上电后只执行一次,主要用于初始化仿真中要输入的信号
- //初始化值在没有特殊要求的情况下给 0 或 1 都可以。如果不赋初值,仿真时信号
- //会显示为不定态(ModelSim 中的波形显示红色)
-
-
-
-
-
-
-
-
-
-
-
-
- `timescale 1ns/1ns // 【`】是预编译,类似C语言的#include // 这是FPGA原语 //晶振时钟 1ns
-
- //======类型声明============
- module FB //跟PLC的FB功能块一样,使用前需要实例化,注:不支持中文
- #(
- // 参数变量表
- parameter num1 = 8'b0001_0001 , //二进制 0x11
- parameter num2 = 32'o123456 , //八进制 8#123456
- parameter num3 = 32'd19890722 , //十进制 10#19890722
- parameter num4 = 64'h00ff_00ff //【最后一个不要加逗号,】 // 十六进制 0x00ff00ff // 16#00FF00FF
- )
-
- (
- // io变量表
- input wire num5 , // bool
- input wire[7:0] num6 , // byte
-
- output num7 ,//输出 bool 【默认wire】
- output reg[8-1:0] num8 ,//输出【寄存器】信号 8bit
-
- inout[7:0] num9 , // 可读写的 8bit变量
-
- input mun99 //【最后一个不要加逗号,】
- );
-
- // 内部成员变量
- parameter num10 = 1 ; // 内部 bool 常量
- parameter[7:0] num11 = 255 ; // 内部 byte 常量
-
- reg num12; // 内部bool变量
- reg [7:0] num13 = 8'b0011_0011 ; // 内部byte变量
- reg [15:0] num14 = 8'b0011_0011 ; // 内部16bit变量
-
- // 内部线程【多线程程序】
- // always时序程序, assign非时序, posedge上升沿, negedge下降沿
- //====================================================
- //==程序A=========
- assign num7 = num5 ; // 逻辑门输出
- //==程序B=========
- always@(posedge num10)begin // 如果 num10上升沿,就运行
- if(num6[7:6]) // num6的D7bit如果是True
- num8 <= 1 ; // num8输出高电平
- end
- //==程序n=========
- //====以下可以继续添加程序======================
-
- endmodule
- //======模块声明============
- //======A最简单的==============
- //module adder(input [7:0] a, input [7:0] b, output [7:0] sum);
- // assign sum = a + b;
- //endmodule
-
- //======B简单的================
- module example_module #(parameter WIDTH = 8) (
- input clk,
- input [WIDTH-1:0] data_in, // 利用参数
- output [WIDTH-1:0] data_out
- );
-
- // 使用parameter定义常量
- parameter ADD_VALUE = 4;
-
- // 在组合逻辑中使用parameter
- assign data_out = data_in + ADD_VALUE;
-
- // 在时序逻辑中使用parameter
- always @(posedge clk) begin
- // data_out <= data_in + ADD_VALUE ; //【data_out是wire】不能在时序方法内
- end
-
- endmodule
-
- //======C常规的=======================
- module FB //声明模块【名字不能用中文】
- //用#预处理
- #(
- // 参数表【常量】
- parameter pnum1 = 1'b0000_0011, // 二进制【下划线编译器是忽略的】
- parameter pnum2 = 18'd198907 , // 十进制,占18bit
- parameter pnum3 = 18'd170067 //【最后一个不加逗号】
- )
-
- (
- // 输入输出io表
- input wire num1 , // bool类型
- input wire[7:0] num2 , // 8bit,最高位d7
- input wire[0:7] num3 , // 8bit,最高位d0
- output reg num4 ,//输出【寄存器】信号 只读
- output reg num5 , //【最后一个不加逗号】 // 可读写
-
- inout num7 ,
-
- input num6 , // 默认wire
- input wire key_in , //输入按键
- output wire led_out //输出控制led灯
-
- ); // io表最后要加【;】
-
- //==============================================
- // 以下成员变量和方法
-
- parameter pnum4 = 1'b0000_0011; // 二进制【下划线编译器是忽略的】 //参数属于常量
- // 内部成员变量
- reg [24:0] cnt ; //0.5s 计数器
- reg [17:0] freq_cnt ; //音调计数器
- reg [2:0] cnt_500ms ; //0.5s 个数计数
- reg [17:0] freq_data ; //音调分频计数值
-
- // 并联线程
- // always@(posedge cnt or negedge cnt) ;
- assign led_out = ~key_in ;
-
- // always@(*)
- // if(num1 == 1'b0)
- // num1 += 1;
-
- endmodule
-
-
- `timescale 1ns/1ns
- ///
- // Author : EmbedFire
- // Create Date : 2023/03/30
- // Module Name : led
- // Project Name : led
- // Target Devices: PGL22G-6MBG324
- // Tool Versions : Pango Design Suite 2022.2
- // Description : 按键控制LED灯
- //
- // Revision :
- // Additional Comments:
- //
- // 实验平台: 野火_紫光PGL22G_FPGA开发板
- // 公司 : http://www.embedfire.com
- // 论坛 : http://www.firebbs.cn
- // 淘宝 : https://fire-stm32.taobao.com
- //
-
- module led
- (
- input wire key_in , //输入按键
- output wire led_out //输出控制led灯
- );
-
- //********************************************************************//
- //***************************** Main Code ****************************//
- //********************************************************************//
- //led_out:led灯输出的结果为key_in按键的输入值
- assign led_out = ~key_in ;
-
- endmodule
-
-
- 在Verilog中,符号{}用于连接多个信号或者数值,形成一个更大的信号或者数值。
- 下面是一个示例代码:
-
- module demo(
- input [3:0] a,
- input [3:0] b,
- output [7:0] c
- );
-
- assign c = {a, b};
-
- endmodule
-
- 在这个示例代码中,a和b都是4位的信号,c是8位的信号。{}符号将a和b连接起来,形成一个8位的信号c。
- 例如,如果a的值为4'b1010,b的值为4'b0110,那么c的值就是8'b10100110。
-
-
-
- assign {led1_d15,led2_c15,led3_a12,led4_b12} = {~key1_k18,~key2_n17,~key3_n18,~key4_h17}; //key1_k18 +key2_n17 + key3_n18 +key4_h17 ;
- 在C#中,可以使用数组和字符串拼接的方式实现类似Verilog中{}符号的功能。下面是一个示例代码:
-
- ```csharp
- using System;
-
- class Program
- {
- static void Main(string[] args)
- {
- int[] a = { 1, 0, 1, 0 };
- int[] b = { 0, 1, 1, 0 };
- int[] c = new int[8];
-
- for (int i = 0; i < 4; i++)
- {
- c[i] = a[i];
- c[i + 4] = b[i];
- }
-
- Console.WriteLine(string.Join("", c));
- }
- }
- ```
-
- 在这个示例代码中,我们定义了两个长度为4的整型数组a和b,以及一个长度为8的整型数组c。
- 通过for循环将a和b中的元素依次赋值给c中的对应位置,
- 最后使用string.Join方法将c中的元素拼接成一个字符串输出。
- 如果a和b的值分别为{1, 0, 1, 0}和{0, 1, 1, 0},那么输出的字符串就是"10100110"。
-