Intel FPGA:线性序列机

这篇具有很好参考价值的文章主要介绍了Intel FPGA:线性序列机。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Intel FPGA:线性序列机

前提摘要

  1. 个人说明:

    • 限于时间紧迫以及作者水平有限,本文错误、疏漏之处恐不在少数,恳请读者批评指正。意见请留言或者发送邮件至:“Email:noahpanzzz@gmail.com”
    • 本博客的工程文件均存放在:GitHub:https://github.com/panziping。
    • 本博客的地址:CSDN:https://blog.csdn.net/ZipingPan
  2. 参考:

    • 芯片型号:Intel EP4CE10F17C8(Cyclone IV E)
    • 《数字电子技术基础》-阎石
    • 《FPGA自学笔记—设计与验证》袁玉卓,曾凯锋,梅雪松
    • 《Verilog 数字系统设计教程》夏宇闻
    • 《Verilog HDL 高级数字设计》Michael D.Ciletti
    • 《Intel FPGA/CPLD设计》(基础篇)王欣 王江宏等
    • 《Intel FPGA/CPLD设计》(高级篇)王江宏 蔡海宁等
    • 《综合与时序分析的设计约束 Synopsys设计约束(SDC)实用指南》Sridhar Gangadharan

正文

点亮LED灯

硬件资源

Intel FPGA:线性序列机,# FPGA,Intel FPGA

由原理图可知,FPGA的IO口输出低电平,则LED点亮。

程序编写
module led_test(
	led
);
	output led;

	assign led = 1'b0;

endmodule 

点亮LED灯进阶

将LED点亮200ms,熄灭800ms。

程序编写
module led_test(
	clk,
	rst_n,
	led
);

	input clk;
	input rst_n;
	output reg led;
	reg [27:0] r_led_cnt;
	localparam LED_CNT_MAX = 28'd50_000_000;
	localparam LED_CNT_TURN = 28'd40_000_000;

    always@(posedge clk or negedge rst_n) begin
		if(!rst_n)
			r_led_cnt <= 'd0;
		else if(r_led_cnt == LED_CNT_MAX-1)
			r_led_cnt <= 'd0;
		else
			r_led_cnt <= r_led_cnt + 1'd1;
	end
	
    always@(posedge clk or negedge rst_n) begin
		if(!rst_n)
			led <= 1'd1;
		else if(r_led_cnt == LED_CNT_TURN-1)
			led <= 1'd0;
		else if(r_led_cnt == LED_CNT_MAX-1)
			led <= 1'd1;
		else
			led <= led;
	end

	
endmodule 
波形图

Intel FPGA:线性序列机,# FPGA,Intel FPGA

由上述实验可以发现,通过计数器可以产生一个占空比不是50%的周期信号。那么是不是由此可以引申,通过计数器对时钟计数,产生一串带有数字信息的信号。

线性序列机(LSM)

产生一段信号,包含的内容为11011010,每个码元所占用的时间为50us。

module tx_test(
	clk,
	rst_n,
	tx
);
	input clk;
	input rst_n;
	output reg tx;

	reg [15:0] r_tim_cnt;
	
	localparam TIM_CNT_MAX = 16'd20_000;
	localparam DATA0 = 16'd2_500;
	localparam DATA1 = 16'd5_000;
	localparam DATA2 = 16'd7_500;
	localparam DATA3 = 16'd10_000;
	localparam DATA4 = 16'd12_500;
	localparam DATA5 = 16'd15_000;
	localparam DATA6 = 16'd17_500;
	localparam DATA7 = 16'd20_000;
    always@(posedge clk or negedge rst_n) begin
		if(!rst_n)
			r_tim_cnt <= 'd0;
		else if(r_tim_cnt == TIM_CNT_MAX-1)
			r_tim_cnt <= 'd0;
		else
			r_tim_cnt <= r_tim_cnt + 1'd1;
	end
	
    always@(posedge clk or negedge rst_n) begin
		if(!rst_n)
			tx <= 1'd1;
		else if(r_tim_cnt == DATA0 - 1'd1)
			tx <= 1'd0;
		else if(r_tim_cnt == DATA1 - 1'd1)
			tx <= 1'd1;
		else if(r_tim_cnt == DATA2 - 1'd1)
			tx <= 1'd0;
		else if(r_tim_cnt == DATA3 - 1'd1)
			tx <= 1'd1;
		else if(r_tim_cnt == DATA4 - 1'd1)
			tx <= 1'd1;
		else if(r_tim_cnt == DATA5 - 1'd1)
			tx <= 1'd0;
		else if(r_tim_cnt == DATA6 - 1'd1)
			tx <= 1'd1;
		else if(r_tim_cnt == DATA7 - 1'd1)
			tx <= 1'd1;
		else 
			tx <= tx;
	end
	
//	always@(posedge clk or negedge rst_n) begin
//		if(!rst_n)
//			tx <= 1'd1;
//		else 
//			case(r_tim_cnt)
//			DATA0-1'd1: tx <= 1'd0;
//			DATA1-1'd1: tx <= 1'd1;			
//			DATA2-1'd1: tx <= 1'd0;
//			DATA3-1'd1: tx <= 1'd1;		
//			DATA4-1'd1: tx <= 1'd1;
//			DATA5-1'd1: tx <= 1'd0;			
//			DATA6-1'd1: tx <= 1'd1;
//			DATA7-1'd1: tx <= 1'd1;			
//			default:tx <= tx;
//			endcase
//	end
//	

endmodule 
波形图

Intel FPGA:线性序列机,# FPGA,Intel FPGA

由上述实验可以发现,通过线性序列机产生了8bits(11011010)的信号。那么是不是对于串行信号都可以通过线性序列机进行输出。

数码管驱动

上述是线性序列机(LSM)的简单应用。

这一部分展示线性序列机应用在数码管驱动电路中(完整请见(Intel FPGA (3):数码管显示)),需要通过线性序列机产生三个信号seg_sclk(sh_cp),seg_rclk(st_cp),seg_dio(ds)

波形图

Intel FPGA:线性序列机,# FPGA,Intel FPGA

程序编写
module hc595_driver(
	clk,
	rst_n,
	seg_data,
	seg_data_valid_go,
	seg_sclk,
	seg_rclk,
	seg_dio
);

	input clk;
	input rst_n;
	input [15:0] seg_data;
	input seg_data_valid_go;
	output reg seg_sclk;
	output reg seg_rclk;
	output reg seg_dio;
	

	reg [15:0] r_seg_data;
	always@(posedge clk or negedge rst_n) begin
		if(!rst_n)
			r_seg_data <= 'd0;
		else if(seg_data_valid_go == 1'b1)
			r_seg_data <= seg_data;
		else
			r_seg_data <= r_seg_data;
	end
	
	localparam DIV_CNT_MAX = 4;			//fsh_cp = 6.25MHz
	reg [2:0] r_div_cnt;
	
	always@(posedge clk or negedge rst_n) begin
		if(!rst_n)
			r_div_cnt <= 'd0;
		else if(r_div_cnt == DIV_CNT_MAX -1)
			r_div_cnt <= 'd0;
		else	
			r_div_cnt <= r_div_cnt + 1'b1;
	end
	wire w_sclk_pluse;	//SH_CP
	assign w_sclk_pluse = (r_div_cnt == DIV_CNT_MAX -1) ? 1'b1 :1'b0;
	
	
	reg [4:0] r_sclk_edge_cnt;	//SH_CP
	
	
	always@(posedge clk or negedge rst_n) begin
		if(!rst_n)
			r_sclk_edge_cnt <= 'd0;
		else if(w_sclk_pluse == 1'b1)
			if(r_sclk_edge_cnt == 5'd31)
				r_sclk_edge_cnt <= 'd0;
			else
				r_sclk_edge_cnt <= r_sclk_edge_cnt + 1'd1;
		else
			r_sclk_edge_cnt <= r_sclk_edge_cnt;
	end
	

	
	always@(posedge clk or negedge rst_n) begin
		if(!rst_n) begin
			seg_sclk <= 1'd0;
			seg_rclk <= 1'd0;
			seg_dio <= 1'd0;
		end
		else begin
			case(r_sclk_edge_cnt)
				5'd0 : begin seg_sclk = 1'b0; seg_rclk = 1'b1; seg_dio = r_seg_data[15]; end //Q2H(HEX_DP)
				5'd1 : begin seg_sclk = 1'b1; seg_rclk = 1'b0;  								 end 
				5'd2 : begin seg_sclk = 1'b0;				        seg_dio = r_seg_data[14]; end //Q2G(HEX_G)
				5'd3 : begin seg_sclk = 1'b1;								   						 end
				5'd4 : begin seg_sclk = 1'b0;				        seg_dio = r_seg_data[13]; end //Q2F(HEX_F)
				5'd5 : begin seg_sclk = 1'b1;														    end
				5'd6 : begin seg_sclk = 1'b0;				        seg_dio = r_seg_data[12]; end //Q2E(HEX_E)
				5'd7 : begin seg_sclk = 1'b1;														    end
				5'd8 : begin seg_sclk = 1'b0;				        seg_dio = r_seg_data[11]; end //Q2D(HEX_D)	
				5'd9 : begin seg_sclk = 1'b1;														    end
				5'd10: begin seg_sclk = 1'b0;				        seg_dio = r_seg_data[10]; end //Q2C(HEX_C)	
				5'd11: begin seg_sclk = 1'b1;														    end
				5'd12: begin seg_sclk = 1'b0;				        seg_dio = r_seg_data[9];  end //Q2B(HEX_B)	
				5'd13: begin seg_sclk = 1'b1;					    									 end
				5'd14: begin seg_sclk = 1'b0;				        seg_dio = r_seg_data[8];  end //Q2A(HEX_A)
				5'd15: begin seg_sclk = 1'b1;					    									 end
				5'd16: begin seg_sclk = 1'b0;				        seg_dio = r_seg_data[7];  end //Q1H(HEX_SEL7)		
				5'd17: begin seg_sclk = 1'b1;					    									 end
				5'd18: begin seg_sclk = 1'b0;				        seg_dio = r_seg_data[6];  end //Q1G(HEX_SEL6)
				5'd19: begin seg_sclk = 1'b1;					    									 end
				5'd20: begin seg_sclk = 1'b0;				        seg_dio = r_seg_data[5];  end //Q1F(HEX_SEL5)
				5'd21: begin seg_sclk = 1'b1;					    									 end
				5'd22: begin seg_sclk = 1'b0;				        seg_dio = r_seg_data[4];  end //Q1E(HEX_SEL4)		
				5'd23: begin seg_sclk = 1'b1;					    									 end
				5'd24: begin seg_sclk = 1'b0;				        seg_dio = r_seg_data[3];  end //Q1D(HEX_SEL3)			
				5'd25: begin seg_sclk = 1'b1;					    									 end
				5'd26: begin seg_sclk = 1'b0;				        seg_dio = r_seg_data[2];  end //Q1C(HEX_SEL2)	
				5'd27: begin seg_sclk = 1'b1;					    									 end
				5'd28: begin seg_sclk = 1'b0;				        seg_dio = r_seg_data[1];  end //Q1B(HEX_SEL1)	
				5'd29: begin seg_sclk = 1'b1;					    									 end
				5'd30: begin seg_sclk = 1'b0;				        seg_dio = r_seg_data[0];  end //Q1A(HEX_SEL0)
				5'd31: begin seg_sclk = 1'b1;					    									 end
				default:;
			endcase
		end
	end

endmodule 

总结

线性序列机可以画出任意波形的数字信号!常用作为最低层RTL设计。


本文均为原创,欢迎转载,请注明文章出处:CSDN:https://blog.csdn.net/ZipingPan/FPGA。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。

非原创博客会在文末标注出处,由于时效原因,可能并不是原创作者地址(已经无法溯源)。文章来源地址https://www.toymoban.com/news/detail-847173.html

到了这里,关于Intel FPGA:线性序列机的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Intel Atom + Artix-7 100T FPGA,CompactRIO单板控制器

    CompactRIO控制器是搭载了实时处理器和用户可编程FPGA的嵌入式控制器。其产品范围涵盖各类坚固耐用的系统和单板RIO产品等,可用作单板计算机(SBC)和模块上系统(SOM)。 sbRIO-9628是一款CompactRIO单板控制器,运行NI Linux实时操作系统,在单板上包含用户可编程FPGA和I/O。该控制器还

    2024年01月25日
    浏览(27)
  • 信号发生器:Intel FPGA DDS(NCO)+双路DAC(AD9767)输出正余弦信号

    Quartus18.1 小梅哥AC620开发板+ACM9767模块 示波器 ACM9767模块使用的是ADI公司的AD9767芯片,14位CMOS 双通道DAC,125Msps转换率。 输出形式为差分电流输出,输出电流满量程范围为可设置为 2~20mA。 AD9767的两路DA输出都为补码形式的电流输出IoutA和IoutB。当AD9767数字输入为满量程时(DAC的

    2024年03月24日
    浏览(45)
  • 力扣hot100 最长递增子序列 线性DP 贪心 二分

    Problem: 300. 最长递增子序列 时间复杂度: O ( n 2 ) O(n^2) O ( n 2 ) 空间复杂度: O ( n ) O(n) O ( n ) 👨‍🏫 参考题解 时间复杂度: O ( n log ⁡ n ) O(nlog{n}) O ( n lo g n ) 空间复杂度: O ( n ) O(n) O ( n )

    2024年01月20日
    浏览(29)
  • FPGA学习(2)m序列和gold序列的产生

           m序列是最长线性反馈移位寄存器序列的简称。它是由带线性反馈的移存器产生的周期最长的序列。一般来说,一个n级线性反馈移存器可能产生的最长周期等于。         m序列是一种典型的伪随机序列。在通信领域有着广泛的应用,如扩频通信、卫星通信的码分

    2024年02月11日
    浏览(28)
  • 【FPGA & Modsim】序列检测

    实验题目:    序列检测器设计                                   实验目的:    掌握应用数字逻辑设计集成开发环境进行序列检测器设计的方法;掌握时序逻辑电路设计的过程。                        实验内容: 1、设计一个序列检测器,用于

    2024年02月20日
    浏览(22)
  • 【IC设计】Verilog线性序列机点灯案例(三)(小梅哥课程)

    声明:案例和代码来自小梅哥课程,本人仅对知识点做做笔记,如有学习需要请支持官方正版。 Verilog线性序列机点灯案例(一) Verilog线性序列机点灯案例(二) Verilog线性序列机点灯案例(三) Verilog线性序列机点灯案例(四) 使用8个拨码开关控制一个LED灯,每个拨码开关

    2024年04月14日
    浏览(21)
  • 【论文阅读】Mamba:具有选择状态空间的线性时间序列建模

    Mamba:基于选择状态空间的线性时间序列建模 论文两位作者Albert Gu和Tri Dao,博士都毕业于斯坦福大学,导师为Christopher Ré。 Albert Gu现在是CMU助理教授,多年来一直推动SSM架构发展。他曾在DeepMind 工作,目前是Cartesia AI的联合创始人及首席科学家。 Tri Dao,以FlashAttention、Flas

    2024年03月21日
    浏览(39)
  • 【LabVIEW FPGA入门】插值、输出线性波形

            NI 的可重配置 I/O (RIO) 硬件使开发人员能够创建自定义硬件,以在坚固耐用、高性能和模块化架构中执行许多任务,而无需了解低级 EDA 工具或硬件设计。使用 RIO 硬件轻松实现的此类任务之一是模拟波形生成。本教程介绍了使用 CompactRIO 硬件和 LabVIEW FPGA 模块输出

    2024年04月09日
    浏览(33)
  • m序列生成方法及其fpga实现

    1、 什么是PN码 PN码的英文名字叫Pseudo-Noise Code,(pseudo:adj.伪; 假的),直译过来就是伪噪声码,这里噪声主要是想表达随机的意思。其中最重要的一种PN序列叫 m序列 (全称叫最长线性反馈移位寄存器序列),说它重要主要是研究得早,理论成熟,用得多。 其本质上就是一串

    2024年02月03日
    浏览(21)
  • 基于FPGA线性调频信号LFM的产生

    本文用了DDS来产生LFM信号,DDS的原理可以查看赛灵思的官方文档,这里不做赘述,同时对于LFM信号也不做赘述,直接上工程实现及其方法。 首先,我们要确定脉宽和PRI,在这里脉宽选取10us,PRI选取200us(fpga内部时钟用来100MHz),所以使用计数器去实现这两个信号的计数,当

    2024年02月16日
    浏览(69)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包