From 6c27daa30bf4837f38a17c351976758b8cdf5ab1 Mon Sep 17 00:00:00 2001 From: ikari Date: Sun, 12 Dec 2010 03:11:04 +0100 Subject: [PATCH] SD DMA, early status messages, DAC --- verilog/sd2snes/dac_test.v | 77 ++++++++++++++++++++++++ verilog/sd2snes/data.v | 2 +- verilog/sd2snes/sd_dma.v | 119 +++++++++++++++++++++++++++++++++++++ 3 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 verilog/sd2snes/dac_test.v create mode 100644 verilog/sd2snes/sd_dma.v diff --git a/verilog/sd2snes/dac_test.v b/verilog/sd2snes/dac_test.v new file mode 100644 index 0000000..1a78ba2 --- /dev/null +++ b/verilog/sd2snes/dac_test.v @@ -0,0 +1,77 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 19:26:11 07/23/2010 +// Design Name: +// Module Name: dac_test +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module dac_test( + input clkin, + output sdout, + output lrck, + output mclk + ); + +reg [15:0] cnt; +reg [15:0] smpcnt; +wire [15:0] sample = {smpcnt[10] ? ~smpcnt[9:0] : smpcnt[9:0], 6'b0}; +wire [15:0] sample2 = {smpcnt[9] ? ~smpcnt[8:0] : smpcnt[8:0], 7'b0}; +reg [15:0] smpshift; + +assign mclk = cnt[3]; // mclk = clk/8 +assign lrck = cnt[11]; // lrck = mclk/256 +wire sclk = cnt[6]; // sclk = lrck*32 + +reg [7:0] volume; +reg [1:0] lrck_sreg; +reg sclk_sreg; +wire lrck_rising = ({lrck_sreg[0],lrck} == 2'b01); +wire lrck_falling = ({lrck_sreg[0],lrck} == 2'b10); + +wire sclk_rising = ({sclk_sreg, sclk} == 2'b01); + +reg sdout_reg; +assign sdout = sdout_reg; + +initial begin + cnt = 16'b0; + smpcnt = 16'b0; + lrck_sreg = 2'b0; + sclk_sreg = 1'b0; + volume = 8'b0; +end + +always @(posedge clkin) begin + cnt <= cnt + 1; + lrck_sreg <= {lrck_sreg[0], lrck}; + sclk_sreg <= sclk; +end + +always @(posedge clkin) begin + if (lrck_rising) begin // right channel + smpshift <= (({16'h0, sample} * volume) >> 8) ^ 16'h8000; // convert to signed + end else if (lrck_falling) begin // left channel + smpshift <= (({16'h0, sample2} * volume) >> 8) ^ 16'h8000; + end else begin + if (sclk_rising) begin + smpcnt <= smpcnt + 1; + sdout_reg <= smpshift[15]; + smpshift <= {smpshift[14:0], 1'b0}; + end + end +end + +endmodule diff --git a/verilog/sd2snes/data.v b/verilog/sd2snes/data.v index d3f405f..16e8545 100644 --- a/verilog/sd2snes/data.v +++ b/verilog/sd2snes/data.v @@ -44,7 +44,7 @@ reg [7:0] MCU_OUT_MEM; wire [7:0] FROM_ROM_BYTE; -assign SNES_DATA = SNES_READ ? 8'bZ : SNES_OUT_MEM; +assign SNES_DATA = SNES_READ ? 8'bZ : (!MCU_OVR ? 8'h00 : SNES_OUT_MEM); assign FROM_ROM_BYTE = (ROM_ADDR0 ? ROM_DATA[7:0] : ROM_DATA[15:8]); diff --git a/verilog/sd2snes/sd_dma.v b/verilog/sd2snes/sd_dma.v new file mode 100644 index 0000000..3e8b4bc --- /dev/null +++ b/verilog/sd2snes/sd_dma.v @@ -0,0 +1,119 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 19:19:08 12/01/2010 +// Design Name: +// Module Name: sd_dma +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module sd_dma( + input [3:0] SD_DAT, + inout SD_CLK, + input CLK, + input SD_DMA_EN, + output SD_DMA_STATUS, + output SD_DMA_SRAM_WE, + output SD_DMA_NEXTADDR, + output [7:0] SD_DMA_SRAM_DATA + ); + +reg SD_DMA_DONEr; +reg[2:0] SD_DMA_DONEr2; +initial begin + SD_DMA_DONEr2 = 3'b000; + SD_DMA_DONEr = 1'b0; +end +always @(posedge CLK) SD_DMA_DONEr2 <= {SD_DMA_DONEr2[1:0], SD_DMA_DONEr}; +wire SD_DMA_DONE_rising = (SD_DMA_DONEr2 == 2'b01); + +reg [2:0] SD_DMA_ENr; +initial SD_DMA_ENr = 3'b000; +always @(posedge CLK) SD_DMA_ENr <= {SD_DMA_ENr[1:0], SD_DMA_EN}; +wire SD_DMA_EN_rising = (SD_DMA_ENr [1:0] == 2'b01); + +reg SD_DMA_STATUSr; +assign SD_DMA_STATUS = SD_DMA_STATUSr; + +// we need 1042 cycles (startbit + 1024 nibbles + 16 crc + stopbit) +reg [10:0] cyclecnt; +initial cyclecnt = 11'd0; + +reg SD_DMA_SRAM_WEr; +assign SD_DMA_SRAM_WE = (cyclecnt < 1025 && SD_DMA_STATUSr) ? SD_DMA_SRAM_WEr : 1'b1; + +reg SD_DMA_NEXTADDRr; +assign SD_DMA_NEXTADDR = (cyclecnt < 1025 && SD_DMA_STATUSr) ? SD_DMA_NEXTADDRr : 1'b0; + +reg[7:0] SD_DMA_SRAM_DATAr; +assign SD_DMA_SRAM_DATA = SD_DMA_SRAM_DATAr; + +// we have 4 internal cycles per SD clock +reg [12:0] clkcnt; +initial clkcnt = 13'd0; +reg SD_CLKr; +always @(posedge CLK) SD_CLKr <= clkcnt[1]; +assign SD_CLK = SD_DMA_STATUSr ? SD_CLKr : 1'bZ; + +always @(posedge CLK) begin + if(SD_DMA_EN_rising) SD_DMA_STATUSr <= 1'b1; + else if (SD_DMA_DONE_rising) SD_DMA_STATUSr <= 1'b0; +end + +always @(posedge CLK) begin + if(cyclecnt == 1042) SD_DMA_DONEr <= 1; + else SD_DMA_DONEr <= 0; +end + +always @(posedge CLK) begin + if(SD_DMA_EN_rising) begin + clkcnt <= 0; + end else begin + if(SD_DMA_STATUSr) begin + clkcnt <= clkcnt + 1; + end + end +end + +always @(posedge CLK) begin + if(SD_DMA_EN_rising) cyclecnt <= 0; + else if(clkcnt[1:0] == 2'b11) cyclecnt <= cyclecnt + 1; +end + +// we have 8 clk cycles to complete one RAM write +// (4 clk cycles per SD_CLK; 2 SD_CLK cycles per byte) +always @(posedge CLK) begin + if(SD_DMA_STATUSr) begin + case(clkcnt[2:0]) + 3'h0: begin + SD_DMA_SRAM_WEr <= 1'b1; + SD_DMA_SRAM_DATAr[7:4] <= SD_DAT; + if(cyclecnt>0 && cyclecnt < 1025) SD_DMA_NEXTADDRr <= 1'b1; + end + 3'h1: + SD_DMA_NEXTADDRr <= 1'b0; +// 3'h2: + 3'h3: + SD_DMA_SRAM_WEr <= 1'b0; + 3'h4: + SD_DMA_SRAM_DATAr[3:0] <= SD_DAT; +// 3'h5: +// 3'h6: +// 3'h7: + endcase + end +end + +endmodule +