通信 - Verilog实现相关捕获(帧同步)代码

帧同步的相关捕获。在matlab上实现相关捕获的仿真只需要几行相乘相加就可以,但是硬件实现时候确是比较复杂的,尤其是需要不停进行移位相乘相加,手动写这个代码,那Ctrl+C + Ctrl+V到心碎,还容易出错。今天突发奇想,采用C/C++语言通过写文件的方式来编写相关捕获的Verilog代码,进行了一下仿真,功能仿真(前仿)正确。这里,记录一波骚操作。

// 用于实现相关捕获的verilog代码
// 2019-05-19

#include <iostream>
#include <time.h>

using namespace std;

#define		LEN		512

void module_declaration(FILE* fp);
void variable_declaration(FILE* fp);
void shift_register(FILE* fp);
void multi_mSeq_local(FILE* fp);
void addr_reg_module0(FILE* fp);
void addr_reg1_1st(FILE* fp);
void addr_reg2_2nd(FILE* fp);
void addr_reg3_3rd(FILE* fp);
void addr_reg4_4th(FILE* fp);
void addr_reg5_5th(FILE* fp);
void addr_reg6_6th(FILE* fp);
void addr_reg7_7th(FILE* fp);
void addr_reg8_8th(FILE* fp);
void addr_reg9_9th(FILE* fp);
void module_end(FILE* fp);


int main()
{
	FILE* fp = fopen("Shift_Register.v", "w");

	module_declaration(fp);
	variable_declaration(fp);
	//init_mSeq(fp);
	shift_register(fp);
	multi_mSeq_local(fp);
	addr_reg1_1st(fp);
	addr_reg2_2nd(fp);
	addr_reg3_3rd(fp);
	addr_reg4_4th(fp);
	addr_reg5_5th(fp);
	addr_reg6_6th(fp);
	addr_reg7_7th(fp);
	addr_reg8_8th(fp);
	addr_reg9_9th(fp);
	module_end(fp);

	fclose(fp);

	return 0;
}

// 模块声明
void module_declaration(FILE* fp)
{
	if (fp){
		time_t	curTime = time(NULL);
		struct tm* sysTime = localtime(&curTime);
		fprintf(fp, "// %d-%02d-%02d %02d:%02d:%02d \n\n\n", sysTime->tm_year + 1900, sysTime->tm_mon + 1, sysTime->tm_mday, sysTime->tm_hour, sysTime->tm_min, sysTime->tm_sec);

		fprintf(fp, "module Shift_Register(\n");
		fprintf(fp, "							clk,\n");
		fprintf(fp, "							reset,\n");
		fprintf(fp, "							data_in,\n");
		fprintf(fp, "							relate_peak\n");
		fprintf(fp, "						);\n\n");

		fprintf(fp, "input	wire				clk, reset;\n");
		fprintf(fp, "input	wire[11 : 0]		data_in;\n");
		fprintf(fp, "output	reg	[20 : 0]		relate_peak;\n\n\n");
	}
}


//变量声明
void variable_declaration(FILE* fp)
{
	if (fp){
		fprintf(fp, "reg	signed	[ 1 : 0]		m[511 : 0];\n");
		fprintf(fp, "reg	signed	[11 : 0]		shift_reg[511 : 0];\n\n\n");

		fprintf(fp, "reg	signed	[11 : 0]		adder_reg0[511 : 0];\n");
		fprintf(fp, "reg	signed	[12 : 0]		adder_reg1[255 : 0];\n");
		fprintf(fp, "reg	signed	[13 : 0]		adder_reg2[127 : 0];\n");
		fprintf(fp, "reg	signed	[14 : 0]		adder_reg3[63 : 0];\n");
		fprintf(fp, "reg	signed	[15 : 0]		adder_reg4[31 : 0];\n");
		fprintf(fp, "reg	signed	[16 : 0]		adder_reg5[15 : 0];\n");
		fprintf(fp, "reg	signed	[17 : 0]		adder_reg6[7 : 0];\n");
		fprintf(fp, "reg	signed	[18 : 0]		adder_reg7[3 : 0];\n");
		fprintf(fp, "reg	signed	[19 : 0]		adder_reg8[1 : 0];\n");
		//fprintf(fp, "%s\n", "reg	signed	[20 : 0]		adder_reg9;");
		fprintf(fp, "\n\n\n");
	}
}

// 移位操作
void shift_register(FILE* fp)
{
	if (fp){
		fprintf(fp, "always@(posedge clk, negedge reset)\n");
		fprintf(fp, "begin\n");
		fprintf(fp, "	if(!reset)\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN; i++){	
			fprintf(fp, "		shift_reg[%d]		<=	12'd0;\n", i);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "	else\n");
		fprintf(fp, "	begin\n");
		for (int i = 1; i < LEN; i++){
			fprintf(fp, "		shift_reg[%d]		<=	shift_reg[%d];\n", i - 1, i);
		}
		fprintf(fp, "		shift_reg[%d]		<=	data_in;\n", LEN - 1);
		fprintf(fp, "	end\n");
		fprintf(fp, "end\n\n\n\n");
	}
}

// 与本地m序列相乘
void multi_mSeq_local(FILE* fp)
{
	FILE* fm = fopen("m_Seq.txt", "r");
	if (fp && fm){
		fprintf(fp, "wire	signed	[11 : 0]	mult_result[511 : 0];\n\n");

		fprintf(fp, "always@(posedge clk, negedge reset)\n");
		fprintf(fp, "begin\n");
		fprintf(fp, "	if(!reset)\n");
		fprintf(fp, "	begin\n");
		char str[4];
		for (int i = 0; i < LEN; i++){
			fgets(str, 4, fm);
			fprintf(fp, "		m[%d]		<=	2'b%c%c;\n", i, str[0], str[1]);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "	else\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN; i++){
			fprintf(fp, "		adder_reg0[%d]		<=	mult_result[%d];\n", i, i);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "end\n\n\n\n");

	}
}

void addr_reg1_1st(FILE* fp)
{
	if (fp){
		fprintf(fp, "always@(posedge clk, negedge reset)\n");
		fprintf(fp, "begin\n");
		fprintf(fp, "	if(!reset)\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN / 2; i++){
			fprintf(fp, "		adder_reg1[%d]		<=	13'd0;\n", i);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "	else\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN / 2; i++){
			fprintf(fp, "		adder_reg1[%d]		<=	adder_reg0[%d]	+	adder_reg0[%d];\n", i, 2 * i, 2 * i + 1);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "end\n\n\n\n");
	}
}

void addr_reg2_2nd(FILE* fp)
{
	if (fp){
		fprintf(fp, "always@(posedge clk, negedge reset)\n");
		fprintf(fp, "begin\n");
		fprintf(fp, "	if(!reset)\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN / 4; i++){
			fprintf(fp, "		adder_reg2[%d]		<=	14'd0;\n", i);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "	else\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN / 4; i++){
			fprintf(fp, "		adder_reg2[%d]		<=	adder_reg1[%d]	+	adder_reg1[%d];\n", i, 2 * i, 2 * i + 1);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "end\n\n\n\n");
	}
}

void addr_reg3_3rd(FILE* fp)
{
	if (fp){
		fprintf(fp, "always@(posedge clk, negedge reset)\n");
		fprintf(fp, "begin\n");
		fprintf(fp, "	if(!reset)\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN / 8; i++){
			fprintf(fp, "		adder_reg3[%d]		<=	15'd0;\n", i);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "	else\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN / 8; i++){
			fprintf(fp, "		adder_reg3[%d]		<=	adder_reg2[%d]	+	adder_reg2[%d];\n", i, 2 * i, 2 * i + 1);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "end\n\n\n\n");
	}
}

void addr_reg4_4th(FILE* fp)
{
	if (fp){
		fprintf(fp, "always@(posedge clk, negedge reset)\n");
		fprintf(fp, "begin\n");
		fprintf(fp, "	if(!reset)\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN / 16; i++){
			fprintf(fp, "		adder_reg4[%d]		<=	16'd0;\n", i);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "	else\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN / 16; i++){
			fprintf(fp, "		adder_reg4[%d]		<=	adder_reg3[%d]	+	adder_reg3[%d];\n", i, 2 * i, 2 * i + 1);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "end\n\n\n\n");
	}
}

void addr_reg5_5th(FILE* fp)
{
	if (fp){
		fprintf(fp, "always@(posedge clk, negedge reset)\n");
		fprintf(fp, "begin\n");
		fprintf(fp, "	if(!reset)\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN / 32; i++){
			fprintf(fp, "		adder_reg5[%d]		<=	17'd0;\n", i);
		}
		fprintf(fp, "	end");
		fprintf(fp, "	else");
		fprintf(fp, "	begin");
		for (int i = 0; i < LEN / 32; i++){
			fprintf(fp, "		adder_reg5[%d]		<=	adder_reg4[%d]	+	adder_reg4[%d];\n", i, 2 * i, 2 * i + 1);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "end\n\n\n\n");
	}
}

void addr_reg6_6th(FILE* fp)
{
	if (fp){
		fprintf(fp, "always@(posedge clk, negedge reset)\n");
		fprintf(fp, "begin\n");
		fprintf(fp, "	if(!reset)\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN / 64; i++){
			fprintf(fp, "		adder_reg6[%d]		<=	18'd0;\n", i);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "	else\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN / 64; i++){
			fprintf(fp, "		adder_reg6[%d]		<=	adder_reg5[%d]	+	adder_reg5[%d];\n", i, 2 * i, 2 * i + 1);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "end\n\n\n\n");
	}
}

void addr_reg7_7th(FILE* fp)
{
	if (fp){
		fprintf(fp, "always@(posedge clk, negedge reset)\n");
		fprintf(fp, "begin\n");
		fprintf(fp, "	if(!reset)\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN / 128; i++){
			fprintf(fp, "		adder_reg7[%d]		<=	19'd0;\n", i);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "	else\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN / 128; i++){
			fprintf(fp, "		adder_reg7[%d]		<=	adder_reg6[%d]	+	adder_reg6[%d];\n", i, 2 * i, 2 * i + 1);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "end\n\n\n\n");
	}
}

void addr_reg8_8th(FILE* fp)
{
	if (fp){
		fprintf(fp, "always@(posedge clk, negedge reset)\n");
		fprintf(fp, "begin\n");
		fprintf(fp, "	if(!reset)\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN / 256; i++){
			fprintf(fp, "		adder_reg8[%d]		<=	20'd0;\n", i);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "	else\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN / 256; i++){
			fprintf(fp, "		adder_reg8[%d]		<=	adder_reg7[%d]	+	adder_reg7[%d];\n", i, 2 * i, 2 * i + 1);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "end\n\n\n\n");
	}
}

void addr_reg9_9th(FILE* fp)
{
	if (fp){
		fprintf(fp, "always@(posedge clk, negedge reset)\n");
		fprintf(fp, "begin\n");
		fprintf(fp, "	if(!reset)\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN / 512; i++){
			fprintf(fp, "		relate_peak			<= 	21'd0;");
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "	else\n");
		fprintf(fp, "	begin\n");
		for (int i = 0; i < LEN / 512; i++){
			fprintf(fp, "		relate_peak			<=	adder_reg8[%d]	+	adder_reg8[%d];\n", 2 * i, 2 * i + 1);
		}
		fprintf(fp, "	end\n");
		fprintf(fp, "end\n\n\n\n");
	}
}

// 模块结束
void module_end(FILE* fp)
{
	if (fp){
		for (int i = 0; i < LEN; i++){
			fprintf(fp, "assign mult_result[%d] = (m[%d][1]	!=	shift_reg[%d][11])	?	~shift_reg[%d]	+	12'd1 : (m[%d][1] == 2'd1)	?	~shift_reg[%d]	+	12'd1	:	shift_reg[%d];\n", i, i, i, i, i, i, i);
		}
		fprintf(fp, "\n\n\n\n");
		fprintf(fp, "endmodule\n\n");
	}
}

 

  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FPGA(现场可编程门阵列)和STM32(一种基于ARM架构的微控制器)可以通过SPI(串行外设接口)协议进行通信。在这种通信方式中,FPGA作为SPI通信的从机,而STM32作为主机。 为了实现这种通信,我们需要使用Verilog语言编写从机FPGA的代码。首先,我们需要确定FPGA的SPI接口的基本参数,如数据位宽、时钟频率和时钟极性等。然后,我们可以使用Verilog语言编写从机的SPI控制器,将其连接到FPGA的其他逻辑电路中。 在Verilog代码中,我们需要实现SPI的Slave模式。在SPI通信中,从机始终被动地响应主机的指令,并将数据传送给主机。从机的Verilog代码需要包括两个关键部分:状态机和数据传输。 状态机是从机的控制核心,它根据主机的指令进行状态切换,并管理数据传输过程的流程控制。例如,当主机发起读取指令时,从机会进入接收状态,并将要传输的数据存储到缓冲区中。当主机发起写入指令时,从机会进入发送状态,并将数据从缓冲区传输给主机。 数据传输部分负责实际的数据传输。从机需要实现接收和发送两个功能。接收部分负责接收主机发送的数据,并将其存储到缓冲区中。发送部分负责从缓冲区中读取数据,并将其传输给主机。 在编写Verilog代码时,需要注意时序问题和信号同步。SPI通信需要精确的时钟同步,在从机和主机之间共享和交换数据需要遵循一定的时序要求。因此,在设计代码时要特别注意时钟同步和数据的正确传输顺序。 最后,我们需要将Verilog代码综合到FPGA芯片中,并进行功能验证和调试。在验证过程中,我们可以通过观察FPGA输出波形和和STM32的通信结果来判断通信是否成功。如果通信出现问题,我们可以通过调试代码和时序分析来进行故障排查和修复。 通过以上步骤,我们可以实现FPGA作为从机与STM32进行SPI协议通信,并使用Verilog语言完成代码的设计与实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值