在Verilog中生成条件赋值语句
我正在尝试在N个主设备和m个从设备之间创建一个简单的交叉式互连 假设我有两个主设备和两个从设备,纵横杆将它们连接起来,如下所示:在Verilog中生成条件赋值语句,verilog,system-verilog,Verilog,System Verilog,我正在尝试在N个主设备和m个从设备之间创建一个简单的交叉式互连 假设我有两个主设备和两个从设备,纵横杆将它们连接起来,如下所示: // Master - to - Slave assign s[0].addr = (gnt[0] == 1) ? m[0].addr : ( (gnt[1] == 1) ? m[1].addr : 'b0; ) assign s[0].data = (gnt[0] == 1) ? m[0].data : ( (gnt[1] == 1) ? m[1].data :
// Master - to - Slave
assign s[0].addr = (gnt[0] == 1) ? m[0].addr : ( (gnt[1] == 1) ? m[1].addr : 'b0; )
assign s[0].data = (gnt[0] == 1) ? m[0].data : ( (gnt[1] == 1) ? m[1].data : 'b0; )
// Slave - to - Master
assign m[0].resp = (sel[0] == 1) ? s[0].resp : ( (sel[1] == 1) ? s[1].resp : 'b0; )
如果主服务器和从服务器的数量是参数,是否有方法生成上述assign语句?或者有没有其他方法来完成我想做的事情?任何帮助都将不胜感激。在这种情况下,您可以使用
生成
块:
typedef struct {
integer addr;
integer data;
integer resp;
} sigs;
module crossbar;
parameter int num_masters = 3;
parameter int num_slaves = 3;
sigs s[num_slaves];
sigs m[num_masters];
bit gnt[num_masters];
genvar i, j;
// master to slave loop
for (i = 0; i < num_slaves; i++) begin
wire[31:0] addr;
for (j = 0; j < num_masters; j++) begin
assign addr = gnt[j] == 1'b1 ? m[j].addr : 'z;
end
assign addr = gnt == '0 ? '0 : 'z;
assign s[i].addr = addr;
end
endmodule
typedef结构{
整数地址;
整数数据;
整数响应;
}sigs;
模块纵横杆;
参数int num_masters=3;
参数int num_slaves=3;
sigs[num_slaves];
sigsm[num_masters];
位gnt[num_masters];
genvar i,j;
//主从循环
对于(i=0;i
我在这里说明的只是addr
的赋值。您必须将数据
和任何其他主-从信号发送到此循环,并创建另一个循环,在该循环中,您首先循环主循环,然后从循环分配resp
和任何其他从-主信号
我已经为addr
使用了一个中间连接,以便能够为每个master分配一个assign语句。这样,当授予主控时,它将驱动导线,否则它将驱动高阻抗。因此,不能同时授予两个或两个以上的大师
这并不完全是您所拥有的,但是如果您希望同时允许多个主控器,您可以使用优先级编码方案替换多个分配。可以使用组合块来缩放muxing逻辑。下面的示例默认分配为零,然后使用LSB优先级更新分配
parameter NUM_MASTERS=5, NUM_SLAVES=3;
/*
* ...
*/
for ( genvar s_idx = 0; s_idx < NUM_SLAVES; s_idx++ ) begin
alwasy_comb begin
// default value
s[s_idx].addr = '0;
s[s_idx].data = '0;
// update with lsb priority
for ( int idx = NUM_MASTERS-1; idx >= 0; idx-- ) begin
if (gnt[idx]) begin
s[s_idx].addr = m[idx].addr;
s[s_idx].data = m[idx].data;
end
end
end
end
for ( genvar m_idx = 0; m_idx < NUM_MASTERS; m_idx++ ) begin
alwasy_comb begin
// default value
m[m_idx].resp = '0;
// update with lsb priority
for ( int idx = NUM_SLAVES-1; idx >= 0; idx-- ) begin
if (sel[idx]) begin
m[m_idx].resp = s[idx].resp;
end
end
end
end
参数NUM_MASTERS=5,NUM_SLAVES=3;
/*
* ...
*/
对于(genvar s_idx=0;s_idx=0;idx--)开始
如果(gnt[idx])开始
s[s_idx].addr=m[idx].addr;
s[s_idx].data=m[idx].data;
结束
结束
结束
结束
对于(genvar m_idx=0;m_idx=0;idx--)开始
如果(sel[idx])开始
m[m_idx].resp=s[idx].resp;
结束
结束
结束
结束
是gnt
和sel
一个热零点还是优先级?请说明分配给s[1]
和m[1]
的任务在功能上类似于此概念。然而,许多合成器在看到任何匹配的assign io=en?在:'z代码>格式,这可能是设计约束的限制。此样式还要求gnt
和sel
为一个热编码,而sel为一个热编码。谢谢!!你的方法也行,但我只能接受一个答案。。