打印
[verilog]

EPM570上实现的并行总线数据收发,遇到的奇怪问题,求助!

[复制链接]
1133|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
circle900617|  楼主 | 2015-9-28 12:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 circle900617 于 2015-9-28 12:23 编辑

开发环境:Quartus II 12 64bit,语言verilog hdl
主要功能:EPM570T144作为STM32的FSMC总线上的设备,为MCU提供接口扩展和一些简单的逻辑功能。
问题:
1. sensor模块中读取几个IO口数据的时候,若在判断中添加对地址的判断,则无**常读取数据。(传感器就是普通的光电对管,经过施密特)
    由于我是第一次写CPLD代码,有可能是某些基础知识不了解,低级问题导致,请大家帮忙查出来予以指教!
2. 奇怪的问题:如果我将led_beeper模块中的代码添加了一些逻辑功能,甚至仅仅删除一小部分代码,就会导致sensor模块中的数据读出为全0。
    具体添加的逻辑功能,在led_beeper -new.v中。
    具体删除的小部分代码,在下文led_beeper.v中有标识描述,删除这一段,重新下载以后STM32读取sensor模块的数据就是全0了。

硬件没问题,其他功能完全正常,设备总线读写正常(USB、LCD),通过CPLD控制的电机等设备也运行正常。传感器的信号用示波器看过没有任何问题。
我现在是给公司开发一个项目,用到CPLD临时学的,由于时间紧迫也就没能从头到尾系统地学习,希望大家能不吝赐教!!

下面贴代码(只贴了几个模块,其他的在附件中,包括CPLD其他全部代码、STM32对应的FSMC设置代码等):
CPLD 顶层模块:

module xxxxxx
    (
        CLK48M,CPLD_INT,MCU_IO,
        BUS_WR,BUS_RD,BUS_NE,BUS_A_L,BUS_A_H,BUS_D,
        BUS_CS_CH375,BUS_CS_FLASH,BUS_CS_LCD,BUS_CS_RAM,
        BEEP,LED,
        SM1_MONI,SM1_EMO, SM2_MONI,SM2_EMO, SM3_MONI,SM3_EMO, SM4_MONI,SM4_EMO,
        SM_ST, SM4_OE,SM4_FR,SM4_ATT, SM3_OE,SM3_FR,SM3_ATT, SM2_OE,SM2_FR,SM2_ATT, SM1_OE,SM1_FR,SM1_ATT,
        DM2_EN,DM1_EN,DM1_IN,DM2_IN,
        SEN_DOOR,SEN_PRESS,SEN_CARVE,SEN_TAPE_B,SEN_TAPE_F,SEN_CUT_R,SEN_CUT_L,SEN_RESERVE,
        PH_PWR, PH_LATCH,PH_CLK, PH_DAT,PH_STR
    );
   
    /*********************************************************************************************************/
    //接口定义
   
    //晶振时钟
    input CLK48M;
   
    //发送至MCU的中断信号
    output CPLD_INT;
    //与MCU连接的预留IO口
    output[3:0] MCU_IO;
   
    //数据总线   
        input BUS_WR,BUS_RD;
        input[4:1] BUS_NE;
        input[19:0] BUS_A_L;
        input[25:22] BUS_A_H;
        inout[15:0] BUS_D;
    output BUS_CS_CH375,BUS_CS_FLASH,BUS_CS_LCD;
    output[2:1] BUS_CS_RAM;
   
    //蜂鸣器
    output BEEP;
    //LED0--绿,LED1--红
        output[1:0] LED;
   
    //步进电机   
    input SM1_MONI,SM1_EMO, SM2_MONI,SM2_EMO, SM3_MONI,SM3_EMO, SM4_MONI,SM4_EMO;
    output SM_ST, SM4_OE,SM4_FR,SM4_ATT, SM3_OE,SM3_FR,SM3_ATT, SM2_OE,SM2_FR,SM2_ATT, SM1_OE,SM1_FR,SM1_ATT;
    //直流电机
    output DM2_EN,DM1_EN;
    output[2:1] DM1_IN,DM2_IN;

    //传感器接口
    input SEN_DOOR,SEN_PRESS,SEN_CARVE,SEN_TAPE_B,SEN_TAPE_F,SEN_CUT_R,SEN_CUT_L,SEN_RESERVE;
   
    //打印头接口
    output PH_PWR, PH_LATCH,PH_CLK;
    output[4:1] PH_DAT,PH_STR;
   
    /*********************************************************************************************************/
    //双向总线数据口
    reg[15:0] BUS_D_OUT_REG;
    wire[15:0] BUS_D_OUT;
        wire[15:0] BUS_D;
        wire[15:0] BUS_D_IN;
    assign BUS_D[15:0] = ((BUS_RD == 1'b0) && (BUS_CS_CPLD == 0))? BUS_D_OUT_REG : 16'bzzzz_zzzz_zzzz_zzzz;
    assign BUS_D_IN = BUS_D;
    always
    begin
        BUS_D_OUT_REG = BUS_D_OUT;
    end
    /*********************************************************************************************************/
    //模拟上电复位
    wire RST_n;
    sim_rst mod_sim_rst(CLK48M,1'b1,RST_n);
    /*********************************************************************************************************/
    //时钟分频
    wire clk_1k;
    defparam Gen_ClkLed.divdWIDTH=15,Gen_ClkLed.divdFACTOR=24000;
        gen_divd Gen_ClkLed(.reset(RST_n),.clkin(CLK48M),.clkout(clk_1k));
    assign CPLD_INT = clk_1k;
    /*********************************************************************************************************/
   
    wire BUS_CS_CPLD;

    logic_cs mod_logic_cs(BUS_NE,BUS_A_H, BUS_CS_CH375,BUS_CS_LCD,BUS_CS_FLASH,BUS_CS_RAM,BUS_CS_CPLD);
   
    led_beeper mod_led_beeper(clk_1k,RST_n,BUS_CS_CPLD,BUS_WR,BUS_D_IN,BUS_A_L,LED,BEEP);
   
    /*********************************************************************************************************/
    //传感器读取
    sensor mod_sensor(clk_1k,BUS_CS_CPLD,BUS_RD,BUS_D_OUT[7:0],BUS_A_L, MCU_IO[0],
                     SEN_DOOR,SEN_PRESS,SEN_CARVE,SEN_TAPE_B,SEN_TAPE_F,SEN_CUT_R,SEN_CUT_L,SEN_RESERVE);
    //assign MCU_IO[0] = SEN_CUT_L;
   
    /*********************************************************************************************************/
    dc_motor mod_dc_motor(clk_1k,RST_n,BUS_CS_CPLD,BUS_WR,BUS_D_IN,BUS_A_L,DM1_EN,DM1_IN,DM2_EN,DM2_IN);
    /*********************************************************************************************************/
    step_motor mod_step_motor
    (
        clk_1k,RST_n,
        BUS_CS_CPLD,BUS_WR,BUS_D,BUS_A_L,
        SM_ST, SM4_OE,SM4_FR,SM4_ATT, SM3_OE,SM3_FR,SM3_ATT, SM2_OE,SM2_FR,SM2_ATT, SM1_OE,SM1_FR,SM1_ATT
    );
   
    /*********************************************************************************************************/
    print_head mod_print_head
    (
        CLK48M,clk_1k,RST_n,
        BUS_CS_CPLD,BUS_WR,BUS_D,BUS_A_L,
        PH_PWR, PH_LATCH,PH_CLK, PH_DAT,PH_STR,
        MCU_IO[1]
    );
   
endmodule                                
CPLD sensor模块:

module sensor
    (
        inClk1K,
        BUS_CS_CPLD,BUS_RD,BUS_D_OUT,BUS_A_L, MCU_IO,
        SEN_DOOR,SEN_PRESS,SEN_CARVE,SEN_TAPE_B,SEN_TAPE_F,SEN_CUT_R,SEN_CUT_L,SEN_RESERVE
    );
   

        input inClk1K;
        input BUS_CS_CPLD,BUS_RD;
    input[19:0] BUS_A_L;
    input SEN_DOOR,SEN_PRESS,SEN_CARVE,SEN_TAPE_B,SEN_TAPE_F,SEN_CUT_R,SEN_CUT_L,SEN_RESERVE;
    output[7:0] BUS_D_OUT;
    output MCU_IO;
   
    reg[7:0] BUS_D_OUT;
    reg MCU_IO;
   
    parameter ADDR_SENSOR = 16'h2000;
        
    //传感器有光(未挡住)
    //parameter STATE_BRIGHT = 1'b1;
    //传感无光(挡住)
    //parameter STATE_DARK   = 1'b0;
   
    always@(negedge BUS_RD)
    begin
        if ((BUS_CS_CPLD == 0))// && (BUS_A_L[15:0] == ADDR_SENSOR))
        begin
            //                    7          6         5        4          3          2        1        0
            BUS_D_OUT[7:0] = {SEN_DOOR,SEN_PRESS,SEN_CARVE,SEN_TAPE_B,SEN_TAPE_F,SEN_CUT_R,SEN_CUT_L,SEN_RESERVE};
            //出现读取数据为全0的情况时,将上句替换为  BUS_D_OUT[7:0] = 8'h23; 则可以正常读出数据,怀疑是总线上挂的设备太多了,驱动能力不足?
        end
    end

endmodule

CPLD led_beeper模块:

module led_beeper
    (
        clk_1k,rst_n,
        BUS_CS_CPLD,BUS_WR,BUS_D,BUS_A_L,
        outLed,outBeeper
    );
   
    /* 输入信号数据格式
        [7:0]  -- 蜂鸣器
        [11:8] -- LED0
        [15:12]-- LED1
    */
    input clk_1k,rst_n;
        input BUS_CS_CPLD, BUS_WR;
    input[15:0] BUS_D;
    input[19:0] BUS_A_L;
    output[1:0] outLed;
    output outBeeper;
   
    //寄存器定义
    reg[1:0] outLed;
    reg outBeeper;

    reg [3:0]rStateLed0,rStateLed1,rStateBeeper;
    reg [9:1]rCntLed0,rCntLed1,rCntBeeper;
   
    //定义使能信号数据
    //注意:该地址为16位数据地址,即对应到MCU中的地址为0x1000<<1 (MCU中的地址为8位数据地址)
    parameter ADDR_LED_BEEPER = 16'h1000;
   
    parameter STATE_ON   = 4'h1;
    parameter STATE_OFF  = 4'h2;
    parameter STATE_1HZ  = 4'hA;
    parameter STATE_3HZ  = 4'hB;
    parameter STATE_10HZ = 4'hC;
   
    parameter OUT_ON  = 1'b0;
    parameter OUT_OFF = 1'b1;
   
    //总线数据接收
    always @(negedge BUS_WR or negedge rst_n)
    begin
        if (rst_n == 1'b0)
        begin
            rStateLed1 = STATE_ON;
            rStateLed0 = STATE_ON;
            rStateBeeper = STATE_OFF;
        end
        else if ((BUS_CS_CPLD == 0) && (BUS_A_L == ADDR_LED_BEEPER))
        begin
            if (BUS_D[7:4] != 4'h0)
            begin
                rStateLed1 = BUS_D[7:4];
            end
            if (BUS_D[3:0] != 4'h0)
            begin
                rStateLed0 = BUS_D[3:0];
            end
            if (BUS_D[11:8] != 4'h0)
            begin
                rStateBeeper = BUS_D[11:8];
            end
        end
    end
   
    //LED0
    always @(posedge clk_1k)
    begin
        case(rStateLed0)
            STATE_ON:   
                begin
                    outLed[0] = OUT_ON;
                    rCntLed0 = 1'b0;
                end
            STATE_OFF:   
                begin
                    outLed[0] = OUT_OFF;
                    rCntLed0 = 1'b0;
                end
            STATE_1HZ:
            begin
                if (rCntLed0 >= 500)
                begin
                    outLed[0] = ~outLed[0];
                    rCntLed0 = 1'b0;
                end
                rCntLed0 = rCntLed0 + 1'b1;
            end
            STATE_3HZ:
            begin
                if (rCntLed0 >= 166)
                begin
                    outLed[0] = ~outLed[0];
                    rCntLed0 = 1'b0;
                end
                rCntLed0 = rCntLed0 + 1'b1;
            end
            STATE_10HZ:
            begin
                if (rCntLed0 >= 50)
                begin
                    outLed[0] = ~outLed[0];
                    rCntLed0 = 1'b0;
                end
                rCntLed0 = rCntLed0 + 1'b1;
            end
            default: outLed[0] = OUT_ON;
        endcase
    end

    //LED1
    always @(posedge clk_1k)
    begin
        case(rStateLed1)
            STATE_ON:   
                begin
                    outLed[1] = OUT_ON;
                    rCntLed1 = 1'b0;
                end
            STATE_OFF:   
                begin
                    outLed[1] = OUT_OFF;
                    rCntLed1 = 1'b0;
                end
            STATE_1HZ:
            begin
                if (rCntLed1 >= 500)
                begin
                    outLed[1] = ~outLed[1];
                    rCntLed1 = 1'b0;
                end
                rCntLed1 = rCntLed1 + 1'b1;
            end
            STATE_3HZ:
            begin
                if (rCntLed1 >= 166)
                begin
                    outLed[1] = ~outLed[1];
                    rCntLed1 = 1'b0;
                end
                rCntLed1 = rCntLed1 + 1'b1;
            end
            default: outLed[1] = OUT_ON;
        endcase
    end

    //BEEPER
    always @(posedge clk_1k)
    begin
        case(rStateBeeper)
            STATE_ON:  
                begin
                    outBeeper = OUT_ON;
                    rCntBeeper = 1'b0;
                end
            STATE_OFF:
                begin
                    outBeeper = OUT_OFF;
                    rCntBeeper = 1'b0;
                end
            STATE_1HZ:
            begin
                if (rCntBeeper >= 500)
                begin
                    outBeeper = ~outBeeper;
                    rCntBeeper = 1'b0;
                end
                rCntBeeper = rCntBeeper + 1'b1;
            end
            STATE_3HZ:
            begin
                if (rCntBeeper >= 166)
                begin
                    outBeeper = ~outBeeper;
                    rCntBeeper = 1'b0;
                end
                rCntBeeper = rCntBeeper + 1'b1;
            end
            /*STATE_10HZ:
            begin
                if (rCntBeeper >= 50)
                begin
                    outBeeper = ~outBeeper;
                    rCntBeeper = 1'b0;
                end
                rCntBeeper = rCntBeeper + 1'b1;
            end*/
            //这段代码删除以后,会导致sensor模块的数据通过总线读出来是全0,再添加这段代码回来,就恢复了。。奇怪的问题
            default: outBeeper = OUT_OFF;
        endcase
    end




MCU.zip

122.03 KB

CPLD.zip

884.8 KB

相关帖子

沙发
xuander| | 2015-9-28 17:24 | 只看该作者

这么长代码。。。。

为什么不自己仿真呢?modelsim,学学吧,必不可少。



使用特权

评论回复
板凳
circle900617|  楼主 | 2015-9-29 18:03 | 只看该作者
xuander 发表于 2015-9-28 17:24
这么长代码。。。。

为什么不自己仿真呢?modelsim,学学吧,必不可少。

恩确实应该学,但是现在项目着急没时间给我学,所以在这求高人帮忙指点一下

使用特权

评论回复
地板
charrijon| | 2015-9-29 20:13 | 只看该作者
应该很容易测试的,好好规划一下

使用特权

评论回复
5
circle900617|  楼主 | 2015-9-30 11:00 | 只看该作者
charrijon 发表于 2015-9-29 20:13
应该很容易测试的,好好规划一下

为什么很容易测试?我的这个问题感觉很奇怪啊,不怎么相关的两个地方,有影响。

好好规划一下指的是什么?不太懂 详细说明一下呗

使用特权

评论回复
6
charrijon| | 2015-9-30 11:59 | 只看该作者
不想读你写的模块,做FPGA和CPLD关键的是原理图要贴出来,这样别人才能明白你想干什么.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

8

帖子

0

粉丝