6eedb1cd26a5c2105fb37f0dd7119e5138a65c3a
1 # // Copyright 2018 ETH Zurich and University of Bologna.
2 # // Copyright and related rights are licensed under the Solderpad Hardware
3 # // License, Version 0.51 (the "License"); you may not use this file except in
4 # // compliance with the License. You may obtain a copy of the License at
5 # // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
6 # // or agreed to in writing, software, hardware and materials distributed under
7 # // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
8 # // CONDITIONS OF ANY KIND, either express or implied. See the License for the
9 # // specific language governing permissions and limitations under the License.
11 # this file has been generated by sv2nmigen
13 from nmigen
import Signal
, Module
, Const
, Cat
, Elaboratable
20 # // parameter N_SLICES = 16,
21 # // parameter N_REGS = 4*N_SLICES,
22 # // parameter ADDR_WIDTH_PHYS = 40,
23 # // parameter ADDR_WIDTH_VIRT = 32
26 # input logic [N_REGS-1:0] [63:0] int_cfg_regs,
28 # input logic [ADDR_WIDTH_VIRT-1:0] int_addr_min,
29 # input logic [ADDR_WIDTH_VIRT-1:0] int_addr_max,
30 # input logic multi_hit_allow,
31 # output logic multi_hit,
32 # output logic [N_SLICES-1:0] prot,
33 # output logic [N_SLICES-1:0] hit,
34 # output logic cache_coherent,
35 # output logic [ADDR_WIDTH_PHYS-1:0] out_addr
40 class slice_top(Elaboratable
):
43 # FIXME self.int_cfg_regs = Signal() # input
44 self
.params
= coreconfig
.CoreConfig() # rename ?
45 self
.int_rw
= Signal() # input
46 self
.int_addr_min
= Signal(self
.params
.ADDR_WIDTH_VIRT
) # input
47 self
.int_addr_max
= Signal(self
.params
.ADDR_WIDTH_VIRT
) # input
48 self
.multi_hit_allow
= Signal() # input
49 self
.multi_hit
= Signal() # output
50 self
.prot
= Signal(self
.params
.N_SLICES
) # output
51 self
.hit
= Signal(self
.params
.N_SLICES
) # output
52 self
.cache_coherent
= Signal() # output
53 self
.out_addr
= Signal(self
.params
.ADDR_WIDTH_PHYS
) # output
55 def elaborate(self
, platform
=None):
60 for i
in range(self
.params
.N_SLICES
):
61 # TODO pass params / core config here
62 u_slice
= rab_slice
.rab_slice(self
.params
)
63 setattr(m
.submodules
, "u_slice%d" % i
, u_slice
)
64 # TODO set param and connect ports
66 # In case of a multi hit, the lowest slice with a hit is selected.
67 # TODO always_comb begin : HIT_CHECK
72 self
.cache_coherent
.eq(0)]
74 for j
in range(self
.params
.N_SLICES
):
75 with m
.If(self
.hit
[j
] == 1):
76 with m
.If(first_hit
== 1):
77 with m
.If(self
.multi_hit_allow
== 0):
78 m
.d
.comb
+= [self
.multi_hit
.eq(1)]
79 with m
.Elif(first_hit
== 1):
80 m
.d
.comb
+= [first_hit
.eq(1)
81 # only output first slice that was hit
82 # SV self.out_addr.eq(slice_out_addr[ADDR_WIDTH_PHYS*j + : ADDR_WIDTH_PHYS]),
83 # SV self.cache_coherent.eq(int_cfg_regs[4*j+3][3]),
87 # TODO translate generate statement
91 logic [ADDR_WIDTH_PHYS*N_SLICES-1:0] slice_out_addr;
94 for ( i=0; i<N_SLICES; i++ )
98 .ADDR_WIDTH_PHYS ( ADDR_WIDTH_PHYS ),
99 .ADDR_WIDTH_VIRT ( ADDR_WIDTH_VIRT )
103 .cfg_min ( int_cfg_regs[4*i] [ADDR_WIDTH_VIRT-1:0] ),
104 .cfg_max ( int_cfg_regs[4*i+1][ADDR_WIDTH_VIRT-1:0] ),
105 .cfg_offset ( int_cfg_regs[4*i+2][ADDR_WIDTH_PHYS-1:0] ),
106 .cfg_wen ( int_cfg_regs[4*i+3][2] ),
107 .cfg_ren ( int_cfg_regs[4*i+3][1] ),
108 .cfg_en ( int_cfg_regs[4*i+3][0] ),
109 .in_trans_type ( int_rw ),
110 .in_addr_min ( int_addr_min ),
111 .in_addr_max ( int_addr_max ),
112 .out_addr ( slice_out_addr[ADDR_WIDTH_PHYS*i+ADDR_WIDTH_PHYS-1:ADDR_WIDTH_PHYS*i] ),
113 .out_prot ( prot[i] ),
119 // In case of a multi hit, the lowest slice with a hit is selected.
120 always_comb begin : HIT_CHECK
125 for (j = 0; j < N_SLICES; j++) begin
126 if (hit[j] == 1'b1) begin
127 if (first_hit == 1'b1) begin
128 if (multi_hit_allow == 1'b0) begin
133 out_addr = slice_out_addr[ADDR_WIDTH_PHYS*j +: ADDR_WIDTH_PHYS];
134 cache_coherent = int_cfg_regs[4*j+3][3];
141 # sv 2 migen: TODO add translate code for generate statements and for loops inside always_comb