FPGA音乐播放器:ISE中用Coregen生成的ROM怎么在Verilog中读取?
时间:10-02
整理:3721RD
点击:
音乐以简谱的形式存放在coe文件中,比如:1 1 2 2 3 4 5 5 6 6 7 8,一共有21个音从低音1到高音7,可以表示为1~21
已经设计好了分频器模块DFm,时钟是25MHz,可以传递分频倍数(偶数)。
现在想要设计两个模块:
第一个是调用DFm生成1~7音对应的频率:DFm #(分频倍数),音符对应的分频倍数我都算好了,只要举个例子,比如1这个音怎么对应存储DFm输出的频率我就知道了。
第二个是读取ROM中的数据,大概是每0.25秒读一个音(一个数字),然后在上一个模块中找到对应的频率,使之输出到蜂鸣器voi,输出0.25秒
第一个模块我有一点模糊的想法,就是按不同的分频系数例化21个模块,但是这样太复杂了,而且仿真很慢,最大的分频系数是192308....第二个模块首先是不知道怎么读ROM,其次不知道怎么按0.25秒读和输出求大神指导~~用的是ISE,板子是Spartan3E的。
分频器:
已经设计好了分频器模块DFm,时钟是25MHz,可以传递分频倍数(偶数)。
现在想要设计两个模块:
第一个是调用DFm生成1~7音对应的频率:DFm #(分频倍数),音符对应的分频倍数我都算好了,只要举个例子,比如1这个音怎么对应存储DFm输出的频率我就知道了。
第二个是读取ROM中的数据,大概是每0.25秒读一个音(一个数字),然后在上一个模块中找到对应的频率,使之输出到蜂鸣器voi,输出0.25秒
第一个模块我有一点模糊的想法,就是按不同的分频系数例化21个模块,但是这样太复杂了,而且仿真很慢,最大的分频系数是192308....第二个模块首先是不知道怎么读ROM,其次不知道怎么按0.25秒读和输出求大神指导~~用的是ISE,板子是Spartan3E的。
分频出一个4HZ的时钟,然后利用这个时钟做个计数器,计数器的值作为ROM地址(可以控制计数器值计到某个值后从0开始重新计数,达到重复播放的效果)。ROM的片选常开。从ROM中读出的数据经过一个译码器(不同的数据对应不同的分频数),得到分频数,送到分频模块里面(只需要一个分频电路就行了),得到分频时钟,输出到FPGA口上。
十分感谢!不过我还是有点不太清楚,比如我现在建立了一个wonder.xco的ROM,wonder.coe已经导入并且生成了相应的mif文件,我应该怎么在代码里读这个ROM的地址呢?
你用corgen生成ROM时,应该伴随生成了一个.v文件,这个是ROM的模型,把它加到里的仿真环境里面(这个ROM模型中例化了另外一个BLK_MEM_GEN_**的模块,根据其名字,到ISE的安装目录中找到相应的.v模型,也加到仿真环境中去)。同时在你的设计中要例化ROM。ROM的端口定义在模型文件中有描述。
由于ROM已固化了数据,所以mif文件应拷到仿真目录下,仿真工具才能找得到
按你说的方法成功了,添加Core的时候就已经加到工程中了,按.v文件端口列表输出就行了。
还有个问题,我分频器分频系数是parameter类型的,但是音符译码器译出来的分频系数是reg类型的,在例化的时候译出来的分频系数不能传递到分频器模块里,试了一下function好像也不能用parameter作为输出...
附上译码器和分频器代码:
译码器:
- `timescale 1ns / 1ps
- module dfmratio(music,dfmratio);
- input [4:0]music;
- output [17:0]dfmratio;
- reg [17:0]dfmratio;
- always @(music)
- begin
- case(music)
- 5'b00000:dfmratio=192308;
- 5'b00001:dfmratio=171232;
- 5'b00010:dfmratio=152440;
- 5'b00011:dfmratio=143678;
- 5'b00100:dfmratio=127552;
- 5'b00101:dfmratio=113636;
- 5'b00110:dfmratio=101626;
- 5'b00111:dfmratio=95786;
- 5'b01000:dfmratio=85324;
- 5'b01001:dfmratio=75988;
- 5'b01010:dfmratio=71634;
- 5'b01011:dfmratio=63776;
- 5'b01100:dfmratio=56818;
- 5'b01101:dfmratio=50710;
- 5'b01110:dfmratio=47892;
- 5'b01111:dfmratio=42662;
- 5'b10000:dfmratio=37994;
- 5'b10001:dfmratio=35816;
- 5'b10010:dfmratio=31888;
- 5'b10011:dfmratio=28410;
- 5'b10100:dfmratio=25354;
- default dfmratio=0;
- endcase
- end
- endmodule
分频器:
- `timescale 1ns / 1ps
- module DFm
- (
- input CLK_In,
- input RSTn,
- output CLK_Out
- );
- parameter div_N=2;
- reg [div_N:0] count;
- reg clk_N;
- always @ ( posedge CLK_In or negedge RSTn)
- begin
- if(!RSTn)
- begin
- count <= 1'b0;
- clk_N <= 1'b0;
- end
- else if( count == div_N/2 - 1'b1)
- begin
- count <= 1'b0;
- clk_N <= ~clk_N;
- end
- else
- count <= count + 1'b1;
- end
- assign CLK_Out = clk_N;
- endmodule
把分频器的分频系数做成输入端口
我完成了!太感谢了!
借鉴一下。
