Augus

5.菜鸟初入FPGA之LED显示移位,位拼运算

0
阅读(11008)

  本次做的程序是用板卡的led显示移位和位拼运算,下面我们分别写一下移位,位拼,以及LED显示,通过顶层TOP.v实现设计

   1. 移位运算符

    移位运算符是双目运算符,将运算符左边的操作数左移或右移运算符右边的操作数指定的位数,用 0 来补充空闲位。如果右边操作数的值为 X 或 Z,则移位结果为未知X。    

   Verilog HDL 中有两种移位运算符: <<(左逻辑移)和>>(右逻辑移)。

例程:

module Shift_led(clk,rst_n);
	input rst_n;
	input clk;
	
	reg [3:0]a;
	reg [3:0]b;
	
	always @(posedge clk or negedge rst_n)
	if(!rst_n) begin
		a = 1;
		b = 3;
	end
	else begin
		a <= (a<<1);
		b <= (b>>1);
	end
endmodule 
//仿真代码
`timescale 1ns/1ns
`define clk_period 20
module Shift_led_tb;
	reg clk;
	reg rst_n;
	
	initial clk = 1;
	always #(`clk_period/2)clk = ~clk;
	initial begin
		rst_n = 0;
		#(`clk_period*5);
		rst_n = 1;
		#(`clk_period*20);
		$stop;	
	end
	Shift_led Shift_led(.clk(clk),.rst_n(rst_n));
endmodule

仿真波形图:

a.jpg

从仿真图,可以看出,每次 a 都向左边移动移位,后面补充 0,直到把逻辑1 溢出,后面就一直为 0 了。 每次 b 都向右边移动移位,前面补充 0,直到把逻辑 1 溢出,就一直为 0 了。

    

   备注:移位运算符的使用时,左移可以看成是乘以 2,右移可以看成是除以2。 所以移位运算符用在计算中,代替乘法和除法。


    2. 位拼运算符

    位拼运算符是将多个小的表达式合并形成一个大的表达式,用符号{}来实现多个表达式的连接运算,各个表达式之间用“,”隔开。

module Concatation(clk,rst_n,out);
	input clk;
	input rst_n;
	
	output reg [3:0]out;
	
	reg [1:0]a;
	reg [1:0]b;
	
	always @(posedge clk or negedge rst_n)
	if(!rst_n) begin
		a <= 2'b11;
		b <= 2'b01;
		out <= 4'b0011;
	end
	else begin
		a <= (a<<1);
		b <= (b<<1);
		out <= {a,b};
	end
endmodule

//`tb.v同移位   注意修改例化

仿真波形图为:

2016-03-25_183519.jpg

通过波形图,我们可以清晰的看到移位和位拼结合的效果


注:用位拼"{ }"同样可以实现循环效果

例程:

if()
...
out <= 4'b0111;
...
else
...
out <= {out[0],out[3:1]};
...
//感兴趣的可以试一下,这里不做展示


    3.LED显示移位,位拼效果.

    下面我们通过例程说明

module Concatation(clk,rst_n,led);
	input clk;
	input rst_n;
	
	output [3:0]led;
	
	reg [3:0]out;
	
	reg [1:0]a;
	reg [1:0]b;
	
	always @(posedge clk or negedge rst_n)
	if(!rst_n) begin
		a <= 2'b11;
		b <= 2'b01;
		out <= 4'b0011;
	end
	else begin
		a <= (a<<1);
		b <= (b<<1);
		out <= {a,b};
	end
	
	assign led = out;
	
endmodule
///////////////////////////////////////////////////////
`timescale 1ns/1ns

`define clk_period 20

module Concatation_tb;
	
	reg clk;
	reg rst_n;
	
	initial clk = 1;
	always #(`clk_period/2)clk = ~clk;
	
	initial begin
		rst_n = 0;
		#(`clk_period*5);
		rst_n = 1;
		#(`clk_period*20);
		$stop;
		
	end
	
	
	Concatation Concatation(.clk(clk),.rst_n(rst_n),.led(led));
	
endmodule

仿真效果

2016-03-25_185149.jpg

我们通过观察led和out的输出,可以看到结果相同,通过led信号我们下载到板卡上时,就能观察到led显示同波形图


注: 真正下载板卡让led显示时,我们需要通过计数延时,要不然人眼观察不出led变化

详情请等后续笔记......................^^


更多资料参考

                发烧友小梅哥专版 http://bbs.elecfans.com/zhuti_fpga_1.html

                   梦翼师兄的炼狱传奇