基于国产京微齐力FPGA-M5的DDS实现

本文中用到的所有附加文件,均打包至百度网盘。

链接:https://pan.baidu.com/s/1sBRTj8nkF6ynLFDN0qiV_A 
提取码:unh7

完整工程下载地址:DDS_SIN.rar-硬件开发文档类资源-CSDN下载

简介

京微齐力是除美国外最早进入自主研发、规模生产、批量销售通用FPGA芯片及新一代异构可编程计算芯片的企业之一。公司团队申请了近200件专利和专有技术(含近50件PCT/美国专利),具备独立完整的自主知识产权。其产品将FPGA与CPU、MCU、Memory、ASIC、AI等多种异构单元集成在同一芯片上,实现了可编程、自重构、易扩展、广适用、多集成、高可靠、强算力、长周期等特点。

使用产品

本文所用的产品为京微齐力FPGA-M5系列产品:M5C06N3T100C7。

M5(金山)是一款集成了增强型8051MCU和高性能FPGA的智能型器件。它采用全新的Tile架构,使得FPGA的硬件性能大幅提升。M5基于单芯片的可配置应用平台(CAP),能够提供灵活的FPGA和低成本高性能的微处理器,是设计开发者的最佳选择。

本次设计使用的主要模块即8051MCU核。

实现功能

使用Fuxi EDA和M5 FPGA实现信号发生器(包括正弦波、三角波、锯齿波、方波)。

实现步骤

一、软件下载

下载软件主要包括:

Fuxi2020.1

keil5及C51支持包

具体下载步骤见如下网址:京微齐力 FUXI下载安装说明_HappyZGG的博客-CSDN博客

二、利用matlab生成波形数组

在后面的程序中直接使用各波形生成数组,也可根据需求自行生成波型数组。

生成的数组文件ROM_SIN.txt,可在程序同路径下查看。

//以正弦波为例,其它波形根据函数做出部分修改即可
clc;clear all;close all
 
%% 生成正弦波信号
f = 1000;       % 信号频率,1000Hz
T = 1/f;
N = 200;        % 每个周期200pts
A = 1;          % 振幅
phrase = 0;     % 相位
w = 2*pi*f;

dt = T/N;       % 采样信号周期
x = 0:dt:T;     % x为1*N的矩阵,表示离散时间序列

sin_wave = A*sin(w*x+phrase);   % 正弦波
% sin_wave=sawtooth(w*x,0.5);
% sin_wave=sawtooth(w*x);
%sin_wave=square(w*x,50);

%% 量化位宽
width = 7;         % 数据宽度8位
 
%% 量化滤波器系数
% 量化正弦波形数据并取整
sin_data  = round(sin_wave .* 2^(width - 1));   % 1*N的幅度矩阵,对0-A的幅度均匀量化到0-2^(width-1)的范围上    

data_com_sin = zeros(1,length(sin_data));

for i = 1:length(sin_data)
        data_com_sin(i) = 2^(width) + sin_data(i);
end
% plot(data_com_sin);axis([0 100 -2000 2000]);grid on;

sin_bin = dec2hex(data_com_sin);            % 十进制转十六进制
%%输出到文件
fid = fopen('ROM_sin.txt','w+');
for i=1 : length(sin_bin)
 if mod(i,9)==0

     fprintf(fid,'0x%c%c,\n',sin_bin(i,1),sin_bin(i,2));
 else
    fprintf(fid,'0x%c%c,',sin_bin(i,1),sin_bin(i,2));
 end
end
fclose(fid);

三、编写8051MCU核生成正弦波.hex文件

1. 新建工程

打开Keil uVision5,新建工程

确定存储位置并命名后,选择芯片HME-M5

 工程新建成功

2.添加头文件(.h) 

 为方便编程且提高程序的可读性,导入部分头文件,以简化语句。

将头文件(BasicDataType.h ,CME-M5.h)复制到与后续编写的.c文件同一个目录下即可,本例所用头文件在文章开头的网盘链接中给出。(下图中的.c文件是在下一步中生成的)

3.编写8051程序

1)添加文件:右键新建的组 - [Add New item  to Group 'xxx'...]

命名文件,点击 [Add] 

 2)在新建的.c文件中,编写代码(正弦波生成)

#include "CME-M5.h"
#include "BasicDataType.h"
 
// 正弦波
UINT8 code sine_table[]	={
0x80,0x82,0x84,0x86,0x88,0x8A,0x8C,0x8E,0x90,
0x92,0x94,0x96,0x98,0x99,0x9B,0x9D,0x9F,0xA1,
0xA2,0xA4,0xA6,0xA7,0xA9,0xAA,0xAC,0xAD,0xAF,
0xB0,0xB1,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,
0xBA,0xBB,0xBC,0xBC,0xBD,0xBD,0xBE,0xBE,0xBF,
0xBF,0xBF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
0xBF,0xBF,0xBF,0xBE,0xBE,0xBD,0xBD,0xBC,0xBC,
0xBB,0xBA,0xB9,0xB8,0xB7,0xB6,0xB5,0xB4,0xB3,
0xB1,0xB0,0xAF,0xAD,0xAC,0xAA,0xA9,0xA7,0xA6,
0xA4,0xA2,0xA1,0x9F,0x9D,0x9B,0x99,0x98,0x96,
0x94,0x92,0x90,0x8E,0x8C,0x8A,0x88,0x86,0x84,
0x82,0x80,0x7E,0x7C,0x7A,0x78,0x76,0x74,0x72,
0x70,0x6E,0x6C,0x6A,0x68,0x67,0x65,0x63,0x61,
0x5F,0x5E,0x5C,0x5A,0x59,0x57,0x56,0x54,0x53,
0x51,0x50,0x4F,0x4D,0x4C,0x4B,0x4A,0x49,0x48,
0x47,0x46,0x45,0x44,0x44,0x43,0x43,0x42,0x42,
0x41,0x41,0x41,0x40,0x40,0x40,0x40,0x40,0x40,
0x40,0x41,0x41,0x41,0x42,0x42,0x43,0x43,0x44,
0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
0x4D,0x4F,0x50,0x51,0x53,0x54,0x56,0x57,0x59,
0x5A,0x5C,0x5E,0x5F,0x61,0x63,0x65,0x67,0x68,
0x6A,0x6C,0x6E,0x70,0x72,0x74,0x76,0x78,0x7A,
0x7C,0x7E,0x80
};

// 三角波
UINT8 code tri_table[]	={
0x40,0x41,0x43,0x44,0x45,0x46,0x48,0x49,0x4A,
0x4C,0x4D,0x4E,0x4F,0x51,0x52,0x53,0x54,0x56,
0x57,0x58,0x5A,0x5B,0x5C,0x5D,0x5F,0x60,0x61,
0x63,0x64,0x65,0x66,0x68,0x69,0x6A,0x6C,0x6D,
0x6E,0x6F,0x71,0x72,0x73,0x74,0x76,0x77,0x78,
0x7A,0x7B,0x7C,0x7D,0x7F,0x80,0x81,0x83,0x84,
0x85,0x86,0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x8F,
0x91,0x92,0x93,0x94,0x96,0x97,0x98,0x9A,0x9B,
0x9C,0x9D,0x9F,0xA0,0xA1,0xA3,0xA4,0xA5,0xA6,
0xA8,0xA9,0xAA,0xAC,0xAD,0xAE,0xAF,0xB1,0xB2,
0xB3,0xB4,0xB6,0xB7,0xB8,0xBA,0xBB,0xBC,0xBD,
0xBF,0xC0,0xBF,0xBD,0xBC,0xBB,0xBA,0xB8,0xB7,
0xB6,0xB4,0xB3,0xB2,0xB1,0xAF,0xAE,0xAD,0xAC,
0xAA,0xA9,0xA8,0xA6,0xA5,0xA4,0xA3,0xA1,0xA0,
0x9F,0x9D,0x9C,0x9B,0x9A,0x98,0x97,0x96,0x94,
0x93,0x92,0x91,0x8F,0x8E,0x8D,0x8C,0x8A,0x89,
0x88,0x86,0x85,0x84,0x83,0x81,0x80,0x7F,0x7D,
0x7C,0x7B,0x7A,0x78,0x77,0x76,0x74,0x73,0x72,
0x71,0x6F,0x6E,0x6D,0x6C,0x6A,0x69,0x68,0x66,
0x65,0x64,0x63,0x61,0x60,0x5F,0x5D,0x5C,0x5B,
0x5A,0x58,0x57,0x56,0x54,0x53,0x52,0x51,0x4F,
0x4E,0x4D,0x4C,0x4A,0x49,0x48,0x46,0x45,0x44,
0x43,0x41,0x40
};

锯齿波
UINT8 code saw_table[]	={
0x40,0x41,0x41,0x42,0x43,0x43,0x44,0x44,0x45,
0x46,0x46,0x47,0x48,0x48,0x49,0x4A,0x4A,0x4B,
0x4C,0x4C,0x4D,0x4D,0x4E,0x4F,0x4F,0x50,0x51,
0x51,0x52,0x53,0x53,0x54,0x54,0x55,0x56,0x56,
0x57,0x58,0x58,0x59,0x5A,0x5A,0x5B,0x5C,0x5C,
0x5D,0x5D,0x5E,0x5F,0x5F,0x60,0x61,0x61,0x62,
0x63,0x63,0x64,0x64,0x65,0x66,0x66,0x67,0x68,
0x68,0x69,0x6A,0x6A,0x6B,0x6C,0x6C,0x6D,0x6D,
0x6E,0x6F,0x6F,0x70,0x71,0x71,0x72,0x73,0x73,
0x74,0x74,0x75,0x76,0x76,0x77,0x78,0x78,0x79,
0x7A,0x7A,0x7B,0x7C,0x7C,0x7D,0x7D,0x7E,0x7F,
0x7F,0x80,0x81,0x81,0x82,0x83,0x83,0x84,0x84,
0x85,0x86,0x86,0x87,0x88,0x88,0x89,0x8A,0x8A,
0x8B,0x8C,0x8C,0x8D,0x8D,0x8E,0x8F,0x8F,0x90,
0x91,0x91,0x92,0x93,0x93,0x94,0x94,0x95,0x96,
0x96,0x97,0x98,0x98,0x99,0x9A,0x9A,0x9B,0x9C,
0x9C,0x9D,0x9D,0x9E,0x9F,0x9F,0xA0,0xA1,0xA1,
0xA2,0xA3,0xA3,0xA4,0xA4,0xA5,0xA6,0xA6,0xA7,
0xA8,0xA8,0xA9,0xAA,0xAA,0xAB,0xAC,0xAC,0xAD,
0xAD,0xAE,0xAF,0xAF,0xB0,0xB1,0xB1,0xB2,0xB3,
0xB3,0xB4,0xB4,0xB5,0xB6,0xB6,0xB7,0xB8,0xB8,
0xB9,0xBA,0xBA,0xBB,0xBC,0xBC,0xBD,0xBD,0xBE,
0xBF,0xBF,0x40
};

//方波
UINT8 code square_table[]={
0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
0xC0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0x40,0x40,0xC0
};
 
 
void main(void)
{
	UINT8 k;
	CKCON = 0x11; 
    EAL = 1;      //è????D??ê1?ü
  
    while(1)
		{
 
			for(k=1;k<201;k++)
			{
				P0 = sine_table[k];
				P1 = tri_table[k];
				P2 = saw_table[k];
				P3 = square_table[k];
			}
		}
 
}

注:①代码中乱码的注释,在keil5中变成中文,反之,在keil5中编写中文注释,显示乱码,推荐使用英文注释

      ②根据本文设计的功能,编写的程序是用来实现正弦波发生器的,若想实现其他功能,只需根据头文件中的定义,自行编写程序即可。

4.生成.hex文件

 1)点击[Options for Target...]

 2)选中[output] - 勾选[Create HEX File]

3)编译生成.hex文件,点击[Translate] 

 再点击[Build]

 成功生成.hex文件

 在工程文件下的Objects文件夹中查看

 到此,在keil中的设计过程就结束了,接下来是使用Fuxi EDA软件的过程。

四、使用Fuxi 2020.1配置FPGA

 1.新建工程

 1)完成命名后,点击[Next]

 2)选择芯片 - 点击[finish]

 2.配置IP核

点击[Tool] - [Wizard Manager] ,启动 IP 向导

 [Create a new design] - [Next] 

1)例化8051 MCU

在IP Cores列表里选择[8051 MCU],点击[Next]

Module name任意修改(本例为mcu-51),其余默认,点击Next

选择左侧List中使用的管脚,至如下界面,点击[Next]

 选择[yes,initialize it ....],导入之前生成的.hex文件,初始化8051MCU,[finish]完成

 2)例化OSC

在IP Cores列表里选择[Oscillator],点击[Next]

 Module name任意修改(本例为oscillator),其余默认,点击Next

 无源晶振选择OSCILLATOR,有源晶振原则CRYSTAL(本例为CRYSTAL),点击Finish完成

3.添加主程序,编写代码

1)新建文件,右键工程文件 - [Add New File...]

 命名文件并存储

 2)在新建文件中,编写代码

module DDS_sin(
    input  [3:0] Mode,
	output reg [7:0] sin,
	output DA_clk
);
 
//io port
wire [7:0] port0o;
reg [7:0] port0i;
wire [7:0] port1o;
wire [7:0] port1i;
wire [7:0] port2o;
wire [7:0] port2i;	
wire [7:0] port3o;
wire [7:0] port3i;

//clock 
wire clkin;       // 晶振时钟
assign  DA_clk = clkin;    // 输出DA转换时钟


always@(*) begin
	case(Mode)
		4'b1110: sin = port0o; //正弦波
		4'b1101: sin = port1o; //三角波
		4'b1011: sin = port2o; //锯齿波
		4'b0111: sin = port3o; //方波   
        default: ;
	endcase
end

 
// 例化晶振驱动20MHz
oscillator oscillator (
	.clkout (clkin)
);
 
// 例化硬核8051
mcu_51 mcu_51(
    .clkcpu     (clkin   ),
    .resetn     (1'b1      ),
    .port0i 	(port0i    ), //8 bit input port
    .port1i 	(port1i    ),
    .port2i 	(port2i    ),
    .port3i 	(port3i    ),
    .port0o 	(port0o    ), //8 bit output port
    .port1o 	(port1o    ),
    .port2o 	(port2o    ),
    .port3o 	(port3o    )
);
 
endmodule

3)将主程序设置为顶层模块

右键主程序模块-[Set As Top Module]

 4.综合

[Flow] - [Run Synthesis]

5.配置IO管脚

[Tools] - [IO Editor]

根据管脚表,找到按钮BUTTON对应的管脚号分配给Mode输入管脚,,DA_clk和sin输出任意配置IO口。

具体配置如下: 

6.编译工程

[Flow] - [Run Project]

编译成功

 五、上板测试

1.下载配置文件至器件

将硬件连接至电脑,点击[Downloader],进入下载界面,选择所需下载的.acf 配置文件,点击 Program 即可。

 2.根据管脚配置,连接8位DA转换器,输出波形到示波器。

在此例中,我们是用的是正点原子的8位DA转换器。根据分配给sin输出的管脚接线,并将DA_clk接到DA转换器时钟输入。

最终,在硬件上调节四个开关得到不同波形,但要注意每次更换波形时需要按下RESET按钮,才可更换波形。

 


虽然,国产FPGA的发展逐渐开始起色,但网络上有关国产FPGA的资料仍然屈指可数,在此附上对此文有贡献的参考文章,表示感谢。

CME-M5系列(四)——SoC之Blink_chinastand的专栏-CSDN博客

京微齐力 FPGA-M5 学习(一)- 开发环境_KVEN33的博客-CSDN博客

基于FPGA的DDS在Vivado中仿真以及在ZYNQ7020上板的实现(1)_syyzuiqiang的博客-CSDN博客

参与人员:  HappyZGG的博客_CSDN博客-领域博主                   lolipop、的博客_CSDN博客-领域博主

有问题可发邮件咨询:sunxj1122@163.com

  • 16
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值