Quartus 曼彻斯特码 CRC校验

2024-02-24 06:40

本文主要是介绍Quartus 曼彻斯特码 CRC校验,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

VHDL 曼彻斯特编解码

曼彻斯特码

曼彻斯特码,即曼彻斯特编码(Manchester Encoding),也叫做相位编码(PE),是一个同步时钟编码技术,被物理层使用来编码一个同步位流的时钟和数据。在曼彻斯特编码中,每一位的中间有一跳变,位中间的跳变既作时钟信号,又作数据信号;从低到高跳变表示“1”,从高到低跳变表示“0”。

说明

最近完成了一个串行通信的项目,采用光纤作为物理层材料,FPGA为控制器。协议方面以4个高电平作为起始位,数据宽度28位数无停止位,通过修改程序使原8个时钟周期判断一位数据变为2位时钟判断一位数据,加快了解码的速度,降低了解码时钟所需频率。

曼彻斯特编码

编码部分较为简单,流程为加同步头、串并转换。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use work.PCK_CRC8_D1.ALL;entity coding isgeneric (dat_wide		: integer := 21;head_wide	: integer := 4);Port ( Clk 			: in  STD_LOGIC;Clk_div_2    : in  STD_LOGIC;Pid_data 		: in  STD_LOGIC_VECTOR (dat_wide-1 downto 0);--输入并行码Pod_manch 	: out STD_LOGIC);
end coding;architecture Behavioral of coding issignal Sbd_manch		:	std_logic := '0';--曼切斯特码内部信号signal Sbd_NRZ			:	std_logic := '0';--串行码元signal Sbd_NRZ_reg	:	std_logic_vector(2 downto 0) := (others => '0');--串行码元(经3个时钟延时)signal Sbd_cnt			:	integer range 0 to head_wide + dat_wide +10 := 0;signal Sbd_data		:	std_logic_vector( dat_wide + 7 downto 0) := ( others => '0' );signal Sbd_crc_1		:	std_logic_vector( 7 downto 0 ) := ( others => '0' );begin
----------------------------------------------------------------------------------
--组合运算
----------------------------------------------------------------------------------	Pod_manch	<=	Sbd_manch;Sbd_data		<= Pid_data & Sbd_crc_1;
----------------------------------------------------------------------------------
--NRZ串行码延时两个时钟进程,通过两个D触发器实现
----------------------------------------------------------------------------------	
Pr_d	:	process(Clk)beginif rising_edge(Clk) thenif Clk_div_2 = '1' thenSbd_NRZ_reg(0) <= Sbd_NRZ;Sbd_NRZ_reg(1) <= Sbd_NRZ_reg(0);Sbd_NRZ_reg(2) <= Sbd_NRZ_reg(1);elsenull;end if;end if;end process;----------------------------------------------------------------------------------
--时钟计数进程,计数值Sbd_cnt用于对并转串和编码进程进行控制
----------------------------------------------------------------------------------		
Pr_count	:	process(Clk)	begin	if rising_edge(Clk) then		if Clk_div_2 = '1' thenif Sbd_cnt < (head_wide + dat_wide +10) then--4+21+8+2=35Sbd_cnt <= Sbd_cnt + 1;elseSbd_cnt <= 0;end if;elsenull;end if;end if;end process;
----------------------------------------------------------------------------------
--并转串进程,通过计数移位的方式实现,并行输入:Pid_data,串行输出:Sbd_NRZ
----------------------------------------------------------------------------------
Pr_1	:	process(CLK)beginif rising_edge(CLK) thenif Clk_div_2 = '1' thencase Sbd_cnt iswhen 0	=>	Sbd_crc_1 <= ( others => '0' );when 1	=>Sbd_crc_1 <= nextCRC8_D1( Sbd_data( 28 ), Sbd_crc_1);when 2 to dat_wide	=>Sbd_NRZ 		<= Sbd_data( (dat_wide + 7) - conv_integer( Sbd_cnt - 2 ) );--并转串Sbd_crc_1 	<= nextCRC8_D1( Sbd_data( (dat_wide + 7) - conv_integer( Sbd_cnt - 1 ) ), Sbd_crc_1);when dat_wide + 1 to dat_wide + 9	=>Sbd_NRZ <= Sbd_data( (dat_wide + 7) - conv_integer( Sbd_cnt - 2 ) );--并转串when others	=>Sbd_NRZ <= '0';end case;elsenull;end if;end if;end process;----------------------------------------------------------------------------------
--曼切斯特编码进程,加入3个时钟的高电平同步头,编码完成输出标志位Poc_flag
----------------------------------------------------------------------------------Pr_2	:	process(Clk)beginif rising_edge(Clk) thencase Sbd_cnt iswhen 0 to 1		=>	Sbd_manch <= '0'; when 2 to head_wide + 1	=>Sbd_manch <= '1';when head_wide + 2 to 34	=>if Sbd_NRZ_reg(2) = '1' thenSbd_manch <= not Clk_div_2;elseSbd_manch <= Clk_div_2;end if;when others		=>Sbd_manch <= '0'; end case;end if;end process;
end Behavioral;

曼彻斯特解码

解码采用状态机实现,分为三个状态:idle(空闲),decod(编码),error(错误)。解码流程如下:1、判断同步头,连续接收到4个高电平即可认为是同步头。2、判断是接收的一位数据是0还是1,详情见下图示意。3、接收到指定长度的数据后串转并输出。
判断数据
判断接收的数据,在 计数器为01的时刻判断,如果此时接收的电平为高电平就判断为1,反之为0。上述通过01时刻就可以判断出数据为0或1,增加10时刻判断是因为01时刻此时的寄存器还没更新数据,从寄存器读到的数据是旧的数据,而10时刻寄存器已更新。


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use work.PCK_CRC8_D1.ALL;entity decoding isgeneric (dat_wide		: integer := 21);Port ( 	CLK								: in  STD_LOGIC;DECODE_EN						: in  STD_LOGIC;MANCHESTER_WITHOUT_HEADER	: in  STD_LOGIC;	--输入的曼切斯特码DECODE_ERROR					: out	STD_LOGIC;DECODE_OUT						: out std_logic_vector( (dat_wide-1) downto 0)	--解码后的串行编码);
end decoding;architecture Behavioral of decoding is
----------------------------------------------------------------------------------signal crc8_data_reg 		:	std_logic_vector( 7 downto 0 ) := (others => '0');signal crc8_data				:	std_logic_vector( 7 downto 0 ) := (others => '0');signal manchester_data		:  std_logic_vector( dat_wide + 8 downto 0) := (others => '0');signal decode_reg1			:	std_logic := '0';signal decode_reg2			:	std_logic := '0';signal decode_coder			:	std_logic := '0';--输出串行码元内部信号signal coder_cnt				:	std_logic_vector( 1 downto 0 ) := (others => '0');--时钟计数--signal coder_fall_cnt		:	std_logic_vector( 1 downto 0 ) := (others => '0');--时钟计数,用于判断码的‘0’‘1’状态signal manchester_cnt		:	std_logic_vector( 4 downto 0 ) := (others => '0');--signal decoder_end			:	std_logic := '0';signal decoder_end_reg		:	std_logic := '0';signal decod_end_reg_cnt1	:	std_logic_vector(10 downto 0) := (others => '0');begin
----------------------------------------------------------------------------------
--组合运算 
----------------------------------------------------------------------------------
--	DECODE_OUT	<= manchester_data(28 downto 8);
--	Pod_crc 		<= crc8_data;
----------------------------------------------------------------------------------
--曼切斯特码解码
----------------------------------------------------------------------------------Pr_rising_cnt_CLK	:	process(CLK)beginif falling_edge(CLK) thenif DECODE_EN = '0' thencoder_cnt <= (others => '0');								elseif coder_cnt < "10" then--3coder_cnt <= coder_cnt + 1; elsecoder_cnt <= "01";end if;end if;end if;end process;----------------------------------------------------------------------------------
--判断电平
----------------------------------------------------------------------------------				Pr_just	:	process(CLK)beginif rising_edge(CLK) thenif DECODE_EN = '0' thendecode_reg1 <= '0';decode_reg2 <= '0';elseif (coder_cnt = "01") thenif MANCHESTER_WITHOUT_HEADER = '0' thendecode_reg1 <= '0';decode_reg2 <= '1';elsedecode_reg1 <= '1';decode_reg2 <= '0';end if;elsenull;end if;end if;end if;end process;Pr_decode	:	process(CLK)beginif rising_edge(CLK) thenif DECODE_EN = '0' thenDECODE_ERROR <= '0';decode_coder <= '0';elseif coder_cnt = "10" thenif decode_reg1 = '0' and decode_reg2 = '1' thendecode_coder <= '0';DECODE_ERROR <= '0';elsif decode_reg1 = '1' and decode_reg2 = '0' thendecode_coder <= '1';DECODE_ERROR <= '0';elseDECODE_ERROR <= '1';end if;elseDECODE_ERROR <= '0';end if;end if;end if;end process;									----------------------------------------------------------------------------------	
--串转并处理和CRC8校验
----------------------------------------------------------------------------------				Pr_tran	:	process(CLK)beginif rising_edge(CLK) thenif DECODE_EN = '0' thenmanchester_cnt <= (others => '0');crc8_data_reg <= (others => '0');decoder_end <= '0';elseif coder_cnt < "10" then--7manchester_cnt <= manchester_cnt;elsemanchester_cnt <= manchester_cnt + 1;manchester_data ( (dat_wide + 8) - conv_integer( manchester_cnt ) ) <= decode_coder;--以串行码开头作为高位if manchester_cnt < dat_wide+1 then--21decoder_end <= '0';crc8_data_reg <= nextCRC8_D1( decode_coder, crc8_data_reg);elsif manchester_cnt < (dat_wide + 8) then--29decoder_end <= '0';elsedecoder_end <= '1';
--						DECODE_OUT	<= manchester_data(28 downto 8);crc8_data <= crc8_data_reg;end if;end if;end if;end if;end process;
----------------------------------------------------------------------------------
--输出标志位
----------------------------------------------------------------------------------Pr_d	:	process(CLK)beginif rising_edge(CLK) thendecod_end_reg_cnt1(0) 				<= decoder_end;decod_end_reg_cnt1(10 downto 1) 	<= decod_end_reg_cnt1(9 downto 0);decoder_end_reg 						<= decod_end_reg_cnt1(10);end if;end process;Pr_mark	:	process(CLK)beginif rising_edge(CLK) thenif ( crc8_data = manchester_data(7 downto 0) )and ( decoder_end_reg = '1' ) thenDECODE_OUT	<= manchester_data((dat_wide + 7) downto 8);elsenull;end if;end if;end process;
end Behavioral; 

这篇关于Quartus 曼彻斯特码 CRC校验的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/741259

相关文章

校验码:奇偶校验,CRC循环冗余校验,海明校验码

文章目录 奇偶校验码CRC循环冗余校验码海明校验码 奇偶校验码 码距:任何一种编码都由许多码字构成,任意两个码字之间最少变化的二进制位数就称为数据检验码的码距。 奇偶校验码的编码方法是:由若干位有效信息(如一个字节),再加上一个二进制位(校验位)组成校验码。 奇校验:整个校验码中1的个数为奇数 偶校验:整个校验码中1的个数为偶数 奇偶校验,可检测1位(奇数位)的错误,不可纠错。

web登录校验

基础登录功能 LoginController @PostMapping("/login")Result login(@RequestBody Emp emp) {log.info("前端,发送了一个登录请求");Emp e = empService.login(emp);return e!=null?Result.success():Result.error("用户" +"名或密码错误");

checksum 与 CRC的不同之处

实际应用: CRC:在外发电压时,在报文的最后两个字节做了CRC计算。 checksum : 在按键状态外发,在报文的最后一个字节做了checksum计算。 它们的共同之处:目的都是为了数据的错误检测功能。 只是在算法的复杂度上有较大的区别: 总的来说,CRC算法更复杂,可检测的错误也比较丰富。 CRC与checksum的计算方式都是固定的吗? 在实际应用中,并没有通知对方,所用

spring数据校验Validation

文章目录 需要的依赖创建校验对象Validator 需要的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency> 创建校验对象Validator 测试的实体类 //创建实体

spring项目使用邮箱验证码校验

本项目采用免费QQ邮箱验证码方式进行登录安全的校验。 前期工作 申请邮箱安全授权码 打开QQ邮箱官网点击设置 进入设置页面后点击账户按钮  进入账户后一直往下拉页面找到POP3服务栏,然后点击管理服务(如果没有开启服务需要先开启服务,按照邮箱提示操作即可) 进入管理服务页面后如果没有授权码,点击生成授权码,如果有即可进入授权码管理页面查看。 授权码过一段时间会自动过期,需要重

zdppy+vue3+onlyoffice文档管理系统实战 20240906 上课笔记 整合权限校验中间件

基于角色方法的中间件基本用法 import zdppy_api as apiimport zdppy_apimidauthasync def index(request):return api.resp.success()async def login(request):token = zdppy_apimidauth.get_role_token(role="admin")return ap

Spring源码学习--使用XML Schema文档对XML实例文档校验

文章摘要 在实际开发中读取xml文档的时候,一般都需要先校验,如果使用Sun的XML相关软件包会令你云里雾里。W3C这块的XML相关的规范相当的多,这也是导致XML处理器起来费劲的主要原因。如果xml对应的xsd文档已经定义好,则可以之间复用下面代码对xml文档格式和内容是否合法进行验证。 一、xsd校验xml工具类 import javax.xml.parsers.SA

struts2 xml validator 校验

分类: 【字段校验】  ---- field-validator   ---- 字段优先,我去校验谁(字段),我用谁(校验器)来校验 【非字段校验】  ---- validator  ---- 校验器优先,我用谁(校验器)来校验,我去校验谁(字段) ****** 这两种只是  表现形式  不同,底层是相同的,都是把错误信息放到fielder

【LoRa】打开硬件CRC校验功能,但没有起作用?

目录 1 前言2 解析3 结论 1 前言 在使用LoRa模式(非FSK)时,可能遇到明明RX端已经打开CRC校验了,为什么payload错误了,没有报CRC error中断?本章就这个问题展开讲讲,如何正确使用芯片的硬件CRC校验,并延申到CR和payload length的使用。 2 解析 确实存在前言中的现象,前提是使用的explicit header模式,即有heade