这是一个微不足道的问题,但经过大量的努力,我想把它放在这里。
在我的代码中,我使用条件运算符编写了一行,如下所示:
assign {RS2, RS1} = (!DisM || !DisX)? (RdEn==2'b00? (!DisI? {rs2, rs1} : 64'bz) : (RdEn==2'b01? (!switch? {rs2, Rn} : {Rn, rs1}) : {Rm, Rn}))) : 64'bz;
模拟器(Icarus 0.9.7或任何)显示上述行中存在语法错误。 请帮帮我。
提前致谢。
这是我的代码,它解决了同样的问题:
module TEST(Rn, Rm, DisM, DisX, DisI, switch, RdEn, RS1, RS2);
input [31:0]Rn, Rm;
input DisM, DisX, DisI, switch;
input [1:0]RdEn;
output [31:0]RS1, RS2;
reg [31:0]rs1, rs2;
always@*
begin
rs1 = Rn + 32'd7;
rs2 = Rm - 32'd7;
end
assign {RS2, RS1} = (!DisM || !DisX)? (RdEn==2'b00? (!DisI? {rs2, rs1} : {64{1'bz}}) : (RdEn==2'b01? (!switch? {rs2, Rn} : {Rn, rs1}) : {Rm, Rn}))) : {64{1'bz}};
endmodule
答案 0 :(得分:2)
编译器将?
中的RdEn==2'b00?
解释为第3位,而不是作为三元运算符。只需在b00
和?
之间添加空格即可。与b01?
相同。
?
是有效的z_digit。请参阅IEEE Std 1800-2012,第5.7节“数字”。
此外,您的括号数量不匹配(一个好的编辑器可以显示这个):
assign {RS2, RS1} = (!DisM || !DisX)? (RdEn==2'b00 ? (!DisI? {rs2, rs1} : {64{1'bz}}) : (RdEn==2'b01 ? (!switch? {rs2, Rn} : {Rn, rs1}) : {Rm, Rn})) : {64{1'bz}};
使用{64{1'bz}}
确保获得64位1'bz
也是一种好习惯。
答案 1 :(得分:1)
虽然您已经接受了答案,但我强烈建议您重新编码。因为它很难阅读,因而很难调试。至少添加返回行和缩进,以便条件易于在视觉上配对。例如,以下是工具的解决方案的副本,其中添加了换行符和空格。请注意这种格式化样式不会发生RdEn==2'b00?
问题。像emacs和vim这样的编辑器都有语法插件,可以帮助缩进格式化。
assign {RS2, RS1} = (!DisM || !DisX)
? (RdEn==2'b00
? (!DisI ? {rs2, rs1} : {64{1'bz}})
: (RdEn==2'b01
? (!switch ? {rs2, Rn} : {Rn, rs1})
: {Rm, Rn}))
: {64{1'bz}};
实际上,我发现条件运算符?:
(w / o high-Z)在合成时通常会显式为2:1多路复用,这对于时序和面积可能不是最佳的。我还发现保持三态分配简单可以得到更清晰的结果。
我通常建议的方法是确定与三态分配分开的输出使能和输出数据。合成器通常使用这种方法比一个长的赋值语句做得更好;至少从我的经验来看。如果你有一个有限数量的三态驱动器,这种方法也很好,这在FPGA中很常见。
wire out_en = (!DisM || !DisX) && !(RdEn==2'b00 && !DisI);
reg [63:0] out_data;
always @* begin
case(RdEn)
2'b00 : out_data = {rs2, rs1};
2'b01 : out_data = !switch ? {rs2, Rn} : {Rn, rs1});
default : out_data = {Rm, Rn};
endcase
end
assign {RS2, RS1} = out_en ? out_data : {64{1'bz}};
偶尔并行的三态驱动程序具有非重叠启用功能,可以更好地满足某些设计标准。这种方法可以根据技术节点和架构减少时序。通常会有一个区域被击中,如果加载很多,它可能会对时间产生负面影响。
assign {RS2, RS1} = ((!DisM || !DisX) && RdEn==2'b00 && !DisI) ? {rs2, rs1} : {64{1'bz}};
assign {RS2, RS1} = ((!DisM || !DisX) && RdEn==2'b01 && !switch) ? {rs2, Rn} : {64{1'bz}};
assign {RS2, RS1} = ((!DisM || !DisX) && RdEn==2'b01 && switch) ? { Rn, rs1} : {64{1'bz}};
assign {RS2, RS1} = ((!DisM || !DisX) && RdEn[1]) ? { Rm, Rn} : {64{1'bz}};
无论采用何种方法,都要确保三态的启用控制无故障。如果信号不干净,可能会导致总线争用。理想情况下,使能信号应该是直接触发。失败的使能信号在实践中并不总是可行的,因此您需要密切关注它。您通常不会在RTL仿真中看到潜在的故障。如果存在问题,您的综合报告可能会有一些见解。