fpga-编程线性序列机和状态机

一、线性序列机和有限状态机和(状态机**-编程思想**)的原理

序列机是什么:用计数器对时钟个数计数,根据相应时钟周期下的单个周期时间和计数个数可以确定某个时刻的时间,确定时间后再需要时间点转换电平!

采用的是线性序列机其原理就是设计者必须清楚每一个时钟节拍,都有哪些东西发生变化;举个例子:这个东西就好比我们的课表一样,我们第一节上语文课,第二节上数学课,第三节上英语课,它是按照时钟节拍一拍一拍的按照事先已经知道要发生的步骤做着每件事情。

而状态机则不同它的灵活性比较高可以随意的从一个状态跳到另一个状态。状态机里面case(state),而序列机里面则是case(count),count表示的是时钟节拍数。

线性序列机:是时间顺序的事件,根据时间先后顺序进行工作。每次执行一个工作,都只能按照时间顺序从头到尾。

状态机:根据程序内的状态,进行工作。例

如:a=1时,做A事情然后a=3;a=3时做B事情然后a=1。

示例

1TLC5620驱动模块(DAC):

复制代码
module TLC5620_ctrl(
	clk50M,
	rst_n,
	ctrlword,
	updatareq,
 
	updatadone,
	TLC5620_CLK,
	TLC5620_DATA,
	TLC5620_LOAD,
	TLC5620_LDAC
);
 
	input clk50M;
	input rst_n;
	input [10:0] ctrlword;
	input updatareq;
 
	output reg updatadone;
	output reg TLC5620_CLK;
	output reg TLC5620_DATA;
	output reg TLC5620_LOAD;
	output reg TLC5620_LDAC;
 
	reg [9:0] counter;
 
	/*************************产生计数器************************/
	always @ (posedge clk50M or negedge rst_n) begin
		if(!rst_n)
			counter<=10'd0;
		else if(updatareq==1|(counter!=10'd0)) begin
			if(counter==10'd820)
				counter<=10'd0;
			else
				counter<=counter+1'b1;
		end
		else 
			counter<=10'd0;
	end 
	/**********************************************************/
	
 
	/*********************线性序列机写接口时序*******************/
	always @ (posedge clk50M or negedge rst_n) begin
		if(!rst_n) begin
			updatadone<=1'b0;
			TLC5620_CLK<=1'b0;
			TLC5620_DATA<=1'b0;
			TLC5620_LOAD<=1'b0;
			TLC5620_LDAC<=1'b0;
			updatadone<=1'b0;
		end
		else begin
			case(counter)
				0:begin
					TLC5620_CLK<=1'b0;
					TLC5620_DATA<=1'b0;
					TLC5620_LOAD<=1'b1;
					TLC5620_LDAC<=1'b0;
					updatadone<=1'b0;
				  end
				10:
					begin
						TLC5620_CLK<=1'b1;
						TLC5620_DATA<=ctrlword[10];				
					end
				40:TLC5620_CLK<=1'b0;
				70:
					begin
						TLC5620_CLK<=1'b1;
						TLC5620_DATA<=ctrlword[9];				
					end
				100:TLC5620_CLK<=1'b0;
				130:
					begin
						TLC5620_CLK<=1'b1;
						TLC5620_DATA<=ctrlword[8];				
					end
				160:TLC5620_CLK<=1'b0;
				190:
					begin
						TLC5620_CLK<=1'b1;
						TLC5620_DATA<=ctrlword[7];				
					end
				220:TLC5620_CLK<=1'b0;
				250:
					begin
						TLC5620_CLK<=1'b1;
						TLC5620_DATA<=ctrlword[6];				
					end
				280:TLC5620_CLK<=1'b0;
				310:
					begin
						TLC5620_CLK<=1'b1;
						TLC5620_DATA<=ctrlword[5];				
					end
				340:TLC5620_CLK<=1'b0;
				370:
					begin
						TLC5620_CLK<=1'b1;
						TLC5620_DATA<=ctrlword[4];				
					end
				400:TLC5620_CLK<=1'b0;
				430:
					begin
						TLC5620_CLK<=1'b1;
						TLC5620_DATA<=ctrlword[3];				
					end
				460:TLC5620_CLK<=1'b0;
				490:
					begin
						TLC5620_CLK<=1'b1;
						TLC5620_DATA<=ctrlword[2];				
					end
				520:TLC5620_CLK<=1'b0;
				550:
					begin
						TLC5620_CLK<=1'b1;
						TLC5620_DATA<=ctrlword[1];				
					end
				580:TLC5620_CLK<=1'b0;
				610:
					begin
						TLC5620_CLK<=1'b1;
						TLC5620_DATA<=ctrlword[0];				
					end
				640:TLC5620_CLK<=1'b0;
				670:TLC5620_LOAD<=1'b0;
				800:TLC5620_LOAD<=1'b1;
				820:updatadone<=1'b1;
				default:;
			endcase
		end
	end
 
endmodule

2串口发送设计

复制代码
module uart_tx (
	input			uart_clk,    
	input			rst_n,  
	input			tf_empty,//判断才做是否完成
	input	[7:0]	tf_data,
	output reg		tf_rdreq,
	output reg		txd
);
 
 
reg [7:0] cnt;//节拍计数
reg [7:0] temp_data;//FIFO读数据后进行寄存
 
//LSM_1
always @(posedge uart_clk or negedge rst_n) begin
	if(rst_n == 1'b0) 
		 cnt <= 8'd192;
	else if (cnt >= 8'd192 && tf_empty == 1'b0) 
		cnt <= 8'd0;
	eles if(cnt < 8'd192)
		cnt <= cnt + 1'd1;
end
 
//LSM_2
always @(posedge uart_clk or negedge rst_n) begin
	if(rst_n == 1'b0) begin
		 txd <= 1'b1;
		 tf_rdreq <= 1'b0;
		 temp_data <= 8'd0;
	end else 
		 	case (cnt)
		 		0 : begin
		            tf_rdreq  <= 1'b0;
		            txd       <= 1'b0;
		 		end
		        1 : temp_data <= tf_data;
		        1*16 : txd    <= temp_data[0];
		        2*16 : txd    <= temp_data[1];
		        3*16 : txd    <= temp_data[2];
		        4*16 : txd    <= temp_data[3];
		        5*16 : txd    <= temp_data[4];
		        6*16 : txd    <= temp_data[5];
		        7*16 : txd    <= temp_data[6];
		        8*16 : txd    <= temp_data[7];
		        9*16 : txd    <= 1'b1;
		 	endcase
	
end
 
endmodule

状态机

相关推荐
Eloudy9 小时前
FPGA (QSFP28 + CMAC US+ RoCEv2) 与 Ubuntu22 + Mellanox 网卡直连分析
fpga开发
szxinmai主板定制专家10 小时前
RK3568+FPGA高速并行采集|半导体探针测试设备多通道同步数据采集系统设计
人工智能·嵌入式硬件·计算机视觉·fpga开发
ARM|X86+FPGA工业主板厂家1 天前
RK3588+FPGA+EtherCAT异构架构解析|工业场景如何同时保住AI算力与微秒级运动实时性
人工智能·fpga开发·架构
zlinear数据采集卡2 天前
从“脏信号”到“纳伏级纯净”:硬核拆解DABL7606的多级抗混叠滤波与24位过采样算法
arm开发·科技·嵌入式硬件·fpga开发·开源
尤老师FPGA2 天前
HDMI数据的接收发送实验(二十)
fpga开发
千寻xun2 天前
三、实战篇-NVME SSD控制之FPGA实现(一)
fpga开发·nvme ssd·nvme协议
XMAIPC_Robot3 天前
软硬协同实时控制|RK3588业务调度+FPGA硬件时序,ethercat实现半导体设备微秒级响应(125us)
linux·arm开发·人工智能·fpga开发
upper20203 天前
从零开始设计riscv cpu记录之七
fpga开发·riscv·riscv设计·btb·分支预测
ARM|X86+FPGA工业主板厂家3 天前
AI视觉跟随运动控制实战|RK3588 NPU检测+FPGA EtherCAT多轴联动精准跟随方案,适用于半导体视觉对位等
人工智能·fpga开发·硬件工程·ethercat·实时系统
XMAIPC_Robot3 天前
RK3588+FPGA半导体设备量产踩坑大全|发热、时序漂移、推理抖动、成像干扰、EMC干扰方案
人工智能·嵌入式硬件·fpga开发·arm+fpga