OpenCores
URL https://opencores.org/ocsvn/yifive/yifive/trunk

Subversion Repositories yifive

[/] [yifive/] [trunk/] [caravel_yifive/] [verilog/] [rtl/] [syntacore/] [scr1/] [src/] [top/] [scr1_dmem_router.sv] - Blame information for rev 21

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 dinesha
/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
2
/// @file       
3
/// @brief      Data memory router
4
///
5
`include "scr1_memif.svh"
6
`include "scr1_arch_description.svh"
7
 
8
module scr1_dmem_router
9
#(
10
    parameter SCR1_PORT1_ADDR_MASK      = `SCR1_DMEM_AWIDTH'hFFFF0000,
11
    parameter SCR1_PORT1_ADDR_PATTERN   = `SCR1_DMEM_AWIDTH'h00010000,
12
    parameter SCR1_PORT2_ADDR_MASK      = `SCR1_DMEM_AWIDTH'hFFFF0000,
13
    parameter SCR1_PORT2_ADDR_PATTERN   = `SCR1_DMEM_AWIDTH'h00020000
14
)
15
(
16
    // Control signals
17
    input   logic                           rst_n,
18
    input   logic                           clk,
19
 
20
    // Core interface
21
    output  logic                           dmem_req_ack,
22
    input   logic                           dmem_req,
23 21 dinesha
    input   logic                           dmem_cmd,
24
    input   logic [1:0]                     dmem_width,
25 11 dinesha
    input   logic [`SCR1_DMEM_AWIDTH-1:0]   dmem_addr,
26
    input   logic [`SCR1_DMEM_DWIDTH-1:0]   dmem_wdata,
27
    output  logic [`SCR1_DMEM_DWIDTH-1:0]   dmem_rdata,
28 21 dinesha
    output  logic [1:0]                     dmem_resp,
29 11 dinesha
 
30
    // PORT0 interface
31
    input   logic                           port0_req_ack,
32
    output  logic                           port0_req,
33 21 dinesha
    output  logic                           port0_cmd,
34
    output  logic [1:0]                     port0_width,
35 11 dinesha
    output  logic [`SCR1_DMEM_AWIDTH-1:0]   port0_addr,
36
    output  logic [`SCR1_DMEM_DWIDTH-1:0]   port0_wdata,
37
    input   logic [`SCR1_DMEM_DWIDTH-1:0]   port0_rdata,
38 21 dinesha
    input   logic [1:0]                     port0_resp,
39 11 dinesha
 
40
    // PORT1 interface
41
    input   logic                           port1_req_ack,
42
    output  logic                           port1_req,
43 21 dinesha
    output  logic                           port1_cmd,
44
    output  logic [1:0]                     port1_width,
45 11 dinesha
    output  logic [`SCR1_DMEM_AWIDTH-1:0]   port1_addr,
46
    output  logic [`SCR1_DMEM_DWIDTH-1:0]   port1_wdata,
47
    input   logic [`SCR1_DMEM_DWIDTH-1:0]   port1_rdata,
48 21 dinesha
    input   logic [1:0]                     port1_resp,
49 11 dinesha
 
50
    // PORT2 interface
51
    input   logic                           port2_req_ack,
52
    output  logic                           port2_req,
53 21 dinesha
    output  logic                           port2_cmd,
54
    output  logic [1:0]                     port2_width,
55 11 dinesha
    output  logic [`SCR1_DMEM_AWIDTH-1:0]   port2_addr,
56
    output  logic [`SCR1_DMEM_DWIDTH-1:0]   port2_wdata,
57
    input   logic [`SCR1_DMEM_DWIDTH-1:0]   port2_rdata,
58 21 dinesha
    input   logic [1:0]                     port2_resp
59 11 dinesha
);
60
 
61
//-------------------------------------------------------------------------------
62
// Local types declaration
63
//-------------------------------------------------------------------------------
64
typedef enum logic {
65
    SCR1_FSM_ADDR,
66
    SCR1_FSM_DATA
67
} type_scr1_fsm_e;
68
 
69
typedef enum logic [1:0] {
70
    SCR1_SEL_PORT0,
71
    SCR1_SEL_PORT1,
72
    SCR1_SEL_PORT2
73
} type_scr1_sel_e;
74
 
75
//-------------------------------------------------------------------------------
76
// Local signal declaration
77
//-------------------------------------------------------------------------------
78
type_scr1_fsm_e                 fsm;
79
type_scr1_sel_e                 port_sel;
80
type_scr1_sel_e                 port_sel_r;
81
logic [`SCR1_DMEM_DWIDTH-1:0]   sel_rdata;
82 21 dinesha
logic [1:0]                     sel_resp;
83 11 dinesha
logic                           sel_req_ack;
84
 
85
//-------------------------------------------------------------------------------
86
// FSM
87
//-------------------------------------------------------------------------------
88
always_comb begin
89
    port_sel    = SCR1_SEL_PORT0;
90
    if ((dmem_addr & SCR1_PORT1_ADDR_MASK) == SCR1_PORT1_ADDR_PATTERN) begin
91
        port_sel    = SCR1_SEL_PORT1;
92
    end else if ((dmem_addr & SCR1_PORT2_ADDR_MASK) == SCR1_PORT2_ADDR_PATTERN) begin
93
        port_sel    = SCR1_SEL_PORT2;
94
    end
95
end
96
 
97
always_ff @(negedge rst_n, posedge clk) begin
98
    if (~rst_n) begin
99
        fsm         <= SCR1_FSM_ADDR;
100
        port_sel_r  <= SCR1_SEL_PORT0;
101
    end else begin
102
        case (fsm)
103
            SCR1_FSM_ADDR : begin
104
                if (dmem_req & sel_req_ack) begin
105
                    fsm         <= SCR1_FSM_DATA;
106
                    port_sel_r  <= port_sel;
107
                end
108
            end
109
            SCR1_FSM_DATA : begin
110
                case (sel_resp)
111
                    SCR1_MEM_RESP_RDY_OK : begin
112
                        if (dmem_req & sel_req_ack) begin
113
                            fsm         <= SCR1_FSM_DATA;
114
                            port_sel_r  <= port_sel;
115
                        end else begin
116
                            fsm <= SCR1_FSM_ADDR;
117
                        end
118
                    end
119
                    SCR1_MEM_RESP_RDY_ER : begin
120
                        fsm <= SCR1_FSM_ADDR;
121
                    end
122
                    default : begin
123
                    end
124
                endcase
125
            end
126
            default : begin
127
            end
128
        endcase
129
    end
130
end
131
 
132
always_comb begin
133
    if ((fsm == SCR1_FSM_ADDR) | ((fsm == SCR1_FSM_DATA) & (sel_resp == SCR1_MEM_RESP_RDY_OK))) begin
134
        case (port_sel)
135
            SCR1_SEL_PORT0  : sel_req_ack   = port0_req_ack;
136
            SCR1_SEL_PORT1  : sel_req_ack   = port1_req_ack;
137
            SCR1_SEL_PORT2  : sel_req_ack   = port2_req_ack;
138
            default         : sel_req_ack   = 1'b0;
139
        endcase
140
    end else begin
141
        sel_req_ack = 1'b0;
142
    end
143
end
144
 
145
always_comb begin
146
    case (port_sel_r)
147
        SCR1_SEL_PORT0  : begin
148
            sel_rdata   = port0_rdata;
149
            sel_resp    = port0_resp;
150
        end
151
        SCR1_SEL_PORT1  : begin
152
            sel_rdata   = port1_rdata;
153
            sel_resp    = port1_resp;
154
        end
155
        SCR1_SEL_PORT2  : begin
156
            sel_rdata   = port2_rdata;
157
            sel_resp    = port2_resp;
158
        end
159
        default         : begin
160
            sel_rdata   = '0;
161
            sel_resp    = SCR1_MEM_RESP_RDY_ER;
162
        end
163
    endcase
164
end
165
 
166
//-------------------------------------------------------------------------------
167
// Interface to core
168
//-------------------------------------------------------------------------------
169
assign dmem_req_ack = sel_req_ack;
170
assign dmem_rdata   = sel_rdata;
171
assign dmem_resp    = sel_resp;
172
 
173
//-------------------------------------------------------------------------------
174
// Interface to PORT0
175
//-------------------------------------------------------------------------------
176
always_comb begin
177
    port0_req = 1'b0;
178
    case (fsm)
179
        SCR1_FSM_ADDR : begin
180
            port0_req = dmem_req & (port_sel == SCR1_SEL_PORT0);
181
        end
182
        SCR1_FSM_DATA : begin
183
            if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin
184
                port0_req = dmem_req & (port_sel == SCR1_SEL_PORT0);
185
            end
186
        end
187
        default : begin
188
        end
189
    endcase
190
end
191
 
192
`ifdef SCR1_XPROP_EN
193
assign port0_cmd    = (port_sel == SCR1_SEL_PORT0) ? dmem_cmd   : SCR1_MEM_CMD_ERROR;
194
assign port0_width  = (port_sel == SCR1_SEL_PORT0) ? dmem_width : SCR1_MEM_WIDTH_ERROR;
195
assign port0_addr   = (port_sel == SCR1_SEL_PORT0) ? dmem_addr  : 'x;
196
assign port0_wdata  = (port_sel == SCR1_SEL_PORT0) ? dmem_wdata : 'x;
197
`else // SCR1_XPROP_EN
198
assign port0_cmd    = dmem_cmd  ;
199
assign port0_width  = dmem_width;
200
assign port0_addr   = dmem_addr ;
201
assign port0_wdata  = dmem_wdata;
202
`endif // SCR1_XPROP_EN
203
 
204
//-------------------------------------------------------------------------------
205
// Interface to PORT1
206
//-------------------------------------------------------------------------------
207
always_comb begin
208
    port1_req = 1'b0;
209
    case (fsm)
210
        SCR1_FSM_ADDR : begin
211
            port1_req = dmem_req & (port_sel == SCR1_SEL_PORT1);
212
        end
213
        SCR1_FSM_DATA : begin
214
            if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin
215
                port1_req = dmem_req & (port_sel == SCR1_SEL_PORT1);
216
            end
217
        end
218
        default : begin
219
        end
220
    endcase
221
end
222
 
223
`ifdef SCR1_XPROP_EN
224
assign port1_cmd    = (port_sel == SCR1_SEL_PORT1) ? dmem_cmd   : SCR1_MEM_CMD_ERROR;
225
assign port1_width  = (port_sel == SCR1_SEL_PORT1) ? dmem_width : SCR1_MEM_WIDTH_ERROR;
226
assign port1_addr   = (port_sel == SCR1_SEL_PORT1) ? dmem_addr  : 'x;
227
assign port1_wdata  = (port_sel == SCR1_SEL_PORT1) ? dmem_wdata : 'x;
228
`else // SCR1_XPROP_EN
229
assign port1_cmd    = dmem_cmd  ;
230
assign port1_width  = dmem_width;
231
assign port1_addr   = dmem_addr ;
232
assign port1_wdata  = dmem_wdata;
233
`endif // SCR1_XPROP_EN
234
 
235
//-------------------------------------------------------------------------------
236
// Interface to PORT2
237
//-------------------------------------------------------------------------------
238
always_comb begin
239
    port2_req = 1'b0;
240
    case (fsm)
241
        SCR1_FSM_ADDR : begin
242
            port2_req = dmem_req & (port_sel == SCR1_SEL_PORT2);
243
        end
244
        SCR1_FSM_DATA : begin
245
            if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin
246
                port2_req = dmem_req & (port_sel == SCR1_SEL_PORT2);
247
            end
248
        end
249
        default : begin
250
        end
251
    endcase
252
end
253
 
254
`ifdef SCR1_XPROP_EN
255
assign port2_cmd    = (port_sel == SCR1_SEL_PORT2) ? dmem_cmd   : SCR1_MEM_CMD_ERROR;
256
assign port2_width  = (port_sel == SCR1_SEL_PORT2) ? dmem_width : SCR1_MEM_WIDTH_ERROR;
257
assign port2_addr   = (port_sel == SCR1_SEL_PORT2) ? dmem_addr  : 'x;
258
assign port2_wdata  = (port_sel == SCR1_SEL_PORT2) ? dmem_wdata : 'x;
259
`else // SCR1_XPROP_EN
260
assign port2_cmd    = dmem_cmd  ;
261
assign port2_width  = dmem_width;
262
assign port2_addr   = dmem_addr ;
263
assign port2_wdata  = dmem_wdata;
264
`endif // SCR1_XPROP_EN
265
 
266
`ifdef SCR1_TRGT_SIMULATION
267
//-------------------------------------------------------------------------------
268
// Assertion
269
//-------------------------------------------------------------------------------
270
 
271
SCR1_SVA_DMEM_RT_XCHECK : assert property (
272
    @(negedge clk) disable iff (~rst_n)
273
    dmem_req |-> !$isunknown({port_sel, dmem_cmd, dmem_width})
274
    ) else $error("DMEM router Error: unknown values");
275
 
276
`endif // SCR1_TRGT_SIMULATION
277
 
278
endmodule : scr1_dmem_router

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.