-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// Copyright 2024 ETH Zurich and University of Bologna. | ||
// Solderpad Hardware License, Version 0.51, see LICENSE for details. | ||
// SPDX-License-Identifier: SHL-0.51 | ||
// | ||
// Fabian Hauser <[email protected]> | ||
// | ||
/// Handles the data received from the devices. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
// Copyright 2024 ETH Zurich and University of Bologna. | ||
// Solderpad Hardware License, Version 0.51, see LICENSE for details. | ||
// SPDX-License-Identifier: SHL-0.51 | ||
// | ||
// Fabian Hauser <[email protected]> | ||
// | ||
/// Two-stage output queue of the DMA for endpoint descriptors | ||
/// Additional stash register for nonperiodic/periodic context switches | ||
/// Checks validity at secondin because at head we do | ||
Check warning on line 9 in hw/newusb/new_usb_dmaoutputqueueED.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueED.sv#L9
Raw output
|
||
/// double length reads from the DMA like in an array which is not HCD spec but predicted. | ||
|
||
// Todo: validity check secondin | ||
// Todo: register hccurrent flow check | ||
// Todo: status bits functionality | ||
// Todo: stashing for bulk control? | ||
|
||
package new_usb_dmaoutputqueueED_pkg; | ||
Check warning on line 17 in hw/newusb/new_usb_dmaoutputqueueED.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueED.sv#L17
Raw output
|
||
|
||
typedef struct packed { | ||
struct packed { | ||
Check warning on line 20 in hw/newusb/new_usb_dmaoutputqueueED.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueED.sv#L20
Raw output
|
||
logic [10:0] MPS; // 26:16 | ||
logic F; // 15 | ||
logic K; // 14 | ||
logic S; // 13 | ||
logic [12:11] D; // 12:11 | ||
logic [10:7] EN; // 10:7 | ||
logic [6:0] FA; // 6:0 | ||
} status; | ||
struct packed { | ||
Check warning on line 29 in hw/newusb/new_usb_dmaoutputqueueED.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueED.sv#L29
Raw output
|
||
logic [27:0] address; // 31:4 | ||
logic C; // 1 | ||
logic H; // 0 | ||
} headTD; | ||
struct packed { | ||
Check warning on line 34 in hw/newusb/new_usb_dmaoutputqueueED.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueED.sv#L34
Raw output
|
||
logic [27:0] address; // 31:4 | ||
} nextED; | ||
} endpoint_descriptor; | ||
Check warning on line 37 in hw/newusb/new_usb_dmaoutputqueueED.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueED.sv#L37
Raw output
|
||
|
||
endpackage | ||
|
||
module new_usb_dmaoutputqueueED import new_usb_dmaoutputqueueED_pkg::*; ( | ||
/// control | ||
input logic clk_i, | ||
input logic rst_ni, | ||
input logic pop_i, // @pop store currenthead and do stash or secondin -> firstin | ||
input logic pop_ready_o, | ||
input logic context_switch_np2p_i, // nonperiodic to periodic | ||
input logic context_switch_p2np_i, // periodic to nonperiodic | ||
output logic empty_secondin_o, // request new ED | ||
output logic firstin_valid_o, | ||
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, | ||
/// external ED access | ||
output endpoint_descriptor secondin, | ||
output endpoint_descriptor firstin | ||
); | ||
endpoint_descriptor stash; | ||
endpoint_descriptor secondinmux; | ||
|
||
logic [31:0] dword0; | ||
logic [31:0] dword1; | ||
logic [31:0] dword2; | ||
logic [31:0] dword3; | ||
|
||
assign dword0 [26:16] = secondin.status.MPS; | ||
assign dword0 [15] = secondin.status.F; | ||
assign dword0 [14] = secondin.status.K; | ||
assign dword0 [13] = secondin.status.S; | ||
assign dword0 [12:11] = secondin.status.D; | ||
assign dword0 [10:7] = secondin.status.EN; | ||
assign dword0 [6:0] = secondin.status.FA; | ||
assign dword2 [31:4] = secondin.headTD.address; | ||
assign dword2 [1] = secondin.headTD.C; | ||
assign dword2 [0] = secondin.headTD.H; | ||
assign dword3 [31:4] = secondin.nextED.address; | ||
|
||
// control logic | ||
assign dword1 [31:4] = tailp; // tailpointerTD only used for empty check | ||
assign noTD = (tailp == secondin.headTD.address); // we have no TDs or it's not loaded yet | ||
assign empty_secondin_o = noTD && propagate_level3; // no TDs | ||
assign secondin_valid_o = !noTD && propagate_level3; // loaded and nonempty secondin | ||
assign secondin_loaded_o = propagate_level3; | ||
logic non_empty_context_switch_np2p; | ||
assign non_empty_context_switch_np2p = secondin_valid_o && context_switch_np2p_i; | ||
logic context_switch; | ||
assign context_switch = context_switch_np2p_i || context_switch_p2np_i; | ||
|
||
// create enable, one pulse for one handshake | ||
logic en; | ||
logic dma_handshake; | ||
logic dma_handshake_prev; | ||
assign dma_handshake = dma_ready && dma_valid_i; | ||
`FF(dma_handshake_prev, dma_handshake, 1'b0) | ||
assign en = dma_handshake && ~dma_handshake_prev; | ||
|
||
// secondin registers | ||
`FFL(dword0, dma_data_i, 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 | ||
|
||
// secondin fill propagation | ||
logic propagate_level0; | ||
logic propagate_level1; | ||
logic propagate_level2; | ||
logic propagate_level3; | ||
logic rst_n_propagate; | ||
assign rst_n_propagate = !pop_i && rst_ni && !empty_secondin_o && !context_switch; // equivalent to !(pop || rst_i || empty_secondin || context_switch) | ||
Check warning on line 112 in hw/newusb/new_usb_dmaoutputqueueED.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueED.sv#L112
Raw output
|
||
`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; | ||
|
||
// context switch stash | ||
logic active_stash; | ||
logic rst_n_stash; | ||
logic non_empty_context_switch_p2np; | ||
assign non_empty_context_switch_p2np = active_stash && context_switch_p2np_i; | ||
assign rst_n_stash = !context_switch_p2np_i && rst_ni; // equivalent to !(context_switch_p2np_i || rst_i ) | ||
Check warning on line 124 in hw/newusb/new_usb_dmaoutputqueueED.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueED.sv#L124
Raw output
|
||
`FF(active_stash, non_empty_context_switch_np2p, 1b'0, clk_i, rst_n_stash) | ||
`FFL(stash, secondin, non_empty_context_switch_np2p, '0) // stash secondin at context switch if valid | ||
Check warning on line 126 in hw/newusb/new_usb_dmaoutputqueueED.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueED.sv#L126
Raw output
|
||
|
||
Check warning on line 127 in hw/newusb/new_usb_dmaoutputqueueED.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueED.sv#L127
Raw output
|
||
// create valid firstin ready for TD processing | ||
assign pop_ready_o = secondin_valid_o || non_empty_context_switch_p2np; | ||
`FFL(firstin_valid_o, 1'b1, pop_i, 1b'0) // firstin stays valid until next rst_ni | ||
|
||
// stash and secondin muxed into firstin | ||
assign secondinmux = non_empty_context_switch_p2np ? stash : secondin; | ||
|
||
// The nextED address needs to be updated in firstin in case secondinED has no TD and the next ED is loaded instead. | ||
assign firstin_nextED_overwrite = pop_i || empty_secondin_o; | ||
`FFL(firstin.status.MPS, secondinmux.status.MPS, pop_i, '0) // firstin register | ||
`FFL(firstin.status.F, secondinmux.status.F, pop_i, '0) // firstin register | ||
`FFL(firstin.status.K, secondinmux.status.K, pop_i, '0) // firstin register | ||
`FFL(firstin.status.S, secondinmux.status.S, pop_i, '0) // firstin register | ||
`FFL(firstin.status.D, secondinmux.status.D, pop_i, '0) // firstin register | ||
`FFL(firstin.status.EN, secondinmux.status.EN, pop_i, '0) // firstin register | ||
`FFL(firstin.status.FA, secondinmux.status.FA, pop_i, '0) // firstin register | ||
`FFL(firstin.headTD.address, secondinmux.headTD.address, pop_i, '0) // firstin register | ||
`FFL(firstin.headTD.C, secondinmux.headTD.C, pop_i, '0) // firstin register | ||
`FFL(firstin.headTD.H, secondinmux.headTD.H, pop_i, '0) // firstin register | ||
`FFL(firstin.nextED.address, secondinmux.nextED.address, firstin_nextED_overwrite, '0) // firstin register | ||
Check warning on line 147 in hw/newusb/new_usb_dmaoutputqueueED.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueED.sv#L147
Raw output
|
||
|
||
endmodule | ||
Check warning on line 149 in hw/newusb/new_usb_dmaoutputqueueED.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueED.sv#L149
Raw output
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright 2024 ETH Zurich and University of Bologna. | ||
// Solderpad Hardware License, Version 0.51, see LICENSE for details. | ||
// SPDX-License-Identifier: SHL-0.51 | ||
// | ||
// Fabian Hauser <[email protected]> | ||
// | ||
/// Output queue of the DMA for general transfer descriptors 4x32 bit buffering for isochronous 8x32 | ||
Check warning on line 7 in hw/newusb/new_usb_dmaoutputqueueTD.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueTD.sv#L7
Raw output
|
||
/// Todo: implement ISOCHRONOUS | ||
/// Todo: implement listservicing | ||
|
||
package new_usb_dmaoutputqueueTD_pkg; | ||
Check warning on line 11 in hw/newusb/new_usb_dmaoutputqueueTD.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueTD.sv#L11
Raw output
|
||
|
||
typedef struct packed { | ||
struct packed { | ||
Check warning on line 14 in hw/newusb/new_usb_dmaoutputqueueTD.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueTD.sv#L14
Raw output
|
||
logic [27:0] address; | ||
} nextTD; | ||
} gen_transfer_descriptor; | ||
Check warning on line 17 in hw/newusb/new_usb_dmaoutputqueueTD.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueTD.sv#L17
Raw output
|
||
|
||
typedef struct packed { | ||
struct packed { | ||
Check warning on line 20 in hw/newusb/new_usb_dmaoutputqueueTD.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueTD.sv#L20
Raw output
|
||
logic [27:0] address; | ||
} nextTD; | ||
} iso_transfer_descriptor; | ||
Check warning on line 23 in hw/newusb/new_usb_dmaoutputqueueTD.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueTD.sv#L23
Raw output
|
||
|
||
endpackage | ||
|
||
module new_usb_dmaoutputqueueTD import new_usb_dmaoutputqueueTD_pkg::*; ( | ||
/// control | ||
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, | ||
/// external TD access | ||
output logic [27:0] nextTD_address_o, | ||
output logic served_td_o | ||
); | ||
gen_transfer_descriptor general; | ||
assign nextTD_address_o = general.nextTD; | ||
assign served_td_o = propagate_level3; | ||
|
||
logic [31:0] dword0; | ||
logic [31:0] dword1; | ||
logic [31:0] dword2; | ||
logic [31:0] dword3; | ||
|
||
assign dword0 [26:16] = general.nextTD; | ||
|
||
// create enable, one pulse for one handshake | ||
logic en; | ||
logic dma_handshake; | ||
logic dma_handshake_prev; | ||
assign dma_handshake = dma_ready && dma_valid_i; | ||
`FF(dma_handshake_prev, dma_handshake, 1'b0) | ||
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 | ||
|
||
// 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; | ||
|
||
endmodule | ||
Check warning on line 77 in hw/newusb/new_usb_dmaoutputqueueTD.sv GitHub Actions / verible-verilog-lint[verible-verilog-lint] hw/newusb/new_usb_dmaoutputqueueTD.sv#L77
Raw output
|