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 cfg_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 flash_mem_bus,
@ -15,39 +15,39 @@ module memory_arbiter (
typedef enum bit [1:0] {
SOURCE_N64,
SOURCE_CFG,
SOURCE_USB_DMA//,
// SOURCE_SD_DMA
SOURCE_USB_DMA,
SOURCE_SD_DMA
} e_source_request;
logic n64_sdram_request;
logic cfg_sdram_request;
logic usb_dma_sdram_request;
// logic sd_dma_sdram_request;
logic sd_dma_sdram_request;
logic n64_flash_request;
logic cfg_flash_request;
logic usb_dma_flash_request;
// logic sd_dma_flash_request;
logic sd_dma_flash_request;
logic n64_bram_request;
logic cfg_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 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 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 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 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 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 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;
@ -59,8 +59,8 @@ module memory_arbiter (
sdram_mem_bus.request <= (
n64_sdram_request ||
cfg_sdram_request ||
usb_dma_sdram_request// ||
// sd_dma_sdram_request
usb_dma_sdram_request ||
sd_dma_sdram_request
);
if (n64_sdram_request) begin
@ -81,12 +81,12 @@ module memory_arbiter (
sdram_mem_bus.address <= usb_dma_bus.address;
sdram_mem_bus.wdata <= usb_dma_bus.wdata;
sdram_source_request <= SOURCE_USB_DMA;
// end else if (sd_dma_sdram_request) begin
// sdram_mem_bus.write <= sd_dma_bus.write;
// sdram_mem_bus.wmask <= sd_dma_bus.wmask;
// sdram_mem_bus.address <= sd_dma_bus.address;
// sdram_mem_bus.wdata <= sd_dma_bus.wdata;
// sdram_source_request <= SOURCE_SD_DMA;
end else if (sd_dma_sdram_request) begin
sdram_mem_bus.write <= sd_dma_bus.write;
sdram_mem_bus.wmask <= sd_dma_bus.wmask;
sdram_mem_bus.address <= sd_dma_bus.address;
sdram_mem_bus.wdata <= sd_dma_bus.wdata;
sdram_source_request <= SOURCE_SD_DMA;
end
end
@ -106,8 +106,8 @@ module memory_arbiter (
flash_mem_bus.request <= (
n64_flash_request ||
cfg_flash_request ||
usb_dma_flash_request// ||
// sd_dma_flash_request
usb_dma_flash_request ||
sd_dma_flash_request
);
if (n64_flash_request) begin
@ -128,12 +128,12 @@ module memory_arbiter (
flash_mem_bus.address <= usb_dma_bus.address;
flash_mem_bus.wdata <= usb_dma_bus.wdata;
flash_source_request <= SOURCE_USB_DMA;
// end else if (sd_dma_flash_request) begin
// flash_mem_bus.write <= sd_dma_bus.write;
// flash_mem_bus.wmask <= sd_dma_bus.wmask;
// flash_mem_bus.address <= sd_dma_bus.address;
// flash_mem_bus.wdata <= sd_dma_bus.wdata;
// flash_source_request <= SOURCE_SD_DMA;
end else if (sd_dma_flash_request) begin
flash_mem_bus.write <= sd_dma_bus.write;
flash_mem_bus.wmask <= sd_dma_bus.wmask;
flash_mem_bus.address <= sd_dma_bus.address;
flash_mem_bus.wdata <= sd_dma_bus.wdata;
flash_source_request <= SOURCE_SD_DMA;
end
end
@ -153,8 +153,8 @@ module memory_arbiter (
bram_mem_bus.request <= (
n64_bram_request ||
cfg_bram_request ||
usb_dma_bram_request// ||
// sd_dma_bram_request
usb_dma_bram_request ||
sd_dma_bram_request
);
if (n64_bram_request) begin
@ -175,12 +175,12 @@ module memory_arbiter (
bram_mem_bus.address <= usb_dma_bus.address;
bram_mem_bus.wdata <= usb_dma_bus.wdata;
bram_source_request <= SOURCE_USB_DMA;
// end else if (sd_dma_bram_request) begin
// bram_mem_bus.write <= sd_dma_bus.write;
// bram_mem_bus.wmask <= sd_dma_bus.wmask;
// bram_mem_bus.address <= sd_dma_bus.address;
// bram_mem_bus.wdata <= sd_dma_bus.wdata;
// bram_source_request <= SOURCE_SD_DMA;
end else if (sd_dma_bram_request) begin
bram_mem_bus.write <= sd_dma_bus.write;
bram_mem_bus.wmask <= sd_dma_bus.wmask;
bram_mem_bus.address <= sd_dma_bus.address;
bram_mem_bus.wdata <= sd_dma_bus.wdata;
bram_source_request <= SOURCE_SD_DMA;
end
end
@ -206,11 +206,11 @@ module memory_arbiter (
((flash_source_request == SOURCE_USB_DMA) && flash_mem_bus.ack) ||
((bram_source_request == SOURCE_USB_DMA) && bram_mem_bus.ack)
);
// sd_dma_bus.ack = (
// ((sdram_source_request == SOURCE_SD_DMA) && sdram_mem_bus.ack) ||
// ((flash_source_request == SOURCE_SD_DMA) && flash_mem_bus.ack) ||
// ((bram_source_request == SOURCE_SD_DMA) && bram_mem_bus.ack)
// );
sd_dma_bus.ack = (
((sdram_source_request == SOURCE_SD_DMA) && sdram_mem_bus.ack) ||
((flash_source_request == SOURCE_SD_DMA) && flash_mem_bus.ack) ||
((bram_source_request == SOURCE_SD_DMA) && bram_mem_bus.ack)
);
n64_bus.rdata = n64_bram_request ? bram_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_flash_request ? flash_mem_bus.rdata :
sdram_mem_bus.rdata;
// sd_dma_bus.rdata = sd_dma_bram_request ? bram_mem_bus.rdata :
// sd_dma_flash_request ? flash_mem_bus.rdata :
// sdram_mem_bus.rdata;
sd_dma_bus.rdata = sd_dma_bram_request ? bram_mem_bus.rdata :
sd_dma_flash_request ? flash_mem_bus.rdata :
sdram_mem_bus.rdata;
end
endmodule

View File

@ -38,130 +38,217 @@ module memory_dma (
mem_bus.controller mem_bus
);
typedef enum bit [0:0] {
STATE_FETCH,
STATE_TRANSFER
} e_state;
// DMA start/stop control
// logic [31:0] remaining;
logic [26:0] end_address;
logic [15:0] data_buffer;
logic byte_counter;
e_state state;
logic rx_delay;
logic dma_start;
logic dma_stop;
always_comb begin
dma_start = dma_scb.start && !dma_scb.stop && !dma_scb.busy;
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
fifo_bus.rx_read <= 1'b0;
fifo_bus.tx_write <= 1'b0;
rx_delay <= fifo_bus.rx_read;
rx_rdata_pop <= (
!rx_rdata_pop &&
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.address[0] || (remaining == 32'd1)) begin
// dma.wdata <= {dma.rx_rdata, dma.rx_rdata};
// end else begin
mem_bus.wdata <= {mem_bus.wdata[7:0], fifo_bus.rx_rdata};
// end
if (dma_start) begin
if (dma_scb.starting_address[0]) begin
mem_bus.wmask <= 2'b01;
rx_buffer_counter <= 2'd1;
rx_buffer_valid_counter <= 2'd1;
end else begin
mem_bus.wmask <= 2'b11;
rx_buffer_counter <= 2'd0;
rx_buffer_valid_counter <= 2'd0;
end
end
if (reset) begin
dma_scb.busy <= 1'b0;
mem_bus.request <= 1'b0;
if (rx_rdata_pop) begin
rx_buffer_counter <= rx_buffer_counter + 1'd1;
end
if (rx_rdata_shift || rx_rdata_valid) begin
rx_buffer <= {rx_buffer[7:0], fifo_bus.rx_rdata};
rx_buffer_valid_counter <= rx_buffer_valid_counter + 1'd1;
if (remaining == 27'd0 && rx_buffer_counter == 2'd1) begin
mem_bus.wmask <= 2'b10;
rx_rdata_shift <= 1'b1;
rx_buffer_counter <= rx_buffer_counter + 1'd1;
end
end
if (rx_buffer_valid && !mem_bus.request) begin
rx_buffer_counter <= 2'd0;
rx_buffer_valid_counter <= 2'd0;
end
end
// 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
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
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;
state <= STATE_TRANSFER;
end
// end
end
end
if (dma_start) begin
remaining <= dma_scb.transfer_length;
end
STATE_TRANSFER: begin
if (!fifo_bus.rx_read) begin
mem_bus.request <= 1'b1;
end
if (mem_bus.ack) begin
mem_bus.request <= 1'b0;
// if (dma.wmask != 2'b11) begin
// dma.address <= dma.address + 1'd1;
// remaining <= remaining - 1'd1;
// end else begin
mem_bus.address <= mem_bus.address + 2'd2;
// remaining <= remaining - 2'd2;
// 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
if ((mem_bus.write && rx_rdata_pop) || (!mem_bus.write && tx_wdata_push)) begin
remaining <= remaining - 1'd1;
end
end
end
STATE_TRANSFER: begin
if (!fifo_bus.tx_full && !(fifo_bus.tx_write && fifo_bus.tx_almost_full)) begin
fifo_bus.tx_write <= 1'b1;
// 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
endcase
end
end else begin
// 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;
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

View File

@ -66,7 +66,7 @@ module top (
mem_bus n64_mem_bus ();
mem_bus cfg_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 flash_mem_bus ();
mem_bus bram_mem_bus ();
@ -167,28 +167,28 @@ module top (
// SD card
// sd_top sd_top_inst (
// .clk(clk),
// .reset(reset),
sd_top sd_top_inst (
.clk(clk),
.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_cmd(sd_cmd),
// .sd_dat(sd_dat)
// );
.sd_clk(sd_clk),
.sd_cmd(sd_cmd),
.sd_dat(sd_dat)
);
// memory_dma memory_sd_dma_inst (
// .clk(clk),
// .reset(reset),
memory_dma memory_sd_dma_inst (
.clk(clk),
.reset(reset),
// .dma_scb(sd_dma_scb),
.dma_scb(sd_dma_scb),
// .fifo_bus(sd_fifo_bus),
// .mem_bus(sd_dma_mem_bus)
// );
.fifo_bus(sd_fifo_bus),
.mem_bus(sd_dma_mem_bus)
);
// Memory bus arbiter
@ -200,7 +200,7 @@ module top (
.n64_bus(n64_mem_bus),
.cfg_bus(cfg_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),
.flash_mem_bus(flash_mem_bus),