燕大eda实训

​ 最近一段时间咱们学校在改革,eda实训也开始全面学习fpga开发版,作者就引领着大家对fpga的初步学习。由于作者能力有限,部分内容可能会有错误,欢迎各位大佬在评论区补充内容。

​ 作者的实习一共有三个内容,分别是点亮小灯、进行不同模式的流水灯和自由开发项目。接下来作者将会一一介绍每个实训的内容,本文侧重讲解代码,引脚等配置仔细听上课老师的讲解。

点亮小灯

​ 第一是点亮小灯,代码如下,需要注意的内容见注释:

//描述:LED 闪烁,新建立的.v文件的名称需要和module后的字母(led_flash)相同,不然会报错
module  led_flash(CLK_50M,RST_N,LED);
 
//外部端口声明
input   CLK_50M;            //时钟的端口,开发板用的 50M 晶振  
input   RST_N;              //复位的端口低电平复位  
output   LED;               //对应开发板上的 LED 

//内部端口声明  
reg [26:0] time_cnt;        //用来控制 LED 闪烁频率的定时计数器  
reg [26:0] time_cnt_n;      // time_cnt 的下一个状态  
reg  led_reg;               //用来控制 LED 亮灭的显示寄存器  
reg  led_reg_n;             // led_reg 的下一个状态 
 
//设置定时器的时间为 1s,计算方法为 1s/(1/(50*106Hz))=50*106  50MHz 为开发板晶振// 
parameter  SET_TIME_1S =27'd50_000_000;    //27'd 为 27 位十进制数

//逻辑功能实现 //时序电路,用来给 time_cnt 寄存器赋值 
//<=是非阻塞式赋值,=是阻塞是赋值,作者分不太清有什么用,但是对于同一变量,只能使用一种赋值方式,要么全部使用阻塞式赋值,要么全部使用非阻塞式赋值。
always @ (posedge CLK_50M or negedge RST_N)  
begin      
    if (!RST_N)                     //判断复位         
        time_cnt  <=  27'h0;        //初始化 time_cnt 值      
    else         
        time_cnt  <=  time_cnt_n;   //用来给 time_cnt 赋值  
end 
 
//组合电路,实现 1s 的定时计数器 
always @ (*)  
begin      
    if(time_cnt ==SET_TIME_1S)       //判断 1s 时间,因为开发板使用的晶振是50MHZ,在定义SET_TIME_1S时赋值了50M,所以每到达一次就是1s     
        time_cnt_n = 27'h0;          //如果到达 1s 定时计数器将会被清零      
    else        
        time_cnt_n = time_cnt+27'h1;      //如果未到 1s,定时计数器将会继 续累加  
end

always @ (posedge CLK_50M or negedge RST_N)
begin       
    if (!RST_N)               //判断复位  
        led_reg  <=  1'b0;       //初始化 led_reg 值  
    else     
        led_reg <= led_reg_n;   //用来 给 led_reg 赋值 
end 
 
//组合电路,判断时间,控制 LED 的亮或灭  
always @ (*)  
begin        
    if(time_cnt ==SET_TIME_1S) //判断 1s 时间              
        led_reg_n =~led_reg; //如果到达1s,显示寄存器将会改变LED的 状态        
    else              
        led_reg_n =led_reg;//如果未到 1s,显示寄存器将会将保持 LED 的原状态 
end  

assign   LED=led_reg;        //最后,将显示寄存器的值赋值给端口 LED  

endmodule

流水灯

实验要求:

流水灯分阶段显示,第一阶段从右到左依次点亮;第二阶段LED流水灯从左到右依次熄灭;第三阶段LED流水从中间向两边点依次点亮;第四时间段LED流水灯从中间向两边点依次熄灭,此为一个循环。

方法1 查表法

//描述:LED 闪烁
// 'define SYS_CLK_VAL (27'd50_000_000)

module  led_flash
        (
            input   sys_clk,            //系统时钟端口,开发板用的 50M 晶振
            input   sys_rst_n,          //复位的端口低电平复位
            output  reg  [7:0]  led     //LED输出信号
        );

reg  [27:0] cnt;        //系统时钟计数
integer led_control;

//用于计数的计数器
always @ (posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)              //复位
        cnt<=27'd0;
    else if(cnt<27'd10_000_000) //没到计数值,cnt就加1,等到到达10_000_000也就是10_000_000/50M =0.2秒时,cnt就置0
        cnt<=cnt+1;
    else                        //溢出归零
        cnt<=27'd0;
end

//用于led灯状态的选择
always @(posedge sys_clk or negedge sys_rst_n) begin
    if (!sys_rst_n)
        led_control <= 0;
    else if(cnt == 27'd0_000_000) begin
        led_control = led_control + 1;

        if(led_control>23)
            led_control=0;
//下面过程是查表法,将所有的可能用case写出,当然也可以用if写,不过那样会很麻烦
        case (led_control)
            0   : led<=8'b00000001;
            1   : led<=8'b00000011;
            2   : led<=8'b00000111;
            3   : led<=8'b00001111;
            4   : led<=8'b00011111;
            5   : led<=8'b00111111;
            6   : led<=8'b01111111;
            7   : led<=8'b11111111;

            8    : led<=8'b01111111;
            9    : led<=8'b00111111;
            10   : led<=8'b00011111;
            11   : led<=8'b00001111;
            12   : led<=8'b00000111;
            13   : led<=8'b00000011;
            14   : led<=8'b00000001;
            15   : led<=8'b00000000;

            16   : led<=8'b00011000;
            17   : led<=8'b00111100;
            18   : led<=8'b01111110;
            19   : led<=8'b11111111;

            20   : led<=8'b11100111;
            21   : led<=8'b11000011;
            22   : led<=8'b10000001;
            23   : led<=8'b00000000;
        endcase

    end
end


endmodule


方法2 逻辑法

​ 这一篇是使用逻辑法,就是在上面那种查表法的基础上,将case语句使用左右移、与或语句来进行运算,相对于查表法较为复杂。

//描述:LED 流水
// 'define SYS_CLK_VAL (27'd50_000_000)


module  led_flowing_lights
        (
            input   sys_clk,            //系统时钟端口,开发板用的 50M 晶振
            input   sys_rst_n,          //复位的端口低电平复位
            output  reg  [7:0]  led     //LED输出信号
             );

reg  [27-1:0] cnt;        //系统时钟计数
integer led_cnt;
integer led_mode;
    
//初始化
initial begin
		led_mode <=0;
		led <= 8'b00000001;
		led_cnt <=0;
end

//用于计数的计数器
always @ (posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)              //复位
        cnt<=27'd0;
    else if(cnt<27'd10_000_000) //没到计数值
        cnt<=cnt+1;
    else                        //溢出归零
        cnt<=27'd0;
end

//用于led灯状态的选择
always @(posedge sys_clk or negedge sys_rst_n) begin
    if (!sys_rst_n) begin//初始化
		led_mode <=0;
		led = 8'b00000000;
		led_cnt <=0;
		end
    else if(cnt == 27'd0) begin
	 led_cnt <= led_cnt + 1;
	 
    if((led_cnt>7 &&(led_mode==0||led_mode==1)) || (led_cnt>3 &&(led_mode==2||led_mode==3))) begin 
		led_cnt <= 0;
		led_mode = led_mode +1 ;
		if (led_mode>=4)
			led_mode = 0;
		end
	
  
	if(led_mode==0)
		led = (led << 1)+1;
	else if(led_mode==1)
		led = (led >>1);
	else if(led_mode==2 && led_cnt==0)
		led = 8'b00011000;
	else if(led_mode==2 && led_cnt!=0)
		led = (led<<1) | (led>>1);
	else if(led_mode==3 && led_cnt==0)
		led = 8'b11100111;
	else if(led_mode==3 && led_cnt!=0)
		led = ((led<<1)|(8'b00000001)) & ((led>>>1) | (8'b10000000));
    end
end

endmodule

​ 在流水灯这一章的学习中,建议大家试着用其他思路来完成这一部分的学习,以上代码仅供参考。

自由设计

​ 这个嘛,就要看实力了,由于咱们学校用的板子在网上没找到资料,但作者在实习时找到了正点原子板子的例程,大部分例程改引脚后就可以用,但是有些不行,比如数码管,因为板载数码管驱动方式不同。大家还可以在其他地方找找其他的例程,本文就不赘述了。
正点原子fpga例程

公众号:湛岚宁的小屋

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值