CPLD引脚没有被驱动

时间:2013-03-17 19:16:21

标签: verilog vga

我正在使用Verilog从莱迪思CPLD构建VGA控制器。我过去曾经接触过相当多的Verilog,但是已经有一段时间了,我生锈了,并且控制显示器所需的同步线没有被驱动(用O.Scope检查),我不知道为什么不呢。

我试图模拟Active-HDL中的代码,但是我收到一条奇怪的错误消息(无法为非阻塞事务分配内存)并得到计数器没有负载的警告(我相信我可以忽略这种情况?)代码如下,如果它有助于使代码更清晰,我试图遵循的时序图接近(但不完全)这个 - > click here

module CtrlLines(NRST, CLK, H_SYNC, V_SYNC);
    input  wire CLK;        /*< CLK input from Top module   >*/
    input  wire NRST;       /*< Reset input from Top module >*/
    output reg  H_SYNC;
    output reg  V_SYNC;

    reg [10:0] h_counter;   /*< Tracks amount of pulses from CLK    >*/
    reg [10:0] v_counter;   /*< Tracks amount of pulses from H_SYNC >*/

    `define H_FRONT_PORCH   10'd95
    `define H_BACK_PORCH    10'd720
    `define H_COUNT_MAX     10'd800

    `define V_FRONT_PORCH   10'd2
    `define V_BACK_PORCH    10'd514
    `define V_COUNT_MAX     10'd528

    always @(negedge NRST, posedge CLK) begin
        if (!NRST) begin
            h_counter <= 10'b00;
        end
        else begin
            h_counter <= h_counter + 1'b1;
            case (h_counter)
                `H_FRONT_PORCH: H_SYNC <= 1;    /*< If the counter has reached Front Porch, go High >*/
                `H_BACK_PORCH : H_SYNC <= 0;    /*< If the counter has reached Back Porch, go Low   >*/
                `H_COUNT_MAX  : h_counter <= 0; /*< If the counter has reached Max, Reset   >*/
            endcase                             /*< Else, remain at current level           >*/
        end
    end

    always @(negedge NRST, negedge H_SYNC) begin
        if (!NRST) begin
            v_counter <= 10'b00;
        end
        else begin
            v_counter <= v_counter +1'b1;
            case (v_counter)
                `V_FRONT_PORCH  : V_SYNC <= 1;
                `V_BACK_PORCH   : V_SYNC <= 0;
                `V_COUNT_MAX    : v_counter <= 0;
            endcase
        end
    end
endmodule

3 个答案:

答案 0 :(得分:2)

此代码存在问题,因为您对同一regh_counter)进行了多次非阻止分配。它是不确定的,首先执行一个,这会导致模拟竞争条件:

    h_counter <= h_counter + 1'b1;
    case (h_counter)
        `H_FRONT_PORCH: H_SYNC <= 1;    /*< If the counter has reached Front Porch, go High >*/
        `H_BACK_PORCH : H_SYNC <= 0;    /*< If the counter has reached Back Porch, go Low   >*/
        `H_COUNT_MAX  : h_counter <= 0; /*< If the counter has reached Max, Reset   >*/

我的猜测是你的综合工具也存在问题。

也许你的意思是在default语句的case子句中出现增量。

同样适用于v_counter

答案 1 :(得分:1)

我不知道是否会引起问题,但看起来很奇怪:

default         : V_SYNC = V_SYNC;

使用阻塞分配为自己分配V_SYNC。

我建议删除此行。

答案 2 :(得分:0)

我要重申Tim的建议,即以不使用H_SYNC作为时钟的方式对V_SYNC部分进行编码。使用数据作为时钟(反过来)通常不赞成,因为大多数工具都不能很好地处理它。

对于主要问题,我可能会建议你验证H_SYNC和V_SYNC信号是否正确路由到顶层和IO?根据警告,我认为你的逻辑可能会在syn期间得到优化。我发布的内容没有任何重大的功能问题。