Chisel 查找表电路优先级问题
verilog ROM的两种写法及区别
1 | 方法1 |
方法2是不是带优先级? 实际上是不带优先级
逻辑上if取的条件都是addr1的值,一定是互斥的,综合工具也能自动识别出这种if else
它有别于以下这种情况,这种情况下是真实带有优先级的电路,其中another_cond_A,another_cond_B
是独立的两个输入条件,和addr1的取值可能同时发生,所以不能被综合器当做查找表来对待。
1 | always @(posedge clk ) |
chisel中查找表的写法以及对应电路
1 | 方法一 |
两种方法都会生成以下类似电路,等效CASE语句写法。所以不用担心优先级的问题。
1 | always @(posedge clk ) |
综合工具对上面电路的处理也是没有优先级的。
综合对比
Verilog DEMO1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104module caseifelse_top (
clk,
in_en0,in_addr0,out_data0,
in_en1,in_addr1,out_data1
);
input clk ;
input in_en0 ;
input in_en1 ;
input [5:0] in_addr0 ;
input [5:0] in_addr1 ;
output [7:0] out_data0 ;
output [7:0] out_data1 ;
reg [7:0] out_data0 ;
reg [7:0] out_data1 ;
reg [5:0] addr0 ;
reg [5:0] addr1 ;
reg en0 ;
reg en1 ;
wire [7:0] data0 ;
wire [7:0] data1 ;
always @(posedge clk )
begin
en0 <= in_en0 ;
en1 <= in_en1 ;
addr0 <= in_addr0 ;
addr1 <= in_addr1 ;
out_data0 <= data0 ;
out_data1 <= data1 ;
end
rom u_rom_table(
.clk (clk ),
.en0 (en0 ),
.addr0 (addr0 ),
.data0 (data0 )
);
ifelse u_ifelse_table(
.clk (clk ),
.en1 (en1 ),
.addr1 (addr1 ),
.data1 (data1 )
);
endmodule
module rom(clk,
rstn,en0,addr0,data0
);
input clk ;
input rstn ;
input en0 ;
input [5:0] addr0 ;
output [7:0] data0 ;
reg [7:0] data0 ;
always @(posedge clk )
begin
case(addr0)
6'd0 : data0 <= 8'd214;
6'd1 : data0 <= 8'd213;
6'd2 : data0 <= 8'd212;
6'd3 : data0 <= 8'd211;
6'd4 : data0 <= 8'd210;
6'd5 : data0 <= 8'd209;
6'd6 : data0 <= 8'd208;
6'd7 : data0 <= 8'd207;
。。。
6'd63: data0 <= 8'd151;
default : data0 <= 8'd0;
endcase
end
endmodule
module ifelse(clk,
en1,addr1,data1
);
input clk ;
input en1 ;
input [5:0] addr1 ;
output [7:0] data1 ;
reg [7:0] data1 ;
always @(posedge clk )
begin
if(addr1 == 6'd0 ) data1 <= 8'd150;
else if(addr1 == 6'd1 ) data1 <= 8'd149;
else if(addr1 == 6'd2 ) data1 <= 8'd148;
else if(addr1 == 6'd3 ) data1 <= 8'd147;
else if(addr1 == 6'd4 ) data1 <= 8'd146;
else if(addr1 == 6'd5 ) data1 <= 8'd145;
else if(addr1 == 6'd6 ) data1 <= 8'd144;
else if(addr1 == 6'd7 ) data1 <= 8'd143;
。。。
else if(addr1 == 6'd63) data1 <= 8'd87;
else data1 <= 8'd1 ;
end
endmodule
综合后的网表 看到两种方法都是基本相同,没有优先级区别
1 |
|
代码目录:/nutstore/2017pc/lab/turbo/scala/work
结论
chisel 虽然生成的电路没有CASE语句,也完全没有问题,
if else的写法也能满足查找表的实现,并不会有优先级的问题
扩展
同样一下两种chisel和verilog的写法对于综合器来说其实都是没有优先级的,
综合器可以根据时序情况将其打平,并不影响电路的功能(本质上每个条件都不
重叠,所以没有真实的优先级物理意义)
因此可以大胆的采用这种写法而不用考虑优先级进位链太长而产生的时序问题。
1 | when (io.swif.K<40.U ){tiRomStartAddr := baseRAny } |