2013-07-15 150 views
1

我正在尝试在Verilog中编写一个应该“移动”LED阵列上的LED灯的程序。用一个按钮,灯应该移动到左边,而另一个灯应该移动到右边。这是我的代码:如果使用三元运算符 - Verilog

module led_shift(UP, DOWN, RES, CLK, LED); 
input UP, DOWN, RES, CLK; 
output reg [7:0] LED; 
reg [7:0] STATE; 

[email protected](negedge DOWN or negedge UP or negedge RES) 
begin 
    if(!RES) 
    begin 
     STATE <= 8'b00010000; 
    end 
    else 
    begin 
     STATE <= UP ? STATE>>1 : STATE<<1; 
    end 
end 

always @ (posedge CLK) 
begin 
    LED <= STATE; 
end 
endmodule 

的问题是在STATE < = UP?状态>> 1:状态< < 1;以及以下错误:

错误(10200):led_shift.v处的Verilog HDL条件语句错误(34):无法将条件中的操作数与始终包含的事件控件中的对应边相匹配构建

我试图修改代码,而无需使用那种如果:

[email protected](negedge DOWN or negedge UP or negedge RES) 
begin 
    if(!RES) 
     STATE <= 8'b00010000; 
    else 
    begin 
     if(!DOWN) 
      STATE <= STATE<<1; 
     else 
     begin 
      if(!UP) 
       STATE <= STATE>>1; 
      else 
       STATE <= STATE; 
     end 
    end 
end 

它编译,但不工作:LED的“动作”只到左边,当我按下另一个按钮全部LED关闭。可能在我的代码中存在问题,但我不明白为什么我的第一个代码根本不能编译。 谢谢你的帮助!

harrym

回答

2

目前尚不清楚的合成知道如何控制STATE与3个异步控制信号。

很可能您的合成器试图将STATE映射到具有异步低电平有效置位和复位的D触发器。例如,它可能是想合成的东西,如:

dff state_0_(.Q(STATE[0], .CLK(DOWN), .SET_N(UP), .RST_N(RES(, .D(/*...*/)); 

在实际的翻牌异步设置和重置,默认应该是同意的,并会解释错误在你的第一个代码。在第二次尝试中,UPDOWN一起成为组合逻辑云的一部分。 DOWN也被用作时钟。由于UP不是时钟,所以在UP低的情况下连续发生移位,并立即将开位完全移出。第二种情况的另一个错误实际上会更合适。

要使合成器做得更好,首先需要同步异步控制信号。使用与CDC相同的技术(时钟域交叉; Cliff Cummings的论文进入拘留here)。一个基本的例子:

always @(posedge clk) begin 
    pre_sync_DOWN <= DOWN; 
    sync_DOWN <= pre_sync_DOWN; 
end 

现在,控制信号是同步的,使你的STATE组合逻辑的输出。例如:

always @* begin 
    if(!sync_RES) 
     STATE = 8'b00010000; 
    else 
     case({sync_UP,sync_DOWN}) 
     2'b01 : STATE = LED>>1; 
     2'b10 : STATE = LED<<1; 
     default: STATE = LED; 
     endcase 
end 

随着对一个时钟域和显式定义的组合逻辑运行的一切,合成器可使用触发器和基本栅极构造等效逻辑。


FYI:

要在negedge事件中,你需要保持上次同步值,并检查是否有高到低的过渡只转移。请记得在驱动STATE的组合逻辑中将sync_do_对换。

always @(posedge clk) 
    keep_DOWN <= sync_DOWN; 
always @* 
    do_DOWN = (keep_DOWN && !sync_DOWN); 
+0

谢谢!完美的答案。该项目仍然不起作用(我按下的每个按钮,LED关闭,可能转换太快),但至少它编译。我将在模拟中检查信号。我没有得到的是,在我的第二个代码中,当UP很低时,连续发生移位的原因。只有当灵敏度列表中的一个信号下降,当UP较低时才应该移动? – harrym

+0

尝试使用门进行绘图或编写代码,'STATE'是异步低电平置位和复位的内部DFF的输出。 'UP'将是电平敏感的(不边沿敏感),所以高位将立即移出(只有潜在的减速是蠕动延迟)。 – Greg

+0

我用一个边缘检测的例子更新了我的答案。它会根据每个恶性事件​​转移一次。 – Greg