dma rewrite, needs testing

This commit is contained in:
Polprzewodnikowy 2022-07-22 00:42:35 +02:00
parent 470b61aad9
commit b30537ead8
3 changed files with 257 additions and 170 deletions

View File

@ -5,7 +5,7 @@ module memory_arbiter (
mem_bus.memory n64_bus, mem_bus.memory n64_bus,
mem_bus.memory cfg_bus, mem_bus.memory cfg_bus,
mem_bus.memory usb_dma_bus, mem_bus.memory usb_dma_bus,
// mem_bus.memory sd_dma_bus, mem_bus.memory sd_dma_bus,
mem_bus.controller sdram_mem_bus, mem_bus.controller sdram_mem_bus,
mem_bus.controller flash_mem_bus, mem_bus.controller flash_mem_bus,
@ -15,39 +15,39 @@ module memory_arbiter (
typedef enum bit [1:0] { typedef enum bit [1:0] {
SOURCE_N64, SOURCE_N64,
SOURCE_CFG, SOURCE_CFG,
SOURCE_USB_DMA//, SOURCE_USB_DMA,
// SOURCE_SD_DMA SOURCE_SD_DMA
} e_source_request; } e_source_request;
logic n64_sdram_request; logic n64_sdram_request;
logic cfg_sdram_request; logic cfg_sdram_request;
logic usb_dma_sdram_request; logic usb_dma_sdram_request;
// logic sd_dma_sdram_request; logic sd_dma_sdram_request;
logic n64_flash_request; logic n64_flash_request;
logic cfg_flash_request; logic cfg_flash_request;
logic usb_dma_flash_request; logic usb_dma_flash_request;
// logic sd_dma_flash_request; logic sd_dma_flash_request;
logic n64_bram_request; logic n64_bram_request;
logic cfg_bram_request; logic cfg_bram_request;
logic usb_dma_bram_request; logic usb_dma_bram_request;
// logic sd_dma_bram_request; logic sd_dma_bram_request;
assign n64_sdram_request = n64_bus.request && !n64_bus.address[26]; assign n64_sdram_request = n64_bus.request && !n64_bus.address[26];
assign cfg_sdram_request = cfg_bus.request && !cfg_bus.address[26]; assign cfg_sdram_request = cfg_bus.request && !cfg_bus.address[26];
assign usb_dma_sdram_request = usb_dma_bus.request && !usb_dma_bus.address[26]; assign usb_dma_sdram_request = usb_dma_bus.request && !usb_dma_bus.address[26];
// assign sd_dma_sdram_request = sd_dma_bus.request && !sd_dma_bus.address[26]; assign sd_dma_sdram_request = sd_dma_bus.request && !sd_dma_bus.address[26];
assign n64_flash_request = n64_bus.request && (n64_bus.address[26:25] == 2'b10); assign n64_flash_request = n64_bus.request && (n64_bus.address[26:25] == 2'b10);
assign cfg_flash_request = cfg_bus.request && (cfg_bus.address[26:25] == 2'b10); assign cfg_flash_request = cfg_bus.request && (cfg_bus.address[26:25] == 2'b10);
assign usb_dma_flash_request = usb_dma_bus.request && (usb_dma_bus.address[26:25] == 2'b10); assign usb_dma_flash_request = usb_dma_bus.request && (usb_dma_bus.address[26:25] == 2'b10);
// assign sd_dma_flash_request = sd_dma_bus.request && (sd_dma_bus.address[26:25] == 2'b10); assign sd_dma_flash_request = sd_dma_bus.request && (sd_dma_bus.address[26:25] == 2'b10);
assign n64_bram_request = n64_bus.request && (n64_bus.address[26:25] == 2'b11); assign n64_bram_request = n64_bus.request && (n64_bus.address[26:25] == 2'b11);
assign cfg_bram_request = cfg_bus.request && (cfg_bus.address[26:25] == 2'b11); assign cfg_bram_request = cfg_bus.request && (cfg_bus.address[26:25] == 2'b11);
assign usb_dma_bram_request = usb_dma_bus.request && (usb_dma_bus.address[26:25] == 2'b11); assign usb_dma_bram_request = usb_dma_bus.request && (usb_dma_bus.address[26:25] == 2'b11);
// assign sd_dma_bram_request = sd_dma_bus.request && (sd_dma_bus.address[26:25] == 2'b11); assign sd_dma_bram_request = sd_dma_bus.request && (sd_dma_bus.address[26:25] == 2'b11);
e_source_request sdram_source_request; e_source_request sdram_source_request;
@ -59,8 +59,8 @@ module memory_arbiter (
sdram_mem_bus.request <= ( sdram_mem_bus.request <= (
n64_sdram_request || n64_sdram_request ||
cfg_sdram_request || cfg_sdram_request ||
usb_dma_sdram_request// || usb_dma_sdram_request ||
// sd_dma_sdram_request sd_dma_sdram_request
); );
if (n64_sdram_request) begin if (n64_sdram_request) begin
@ -81,12 +81,12 @@ module memory_arbiter (
sdram_mem_bus.address <= usb_dma_bus.address; sdram_mem_bus.address <= usb_dma_bus.address;
sdram_mem_bus.wdata <= usb_dma_bus.wdata; sdram_mem_bus.wdata <= usb_dma_bus.wdata;
sdram_source_request <= SOURCE_USB_DMA; sdram_source_request <= SOURCE_USB_DMA;
// end else if (sd_dma_sdram_request) begin end else if (sd_dma_sdram_request) begin
// sdram_mem_bus.write <= sd_dma_bus.write; sdram_mem_bus.write <= sd_dma_bus.write;
// sdram_mem_bus.wmask <= sd_dma_bus.wmask; sdram_mem_bus.wmask <= sd_dma_bus.wmask;
// sdram_mem_bus.address <= sd_dma_bus.address; sdram_mem_bus.address <= sd_dma_bus.address;
// sdram_mem_bus.wdata <= sd_dma_bus.wdata; sdram_mem_bus.wdata <= sd_dma_bus.wdata;
// sdram_source_request <= SOURCE_SD_DMA; sdram_source_request <= SOURCE_SD_DMA;
end end
end end
@ -106,8 +106,8 @@ module memory_arbiter (
flash_mem_bus.request <= ( flash_mem_bus.request <= (
n64_flash_request || n64_flash_request ||
cfg_flash_request || cfg_flash_request ||
usb_dma_flash_request// || usb_dma_flash_request ||
// sd_dma_flash_request sd_dma_flash_request
); );
if (n64_flash_request) begin if (n64_flash_request) begin
@ -128,12 +128,12 @@ module memory_arbiter (
flash_mem_bus.address <= usb_dma_bus.address; flash_mem_bus.address <= usb_dma_bus.address;
flash_mem_bus.wdata <= usb_dma_bus.wdata; flash_mem_bus.wdata <= usb_dma_bus.wdata;
flash_source_request <= SOURCE_USB_DMA; flash_source_request <= SOURCE_USB_DMA;
// end else if (sd_dma_flash_request) begin end else if (sd_dma_flash_request) begin
// flash_mem_bus.write <= sd_dma_bus.write; flash_mem_bus.write <= sd_dma_bus.write;
// flash_mem_bus.wmask <= sd_dma_bus.wmask; flash_mem_bus.wmask <= sd_dma_bus.wmask;
// flash_mem_bus.address <= sd_dma_bus.address; flash_mem_bus.address <= sd_dma_bus.address;
// flash_mem_bus.wdata <= sd_dma_bus.wdata; flash_mem_bus.wdata <= sd_dma_bus.wdata;
// flash_source_request <= SOURCE_SD_DMA; flash_source_request <= SOURCE_SD_DMA;
end end
end end
@ -153,8 +153,8 @@ module memory_arbiter (
bram_mem_bus.request <= ( bram_mem_bus.request <= (
n64_bram_request || n64_bram_request ||
cfg_bram_request || cfg_bram_request ||
usb_dma_bram_request// || usb_dma_bram_request ||
// sd_dma_bram_request sd_dma_bram_request
); );
if (n64_bram_request) begin if (n64_bram_request) begin
@ -175,12 +175,12 @@ module memory_arbiter (
bram_mem_bus.address <= usb_dma_bus.address; bram_mem_bus.address <= usb_dma_bus.address;
bram_mem_bus.wdata <= usb_dma_bus.wdata; bram_mem_bus.wdata <= usb_dma_bus.wdata;
bram_source_request <= SOURCE_USB_DMA; bram_source_request <= SOURCE_USB_DMA;
// end else if (sd_dma_bram_request) begin end else if (sd_dma_bram_request) begin
// bram_mem_bus.write <= sd_dma_bus.write; bram_mem_bus.write <= sd_dma_bus.write;
// bram_mem_bus.wmask <= sd_dma_bus.wmask; bram_mem_bus.wmask <= sd_dma_bus.wmask;
// bram_mem_bus.address <= sd_dma_bus.address; bram_mem_bus.address <= sd_dma_bus.address;
// bram_mem_bus.wdata <= sd_dma_bus.wdata; bram_mem_bus.wdata <= sd_dma_bus.wdata;
// bram_source_request <= SOURCE_SD_DMA; bram_source_request <= SOURCE_SD_DMA;
end end
end end
@ -206,11 +206,11 @@ module memory_arbiter (
((flash_source_request == SOURCE_USB_DMA) && flash_mem_bus.ack) || ((flash_source_request == SOURCE_USB_DMA) && flash_mem_bus.ack) ||
((bram_source_request == SOURCE_USB_DMA) && bram_mem_bus.ack) ((bram_source_request == SOURCE_USB_DMA) && bram_mem_bus.ack)
); );
// sd_dma_bus.ack = ( sd_dma_bus.ack = (
// ((sdram_source_request == SOURCE_SD_DMA) && sdram_mem_bus.ack) || ((sdram_source_request == SOURCE_SD_DMA) && sdram_mem_bus.ack) ||
// ((flash_source_request == SOURCE_SD_DMA) && flash_mem_bus.ack) || ((flash_source_request == SOURCE_SD_DMA) && flash_mem_bus.ack) ||
// ((bram_source_request == SOURCE_SD_DMA) && bram_mem_bus.ack) ((bram_source_request == SOURCE_SD_DMA) && bram_mem_bus.ack)
// ); );
n64_bus.rdata = n64_bram_request ? bram_mem_bus.rdata : n64_bus.rdata = n64_bram_request ? bram_mem_bus.rdata :
n64_flash_request ? flash_mem_bus.rdata : n64_flash_request ? flash_mem_bus.rdata :
@ -221,9 +221,9 @@ module memory_arbiter (
usb_dma_bus.rdata = usb_dma_bram_request ? bram_mem_bus.rdata : usb_dma_bus.rdata = usb_dma_bram_request ? bram_mem_bus.rdata :
usb_dma_flash_request ? flash_mem_bus.rdata : usb_dma_flash_request ? flash_mem_bus.rdata :
sdram_mem_bus.rdata; sdram_mem_bus.rdata;
// sd_dma_bus.rdata = sd_dma_bram_request ? bram_mem_bus.rdata : sd_dma_bus.rdata = sd_dma_bram_request ? bram_mem_bus.rdata :
// sd_dma_flash_request ? flash_mem_bus.rdata : sd_dma_flash_request ? flash_mem_bus.rdata :
// sdram_mem_bus.rdata; sdram_mem_bus.rdata;
end end
endmodule endmodule

View File

@ -38,130 +38,217 @@ module memory_dma (
mem_bus.controller mem_bus mem_bus.controller mem_bus
); );
typedef enum bit [0:0] { // DMA start/stop control
STATE_FETCH,
STATE_TRANSFER
} e_state;
// logic [31:0] remaining; logic dma_start;
logic [26:0] end_address; logic dma_stop;
logic [15:0] data_buffer;
logic byte_counter; always_comb begin
e_state state; dma_start = dma_scb.start && !dma_scb.stop && !dma_scb.busy;
logic rx_delay; dma_stop = dma_scb.stop;
end
// Remaining counter and FIFO enable
logic [26:0] remaining;
logic trx_enabled;
always_comb begin
trx_enabled = remaining > 27'd0;
end
// RX FIFO controller
logic rx_rdata_pop;
logic rx_rdata_shift;
logic rx_rdata_valid;
logic [15:0] rx_buffer;
logic rx_buffer_valid;
logic [1:0] rx_buffer_counter;
logic [1:0] rx_buffer_valid_counter;
always_comb begin
rx_buffer_valid = rx_buffer_valid_counter == 2'd2;
end
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
fifo_bus.rx_read <= 1'b0; rx_rdata_pop <= (
fifo_bus.tx_write <= 1'b0; !rx_rdata_pop &&
rx_delay <= fifo_bus.rx_read; trx_enabled &&
rx_buffer_counter < 2'd2 &&
!fifo_bus.rx_empty &&
mem_bus.write
);
rx_rdata_shift <= 1'b0;
fifo_bus.rx_read <= rx_rdata_pop;
rx_rdata_valid <= fifo_bus.rx_read;
if (rx_delay) begin if (dma_start) begin
// if (dma.address[0] || (remaining == 32'd1)) begin if (dma_scb.starting_address[0]) begin
// dma.wdata <= {dma.rx_rdata, dma.rx_rdata}; mem_bus.wmask <= 2'b01;
// end else begin rx_buffer_counter <= 2'd1;
mem_bus.wdata <= {mem_bus.wdata[7:0], fifo_bus.rx_rdata}; rx_buffer_valid_counter <= 2'd1;
// end
end
if (reset) begin
dma_scb.busy <= 1'b0;
mem_bus.request <= 1'b0;
end else begin end else begin
if (!dma_scb.busy) begin
if (dma_scb.start) begin
dma_scb.busy <= 1'b1;
mem_bus.write <= dma_scb.direction;
mem_bus.address <= dma_scb.starting_address;
end_address <= dma_scb.starting_address + dma_scb.transfer_length;
// remaining <= dma.transfer_length;
byte_counter <= 1'd0;
state <= STATE_FETCH;
end
end else begin
if (dma_scb.stop) begin
dma_scb.busy <= 1'b0;
mem_bus.request <= 1'b0;
end else if (mem_bus.address != end_address/* remaining != 32'd0*/) begin
if (mem_bus.write) begin
case (state)
STATE_FETCH: begin
if (!fifo_bus.rx_empty && !(fifo_bus.rx_read && fifo_bus.rx_almost_empty)) begin
fifo_bus.rx_read <= 1'b1;
// if (dma.address[0]) begin
// dma.wmask <= 2'b01;
// state <= STATE_TRANSFER;
// end else if (dma.starting_address[0] remaining == 32'd1) begin
// dma.wmask <= 2'b10;
// state <= STATE_TRANSFER;
// end else begin
byte_counter <= byte_counter + 1'd1;
if (byte_counter) begin
mem_bus.wmask <= 2'b11; mem_bus.wmask <= 2'b11;
state <= STATE_TRANSFER; rx_buffer_counter <= 2'd0;
end rx_buffer_valid_counter <= 2'd0;
// end
end end
end end
STATE_TRANSFER: begin if (rx_rdata_pop) begin
if (!fifo_bus.rx_read) begin rx_buffer_counter <= rx_buffer_counter + 1'd1;
mem_bus.request <= 1'b1;
end end
if (mem_bus.ack) begin
mem_bus.request <= 1'b0; if (rx_rdata_shift || rx_rdata_valid) begin
// if (dma.wmask != 2'b11) begin rx_buffer <= {rx_buffer[7:0], fifo_bus.rx_rdata};
// dma.address <= dma.address + 1'd1; rx_buffer_valid_counter <= rx_buffer_valid_counter + 1'd1;
// remaining <= remaining - 1'd1; if (remaining == 27'd0 && rx_buffer_counter == 2'd1) begin
// end else begin mem_bus.wmask <= 2'b10;
mem_bus.address <= mem_bus.address + 2'd2; rx_rdata_shift <= 1'b1;
// remaining <= remaining - 2'd2; rx_buffer_counter <= rx_buffer_counter + 1'd1;
// end
state <= STATE_FETCH;
end
end
endcase
end else begin
case (state)
STATE_FETCH: begin
mem_bus.request <= 1'b1;
if (mem_bus.ack) begin
mem_bus.request <= 1'b0;
data_buffer <= mem_bus.rdata;
state <= STATE_TRANSFER;
end end
end end
STATE_TRANSFER: begin if (rx_buffer_valid && !mem_bus.request) begin
if (!fifo_bus.tx_full && !(fifo_bus.tx_write && fifo_bus.tx_almost_full)) begin rx_buffer_counter <= 2'd0;
fifo_bus.tx_write <= 1'b1; rx_buffer_valid_counter <= 2'd0;
// if (dma.address[0]) begin
// dma.address <= dma.address + 1'd1;
// // remaining <= remaining - 1'd1;
// dma.dma_tx_wdata <= data_buffer[7:0];
// state <= STATE_FETCH;
// end else if (remaining == 32'd1) begin
// dma.address <= dma.address + 1'd1;
// // remaining <= remaining - 1'd1;
// dma.dma_tx_wdata <= data_buffer[15:8];
// state <= STATE_FETCH;
// end else begin
fifo_bus.tx_wdata <= byte_counter ? data_buffer[7:0] : data_buffer[15:8];
byte_counter <= byte_counter + 1'd1;
if (byte_counter) begin
mem_bus.address <= mem_bus.address + 2'd2;
// remaining <= remaining - 2'd2;
state <= STATE_FETCH;
end
// end
end end
end end
endcase
// TX FIFO controller
logic tx_wdata_push;
logic tx_wdata_first_push;
logic [7:0] tx_buffer;
logic tx_buffer_counter;
logic tx_buffer_ready;
logic tx_buffer_valid;
always_comb begin
fifo_bus.tx_write = tx_wdata_push;
end end
always_ff @(posedge clk) begin
tx_wdata_push <= (
!tx_wdata_push &&
trx_enabled &&
tx_buffer_valid &&
!fifo_bus.tx_full &&
!mem_bus.write
);
if (reset || dma_stop) begin
tx_buffer_ready <= 1'b0;
tx_buffer_valid <= 1'b0;
end
if (dma_start) begin
tx_wdata_first_push <= 1'b1;
tx_buffer_ready <= 1'b1;
tx_buffer_valid <= 1'b0;
end
if (tx_buffer_ready && mem_bus.request) begin
tx_buffer_ready <= 1'b0;
end
if (mem_bus.ack) begin
tx_wdata_first_push <= 1'b0;
tx_buffer_counter <= 1'd1;
tx_buffer_valid <= 1'b1;
{fifo_bus.tx_wdata, tx_buffer} <= mem_bus.rdata;
if (tx_wdata_first_push && dma_scb.starting_address[0]) begin
fifo_bus.tx_wdata <= mem_bus.rdata[7:0];
tx_buffer_counter <= 1'd0;
end
end
if (tx_wdata_push) begin
tx_buffer_counter <= tx_buffer_counter - 1'd1;
fifo_bus.tx_wdata <= tx_buffer;
if (tx_buffer_counter == 1'd0) begin
tx_buffer_ready <= 1'b1;
tx_buffer_valid <= 1'b0;
end
end
end
// Remaining counter controller
always_ff @(posedge clk) begin
if (reset || dma_stop) begin
remaining <= 27'd0;
end else begin end else begin
if (dma_start) begin
remaining <= dma_scb.transfer_length;
end
if ((mem_bus.write && rx_rdata_pop) || (!mem_bus.write && tx_wdata_push)) begin
remaining <= remaining - 1'd1;
end
end
end
// Mem bus controller
always_ff @(posedge clk) begin
if (reset || dma_scb.stop) begin
dma_scb.busy <= 1'b0;
end else begin
if (dma_start) begin
dma_scb.busy <= 1'b1;
end
if (dma_scb.busy) begin
if (!trx_enabled) begin
dma_scb.busy <= 1'b0; dma_scb.busy <= 1'b0;
end end
end end
end end
end end
always_ff @(posedge clk) begin
if (reset || dma_scb.stop) begin
mem_bus.request <= 1'b0;
end else begin
if (dma_scb.busy && !mem_bus.request) begin
if (mem_bus.write) begin
if (rx_buffer_valid) begin
mem_bus.request <= 1'b1;
mem_bus.wdata <= rx_buffer;
end
end else begin
if (tx_buffer_ready) begin
mem_bus.request <= 1'b1;
end
end
end
end
if (mem_bus.ack) begin
mem_bus.request <= 1'b0;
end
end
always_ff @(posedge clk) begin
if (dma_start) begin
mem_bus.write <= dma_scb.direction;
end
end
always_ff @(posedge clk) begin
if (dma_start) begin
mem_bus.address <= {dma_scb.starting_address[26:1], 1'b0};
end
if (mem_bus.ack) begin
mem_bus.address <= mem_bus.address + 2'd2;
end
end
endmodule endmodule

View File

@ -66,7 +66,7 @@ module top (
mem_bus n64_mem_bus (); mem_bus n64_mem_bus ();
mem_bus cfg_mem_bus (); mem_bus cfg_mem_bus ();
mem_bus usb_dma_mem_bus (); mem_bus usb_dma_mem_bus ();
// mem_bus sd_dma_mem_bus (); mem_bus sd_dma_mem_bus ();
mem_bus sdram_mem_bus (); mem_bus sdram_mem_bus ();
mem_bus flash_mem_bus (); mem_bus flash_mem_bus ();
mem_bus bram_mem_bus (); mem_bus bram_mem_bus ();
@ -167,28 +167,28 @@ module top (
// SD card // SD card
// sd_top sd_top_inst ( sd_top sd_top_inst (
// .clk(clk), .clk(clk),
// .reset(reset), .reset(reset),
// .sd_scb(sd_scb), .sd_scb(sd_scb),
// .fifo_bus(sd_fifo_bus), .fifo_bus(sd_fifo_bus),
// .sd_clk(sd_clk), .sd_clk(sd_clk),
// .sd_cmd(sd_cmd), .sd_cmd(sd_cmd),
// .sd_dat(sd_dat) .sd_dat(sd_dat)
// ); );
// memory_dma memory_sd_dma_inst ( memory_dma memory_sd_dma_inst (
// .clk(clk), .clk(clk),
// .reset(reset), .reset(reset),
// .dma_scb(sd_dma_scb), .dma_scb(sd_dma_scb),
// .fifo_bus(sd_fifo_bus), .fifo_bus(sd_fifo_bus),
// .mem_bus(sd_dma_mem_bus) .mem_bus(sd_dma_mem_bus)
// ); );
// Memory bus arbiter // Memory bus arbiter
@ -200,7 +200,7 @@ module top (
.n64_bus(n64_mem_bus), .n64_bus(n64_mem_bus),
.cfg_bus(cfg_mem_bus), .cfg_bus(cfg_mem_bus),
.usb_dma_bus(usb_dma_mem_bus), .usb_dma_bus(usb_dma_mem_bus),
// .sd_dma_bus(sd_dma_mem_bus), .sd_dma_bus(sd_dma_mem_bus),
.sdram_mem_bus(sdram_mem_bus), .sdram_mem_bus(sdram_mem_bus),
.flash_mem_bus(flash_mem_bus), .flash_mem_bus(flash_mem_bus),