最专业的FPGA ZYNQ论坛--黑金动力社区

 找回密码
 注册
楼主: liuhui1987812

在quartus中使用8051核

  [复制链接]
dumao0620 发表于 2012-8-12 10:10:57 | 显示全部楼层
希望好下载,谢谢;
yandaxiaoyao 发表于 2012-8-12 23:56:40 | 显示全部楼层
erilogHDL实现DMA控制器的控制问题
现在要做一个项目,用FPGA来将采集到的视频图像的在SDRAM中。FPGA的片外有两片SDRAM,如何实时地将采集到的视频图像存储到SDRAM中呢?想利用QUARTUS II自带的SDRAM控制器在SOPC中实现,希望高手指点一下如何实现啊。

我现在的想法是自己写一个能控制DMA的控制器的模块,实现《NIOSII 那些事中儿》DMA实验的如下操作
/************************************/
//DMA中断
static void Handle_DMA_Interrupts(void* context, alt_u32 id)
{
        //清除中断标志
        IOWR_ALTERA_AVALON_DMA_STATUS(DMA_BASE, 0);
        //停止DMA传输
        IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE, 0x092);
}

/************************************/
static void DMA_Init(void)    //DMA初始化
{
        //设置传输模式为半字传输
        IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE, 0x092);
        //清除中断标志
        IOWR_ALTERA_AVALON_DMA_STATUS(DMA_BASE, 0);
        //初始化源地址和目的地址
        IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_BASE, SRC_ADDR);
        IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_BASE, DST_ADDR);
        //初始化长度寄存器
        IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_BASE, 2*DAT_LEN);
        //启动DMA
        IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE, 0x09a);
}


我写的VerilogHDL源码如下(此模块最后需要加入SOPC中使用):

module        DMA_Operater
(
        input                        clk,
        input                        rst_n,
      
        //avalon  master port for dma control
        input                        avm_waitrequest,
        output reg[31:0]                         avm_address,
        output reg                avm_read,
        input[31:0]                avm_readdata,
        output reg                avm_write,
        output reg[31:0]                         avm_writedata,
        output reg[3:0]                avm_byteenable,

        //interrupt
        input                        dma_irq,//DMA控制器传输结束后发来的中断,通过接受到中断后关闭DMA传输,此模块中采用检查DMA控制器的状态寄存器来判断DMA传输是否完成

        //export
        input                        vid_clk,//像素时钟
        input                        vid_hs,//行同步信号
      
        //debug port
        output                        dma_busy,//DMA控制器状态信号,用于调试
        output                        dma_done,//DMA控制器状态信号,用于调试
        output reg                dma_start,//启动DMA传输
        output[3:0]                state
);
      
        assign state = i;

        //register define
        reg                        vid_clk_delay;
        reg                        vid_hs_delay;
        reg                        dma_irq_delay;
        reg                        enable;
//        reg                        dma_stop;
      
        reg[31:0]                dma_base_address;
        reg[31:0]                src_base_address;
        reg[31:0]                dst_base_address;
      
        always@(posedge clk or negedge rst_n)
        if(!rst_n)
        begin
                vid_clk_delay <= 1'b0;
                vid_hs_delay <= 1'b0;
                dma_irq_delay <= 1'b0;
                enable <= 1'b0;
                dma_start <= 1'b0;
//                dma_stop <= 1'b0;
        end
        else
        begin
                dma_base_address <= 32'h00000800;//DMA控制器基地址,对DMA控制器进行寄存器操作是使用
                src_base_address <= 32'h00080000;//配置DMA控制器的读数据地址
                dst_base_address <= 32'h00003000;//配置DMA控制器的写数据地址
               
                vid_clk_delay <= vid_clk;
                vid_hs_delay  <= vid_hs;
                dma_irq_delay <= dma_irq;
                dma_start <= vid_hs_delay & (~vid_hs);//vid_hs信号的下降沿启动DMA传输
//                dma_stop <= ~dma_irq_delay & dma_irq;//接收到DMA中断时关闭DMA传输
        end
      

        //dma control
        reg[3:0]                i;//状态信号
        reg[2:0]                j;//此信号的加入只是为了延长对DMA控制器寄存器读写的时间,担心读写地址和控制信号周期不够而加入的,不知道是否有必要?
        reg[31:0]                dma_status_reg;//DMA状态寄存器
      
        assign dma_busy = dma_status_reg[1];
        assign dma_done = dma_status_reg[0];
      
      
      
        always@(posedge clk or negedge rst_n)
        if(!rst_n)
        begin
                i <= 4'b0;
                j <= 3'b0;
                avm_read <= 1'b0;
                avm_address <= 32'b00000000000000000000000000000000;
                avm_write <= 1'b0;
                avm_writedata <= 32'b00000000000000000000000000000000;
                avm_byteenable <= 4'b0000;
        end
        else
        begin
                case(i)
                0:        if(dma_start) begin        i<= i+1; j<=0; end
                        else
                        begin
                                avm_read <= 1'b0;
                                avm_address <= dma_base_address;
                                avm_write <= 1'b0;
                                avm_writedata <= 32'b00000000000000000000000000000000;
                                avm_byteenable <= 4'b0000;
                        end
                1:        begin //对应初始化函数的IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE, 0x092);
                                avm_read <= 1'b0;
                                avm_address <= dma_base_address + 6;
                                avm_write <= 1'b1;
                                avm_writedata <= 32'h00000092;//set transfer mode
                                avm_byteenable <= 4'b1111;
                                                               
                                j<=j+1;
                                if(j==3'b111)
                                        i <= i+1;
                        end
                2:        begin //对应初始化函数的IOWR_ALTERA_AVALON_DMA_STATUS(DMA_BASE, 0);
                                avm_read <= 1'b0;
                                avm_address <= dma_base_address + 0;
                                avm_write <= 1'b1;
                                avm_writedata <= 32'h00000000;//clear interrupt flag
                                avm_byteenable <= 4'b1111;
                              
                                j<=j+1;
                                if(j==3'b111)
                                        i <= i+1;
                        end
                3:        begin //对应初始化函数的IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_BASE, SRC_ADDR);
                                avm_read <= 1'b0;
                                avm_address <= dma_base_address + 1;
                                avm_write <= 1'b1;
                                avm_writedata <= src_base_address;//set dma source address
                                avm_byteenable <= 4'b1111;

                                j<=j+1;
                                if(j==3'b111)
                                        i <= i+1;
                        end
                4:        begin //对应初始化函数的IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_BASE, DST_ADDR);
                                avm_read <= 1'b0;
                                avm_address <= dma_base_address + 2;
                                avm_write <= 1'b1;
                                avm_writedata <= dst_base_address;//set dma dest address
                                avm_byteenable <= 4'b1111;

                                j<=j+1;
                                if(j==3'b111)
                                        i <= i+1;
                        end
                5:        begin //对应初始化函数的IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_BASE, 2*DAT_LEN);
                                avm_read <= 1'b0;
                                avm_address <= dma_base_address + 3;
                                avm_write <= 1'b1;
                                avm_writedata <= 32'h00000064;//set transfer length
                                avm_byteenable <= 4'b1111;

                                j<=j+1;
                                if(j==3'b111)
                                        i <= i+1;
                        end
                6:        begin //对应初始化函数的IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE, 0x09a);
                                avm_read <= 1'b0;
                                avm_address <= dma_base_address + 6;
                                avm_write <= 1'b1;
                                avm_writedata <= 32'h0000009a;//start dma
                                avm_byteenable <= 4'b1111;

                                j<=j+1;
                                if(j==3'b111)
                                        i <= i+1;
                        end
                7:  //读取DMA控制器状态寄存器的值,判断DMA传输是否结束
                        begin
                                avm_read <= 1'b1;//read status register to judgu dma transfer done
                                avm_write <= 1'b0;
                                avm_address <= dma_base_address + 0;
                                avm_byteenable <= 4'b1111;
                                dma_status_reg <= avm_readdata;
                                j<=j+1;
                                if((dma_status_reg[0] | dma_status_reg[4]) && j==3'b111)
                                        i <= i+1;
                        end
                8: //对应中断服务函数中的IOWR_ALTERA_AVALON_DMA_STATUS(DMA_BASE, 0);
                        begin
                                avm_read <= 1'b0;
                                avm_write <= 1'b1;
                                avm_address <= dma_base_address + 0;
                                avm_write <= 1'b1;
                                avm_writedata <= 32'h00000000;//clear interrupt flag
                                avm_byteenable <= 4'b1111;

                                j<=j+1;
                                if(j==3'b111)
                                        i <= i+1;
                        end
                9:        begin  //对应中断服务函数中的IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE, 0x092);
                                avm_address <= dma_base_address + 6;
                                avm_write <= 1'b1;
                                avm_writedata <= 32'h00000092;//stop dma
                                avm_byteenable <= 4'b1111;

                                j<=j+1;
                                if(j==3'b111)
                                        i <= 0;
                        end
                       
                default :
                        begin
                                avm_write <= 1'b0;
                                avm_read <= 1'b0;
                                avm_byteenable <= 4'b0000;
                                i <= 0;
                        end
                endcase
               
        end
      
endmodule


上面的模块加到SOPC中后还是无法对DMA控制器进行正确配置啊,不知道问题出在哪里呢,请高手指点,顺便赐教更好的解决方案啊!!!
y789 发表于 2012-8-17 14:50:54 | 显示全部楼层
thanks for your sharing ..........
liuhuanwhy 发表于 2012-8-25 18:12:29 | 显示全部楼层
这个一定要看一下
pkk8015878 发表于 2012-8-30 14:49:05 | 显示全部楼层
看看
xiahang 发表于 2012-8-31 07:27:45 | 显示全部楼层
哇。。。。太牛B了,这样以后MUC都不用了,
cdlxzlp 发表于 2012-9-1 19:01:36 | 显示全部楼层
回复 1# liuhui1987812


    好东西 啊  好东西
yanfeiyanna 发表于 2012-9-6 20:15:55 | 显示全部楼层
wxmhb2004 发表于 2012-9-10 09:47:19 | 显示全部楼层
回复 1# liuhui1987812
看看
pk3725069 发表于 2012-9-14 18:57:24 | 显示全部楼层
给力回复 1# liuhui1987812
chen_sp 发表于 2012-9-16 06:57:38 | 显示全部楼层
谢谢
chxzh123 发表于 2012-9-16 16:31:49 | 显示全部楼层
压缩工具试试然后上传完整的工程
emwzq 发表于 2012-9-18 19:16:06 | 显示全部楼层
终于找到了,谢谢楼主
ljyjxgzln 发表于 2012-9-22 16:33:58 | 显示全部楼层
谢谢分享
allstars52 发表于 2012-9-24 09:20:57 | 显示全部楼层
谢谢分享
qhb9522 发表于 2012-9-24 13:34:11 | 显示全部楼层
想看看,学习下
lkfanyao 发表于 2012-9-24 19:47:36 | 显示全部楼层
好好学习!!!
hzz137 发表于 2012-9-28 14:58:23 | 显示全部楼层
感谢 学习一下
hzz137 发表于 2012-9-28 14:58:54 | 显示全部楼层
学习学习!!!
hzz137 发表于 2012-9-28 15:00:06 | 显示全部楼层
感谢 看看
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|@2009-2016 芯驿电子科技(上海)有限公司|小黑屋|手机版|Archiver|黑金动力社区 ( 沪ICP备11013590沪公网安备 31011702000003号

GMT+8, 2017-7-24 10:45 , Processed in 0.103310 second(s), 14 queries , Gzip On.

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表