@@ -145,6 +145,8 @@ logic vexii_d_cyc, vexii_d_stb, vexii_d_ack, vexii_d_we;
145145logic [7 : 0 ] vexii_i_sel, vexii_d_sel;
146146logic [63 : 0 ] vexii_i_mosi, vexii_d_mosi, vexii_i_miso, vexii_d_miso;
147147logic [28 : 0 ] vexii_i_addr, vexii_d_addr;
148+ logic [2 : 0 ] vexii_i_cti, vexii_d_cti;
149+ logic [1 : 0 ] vexii_i_bte, vexii_d_bte;
148150
149151VexiiRiscv u_VexiiRiscv (
150152 .PrivilegedPlugin_logic_rdtime (0 ), // 64 bits
@@ -160,8 +162,8 @@ VexiiRiscv u_VexiiRiscv (
160162 .LsuL1WishbonePlugin_logic_bus_DAT_MOSI (vexii_d_mosi), // 64 bits
161163 .LsuL1WishbonePlugin_logic_bus_SEL (vexii_d_sel), // 8 bits
162164 .LsuL1WishbonePlugin_logic_bus_ERR (0 ), // 1 bit
163- .LsuL1WishbonePlugin_logic_bus_CTI (), // 3 bits
164- .LsuL1WishbonePlugin_logic_bus_BTE (), // 2 bits
165+ .LsuL1WishbonePlugin_logic_bus_CTI (vexii_d_cti ), // 3 bits
166+ .LsuL1WishbonePlugin_logic_bus_BTE (vexii_d_bte ), // 2 bits
165167 .FetchL1WishbonePlugin_logic_bus_CYC (vexii_i_cyc), // 1 bit
166168 .FetchL1WishbonePlugin_logic_bus_STB (vexii_i_stb), // 1 bit
167169 .FetchL1WishbonePlugin_logic_bus_ACK (vexii_i_ack), // 1 bit
@@ -171,8 +173,8 @@ VexiiRiscv u_VexiiRiscv (
171173 .FetchL1WishbonePlugin_logic_bus_DAT_MOSI (vexii_i_mosi), // 64 bits
172174 .FetchL1WishbonePlugin_logic_bus_SEL (vexii_i_sel), // 8 bits
173175 .FetchL1WishbonePlugin_logic_bus_ERR (0 ), // 1 bit
174- .FetchL1WishbonePlugin_logic_bus_CTI (), // 3 bits
175- .FetchL1WishbonePlugin_logic_bus_BTE (), // 2 bits
176+ .FetchL1WishbonePlugin_logic_bus_CTI (vexii_i_cti ), // 3 bits
177+ .FetchL1WishbonePlugin_logic_bus_BTE (vexii_i_bte ), // 2 bits
176178 .LsuCachelessWishbonePlugin_logic_bridge_down_CYC (), // 1 bit
177179 .LsuCachelessWishbonePlugin_logic_bridge_down_STB (), // 1 bit
178180 .LsuCachelessWishbonePlugin_logic_bridge_down_ACK (0 ), // 1 bit
@@ -203,6 +205,8 @@ wb64_to_wb32_bridge u_wb64_to_wb32_i (
203205 .dat_o (vexii_i_miso), // 64 bits
204206 .sel_i (vexii_i_sel), // 8 bits
205207 .ack_o (vexii_i_ack),
208+ .cti_i (vexii_i_cti),
209+ .bte_i (vexii_i_bte),
206210
207211 // Lado Core 32 bits
208212 .core_cyc_o (core_cyc),
@@ -229,6 +233,8 @@ wb64_to_wb32_bridge u_wb64_to_wb32_d (
229233 .dat_o (vexii_d_miso), // 64 bits
230234 .sel_i (vexii_d_sel), // 8 bits
231235 .ack_o (vexii_d_ack),
236+ .cti_i (vexii_d_cti),
237+ .bte_i (vexii_d_bte),
232238
233239 // Lado Core 32 bits
234240 .core_cyc_o (data_mem_cyc),
@@ -248,17 +254,19 @@ module wb64_to_wb32_bridge (
248254 input logic clk,
249255 input logic rst,
250256
251- // Wishbone 64-bit lado CPU
257+ // Wishbone 64-bit lado CPU (master)
252258 input logic cyc_i,
253259 input logic stb_i,
254260 input logic we_i,
255- input logic [28 : 0 ] adr_i, // 64-bit Wishbone address ( word aligned)
256- input logic [63 : 0 ] dat_i, // mosi
257- output logic [63 : 0 ] dat_o, // miso
261+ input logic [28 : 0 ] adr_i, // endereço word-alinhado 64b
262+ input logic [63 : 0 ] dat_i,
263+ output logic [63 : 0 ] dat_o,
258264 input logic [7 : 0 ] sel_i,
259265 output logic ack_o,
266+ input logic [2 : 0 ] cti_i,
267+ input logic [1 : 0 ] bte_i,
260268
261- // Wishbone 32-bit lado Core
269+ // Wishbone 32-bit lado Core (slave)
262270 output logic core_cyc_o,
263271 output logic core_stb_o,
264272 output logic core_we_o,
@@ -272,92 +280,130 @@ module wb64_to_wb32_bridge (
272280 typedef enum logic [1 : 0 ] {
273281 IDLE ,
274282 ACCESS_LOW ,
275- ACCESS_HIGH ,
276- DONE
283+ ACCESS_HIGH
277284 } state_t ;
278285
279286 state_t state, next_state;
280- logic [63 : 0 ] data_buffer;
281- logic [28 : 0 ] addr_reg;
282- logic we_reg;
283- logic [7 : 0 ] sel_reg;
284- logic [63 : 0 ] dat_i_reg;
285287
286- // Registradores de entrada
288+ // registradores
289+ logic [63 : 0 ] data_buffer_reg, data_buffer_next;
290+ logic [28 : 0 ] addr_reg, addr_next;
291+ logic we_reg, we_next;
292+ logic [7 : 0 ] sel_reg, sel_next;
293+ logic [63 : 0 ] dat_i_reg, dat_i_next;
294+ logic [2 : 0 ] cti_reg, cti_next;
295+ logic [1 : 0 ] bte_reg, bte_next;
296+
297+ // função: calcula próximo endereço conforme BTE (em unidades de 64-bit word)
298+ function automatic [28 : 0 ] next_addr (input [28 : 0 ] a, input [1 : 0 ] bte);
299+ case (bte)
300+ 2'b00 : next_addr = a + 1 ; // linear
301+ 2'b01 : next_addr = { a[28 : 2 ], (a[1 : 0 ]+ 1 ) & 2'b11 } ; // wrap-4
302+ 2'b10 : next_addr = { a[28 : 3 ], (a[2 : 0 ]+ 1 ) & 3'b111 } ; // wrap-8
303+ 2'b11 : next_addr = { a[28 : 4 ], (a[3 : 0 ]+ 1 ) & 4'b1111 } ; // wrap-16
304+ endcase
305+ endfunction
306+
307+ // estado + registradores
287308 always_ff @ (posedge clk or posedge rst) begin
288309 if (rst) begin
289- state <= IDLE ;
310+ state <= IDLE ;
311+ addr_reg <= '0 ;
312+ we_reg <= '0 ;
313+ sel_reg <= '0 ;
314+ dat_i_reg <= '0 ;
315+ cti_reg <= '0 ;
316+ bte_reg <= '0 ;
317+ data_buffer_reg <= '0 ;
290318 end else begin
291- state <= next_state;
319+ state <= next_state;
320+ addr_reg <= addr_next;
321+ we_reg <= we_next;
322+ sel_reg <= sel_next;
323+ dat_i_reg <= dat_i_next;
324+ cti_reg <= cti_next;
325+ bte_reg <= bte_next;
326+ data_buffer_reg <= data_buffer_next;
292327 end
293328 end
294329
295- // FSM de controle
330+ // FSM combinacional
296331 always_comb begin
297- // Defaults
298- next_state = state;
299- core_cyc_o = 1'b0 ;
332+ // defaults
333+ next_state = state;
334+ addr_next = addr_reg;
335+ we_next = we_reg;
336+ sel_next = sel_reg;
337+ dat_i_next = dat_i_reg;
338+ cti_next = cti_reg;
339+ bte_next = bte_reg;
340+ data_buffer_next = data_buffer_reg;
341+
342+ core_cyc_o = (state != IDLE );
300343 core_stb_o = 1'b0 ;
301344 core_we_o = we_reg;
302345 core_addr_o = 32'h0 ;
303346 core_dat_o = 32'h0 ;
304347 core_sel_o = 4'h0 ;
305348 ack_o = 1'b0 ;
349+ dat_o = data_buffer_reg;
306350
307351 case (state)
308352 IDLE : begin
309353 if (cyc_i && stb_i) begin
310- // Latch comandos
311354 next_state = ACCESS_LOW ;
355+ addr_next = adr_i;
356+ we_next = we_i;
357+ sel_next = sel_i;
358+ dat_i_next = dat_i;
359+ cti_next = cti_i;
360+ bte_next = bte_i;
312361 end
313362 end
314363
315364 ACCESS_LOW : begin
316- core_cyc_o = 1'b1 ;
317365 core_stb_o = 1'b1 ;
318- core_we_o = we_reg;
319- core_addr_o = { addr_reg, 2'b00 } ; // endereço base
366+ core_addr_o = { addr_reg, 3'b000 } ;
320367 core_sel_o = sel_reg[3 : 0 ];
321368 core_dat_o = dat_i_reg[31 : 0 ];
322369 if (core_ack_i) begin
323- if (! we_reg) begin
324- data_buffer[31 : 0 ] = core_dat_i;
325- end
370+ if (! we_reg)
371+ data_buffer_next[31 : 0 ] = core_dat_i;
326372 next_state = ACCESS_HIGH ;
327373 end
328374 end
329375
330376 ACCESS_HIGH : begin
331- core_cyc_o = 1'b1 ;
332377 core_stb_o = 1'b1 ;
333- core_we_o = we_reg;
334- core_addr_o = { addr_reg + 1 , 2'b00 } ; // próximo endereço (offset +4 bytes)
378+ core_addr_o = { addr_reg, 3'b100 } ;
335379 core_sel_o = sel_reg[7 : 4 ];
336380 core_dat_o = dat_i_reg[63 : 32 ];
337381 if (core_ack_i) begin
338- if (! we_reg) begin
339- data_buffer[63 : 32 ] = core_dat_i;
382+ if (! we_reg)
383+ data_buffer_next[63 : 32 ] = core_dat_i;
384+
385+ // gera ack para o master 64b
386+ ack_o = 1'b1 ;
387+
388+ if (cti_reg == 3'b111 ) begin
389+ // fim do burst
390+ next_state = IDLE ;
391+ end else begin
392+ // continua burst
393+ addr_next = next_addr (addr_reg, bte_reg);
394+ next_state = ACCESS_LOW ;
395+
396+ // capturar próximo beat (se master já forneceu)
397+ if (cyc_i && stb_i) begin
398+ dat_i_next = dat_i;
399+ sel_next = sel_i;
400+ cti_next = cti_i;
401+ bte_next = bte_i;
402+ end
340403 end
341- next_state = DONE ;
342404 end
343405 end
344-
345- DONE : begin
346- ack_o = 1'b1 ;
347- dat_o = data_buffer;
348- next_state = IDLE ;
349- end
350406 endcase
351407 end
352408
353- // Latch dos sinais de comando
354- always_ff @ (posedge clk) begin
355- if (state == IDLE && cyc_i && stb_i) begin
356- addr_reg <= adr_i;
357- we_reg <= we_i;
358- sel_reg <= sel_i;
359- dat_i_reg <= dat_i;
360- end
361- end
362-
363409endmodule
0 commit comments