From 30871dc6e0524ec34892717aaf0fb222be9ae018 Mon Sep 17 00:00:00 2001 From: "sem24h18 Fabian Hauser (fhauser)" <146116057+fhaus1@users.noreply.github.com> Date: Thu, 12 Dec 2024 18:13:45 +0100 Subject: [PATCH] Multiple FlipFlop replacements --- hw/newusb/new_usb_dmaoutputqueueED.sv | 8 ++-- hw/newusb/new_usb_dmaoutputqueueTD.sv | 53 +++++++++++++++++--------- hw/newusb/new_usb_unpackdescriptors.sv | 8 ++-- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/hw/newusb/new_usb_dmaoutputqueueED.sv b/hw/newusb/new_usb_dmaoutputqueueED.sv index a6250276..e5224211 100644 --- a/hw/newusb/new_usb_dmaoutputqueueED.sv +++ b/hw/newusb/new_usb_dmaoutputqueueED.sv @@ -24,9 +24,9 @@ module new_usb_dmaoutputqueueED import new_usb_ohci_pkg::*; #( output logic secondin_valid_o, output logic secondin_loaded_o, /// data input - input logic [31:0] dma_data_i, - input logic dma_valid_i, - output logic dma_ready_o, + input logic [AxiDataWidth-1:0] dma_data_i, + input logic dma_valid_i, + output logic dma_ready_o, /// external ED access output endpoint_descriptor secondin, output endpoint_descriptor firstin @@ -90,7 +90,7 @@ module new_usb_dmaoutputqueueED import new_usb_ohci_pkg::*; #( assign propagate_valid = propagate[Stages-1]; assign clear_propagate = pop_i || empty_secondin_o || context_switch_i; assign dma_ready = !propagate_valid; - + // Todo: Maybe replace with just transfer_done through loading without register chain new_usb_registerchain #( .Width(1), .Stages(DmaOutputQueueStages) diff --git a/hw/newusb/new_usb_dmaoutputqueueTD.sv b/hw/newusb/new_usb_dmaoutputqueueTD.sv index 2d88d1fa..c8ae3180 100644 --- a/hw/newusb/new_usb_dmaoutputqueueTD.sv +++ b/hw/newusb/new_usb_dmaoutputqueueTD.sv @@ -14,19 +14,20 @@ module new_usb_dmaoutputqueueTD import new_usb_ohci_pkg::*; ( input logic clk_i, input logic rst_ni, /// data input - input logic [31:0] dma_data_i, - input logic dma_valid_i, - output logic dma_ready_o, + input logic [AxiDataWidth-1:0] dma_data_i, + input logic dma_valid_i, + output logic dma_ready_o, /// external TD access output logic [27:0] nextTD_address_o, output logic served_td_o, // a service attempt was made output logic aborted_td_o // the service was aborted before or after the attempt + ); `include "common_cells/registers.svh" gen_transfer_descriptor general; assign nextTD_address_o = general.nextTD; - assign served_td_o = propagate_level3; + assign served_td_o = propagate_valid; // As soon as propagated => served_td // Todo: Actually implement the serving. assign aborted_td_o = 0'b0; // Todo: The system needs to pre-emptively abort a TD if its data is not fitting inside the periodic, nonperiodic window logic [31:0] dword0; @@ -45,22 +46,36 @@ module new_usb_dmaoutputqueueTD import new_usb_ohci_pkg::*; ( assign en = dma_handshake && ~dma_handshake_prev; // registers - `FFL(dword0, dma_data, en, 32b'0) // Dword0 - `FFL(dword1, dword0, en, 32b'0) // Dword1 - `FFL(dword2, dword1, en, 32b'0) // Dword2 - `FFL(dword3, dword2, en, 32b'0) // Dword3 + new_usb_registerchain #( + .Width(AxiDataWidth), + .Stages(DmaOutputQueueStages) + ) i_registerchain_td ( + .clk_i, + .rst_ni, // asynchronous, active low + .clear_i(1'b0), // never cleared only its propagation validity bit (avoids timing issues, saves power) + .en_i(en), + .data_i(dma_data_i), + .register_o({dword0, dword1, dword2, dword3}) + ); // fill propagation - logic propagate_level0; - logic propagate_level1; - logic propagate_level2; - logic propagate_level3; - logic rst_n_propagate; - assign rst_n_propagate = rst_ni; - `FFL(propagate_level0, 1'b1, en, 1b'0, clk_i, rst_n_propagate) // Propagatelevel0 - `FFL(propagate_level1, propagate_level0, en, 1b'0, clk_i, rst_n_propagate) // Propagatelevel1 - `FFL(propagate_level2, propagate_level1, en, 1b'0, clk_i, rst_n_propagate) // Propagatelevel2 - `FFL(propagate_level3, propagate_level2, en, 1b'0, clk_i, rst_n_propagate) // Propagatelevel3 - assign dma_ready = !propagate_level3; + logic propagate_valid; + logic clear_propagate; + logic [Stages-1:0] propagate; + assign propagate_valid = propagate[Stages-1]; + assign clear_propagate = pop_i; + assign dma_ready = !propagate_valid; + // Todo: Maybe replace with just transfer_done through loading without register chain + new_usb_registerchain #( + .Width(1), + .Stages(DmaOutputQueueStages) + ) i_registerchain_td_propagate ( + .clk_i, + .rst_ni, // asynchronous, active low + .clear_i(clear_propagate), // synchronous, active high + .en_i(en), + .data_i(1'b1), // propagation of ones + .register_o(propagate) + ); endmodule \ No newline at end of file diff --git a/hw/newusb/new_usb_unpackdescriptors.sv b/hw/newusb/new_usb_unpackdescriptors.sv index bba6a457..9b7648c5 100644 --- a/hw/newusb/new_usb_unpackdescriptors.sv +++ b/hw/newusb/new_usb_unpackdescriptors.sv @@ -47,8 +47,9 @@ module new_usb_unpackdescriptors import new_usb_ohci_pkg::* #( /// periodic, nonperiodic transitions input logic context_switch_np2p_i, input logic context_switch_p2np_i, - /// head state - input logic sent_head_i + /// receive + input logic sent_head_i, + input logic transfer_done_i ); `include "common_cells/registers.svh" @@ -112,6 +113,7 @@ module new_usb_unpackdescriptors import new_usb_ohci_pkg::* #( assign dma_valid_td = dma_valid_i && !ed && dma_flush_inv; // dma flush is an early flush to prevent faulty stage loading into the queues, save power and increase speed + // Todo: Maybe replace with just transfer_done through loading without register chain logic [Stages-1:0] flush; logic flushed; logic dma_flush; @@ -121,7 +123,7 @@ module new_usb_unpackdescriptors import new_usb_ohci_pkg::* #( logic double_flush; // 256 bit transaction need to be flushed as two 128 transactions `FF(double_flush, double_flush_early, 1'b0) // Maybe this register is not necessary, depends on transaction complete assign dma_flush_inv = !dma_flush; - assign double_flush_early = (flushed == 1) && (transaction_complete != 1); // Todo: add transaction_complete from dma + assign double_flush_early = (flushed == 1) && (transfer_done_i != 1); assign dma_flush_en = doublehead_invalid || context_flush || double_flush; // Todo: add other flush reasons assign flushed = flush[Stages-1]; `FFLARNC(dma_flush, 1'b1, dma_flush_en, flushed, 1b'0, clk_i, rst_ni)