diff --git a/tridoracpu/tridoracpu.srcs/Arty-A7-35-Master.xdc b/tridoracpu/tridoracpu.srcs/Arty-A7-35-Master.xdc index 7c62767..2a33ae0 100644 --- a/tridoracpu/tridoracpu.srcs/Arty-A7-35-Master.xdc +++ b/tridoracpu/tridoracpu.srcs/Arty-A7-35-Master.xdc @@ -70,10 +70,10 @@ set_property -dict {PACKAGE_PIN V14 IOSTANDARD LVCMOS33} [get_ports VGA_VS_O] #set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { jc[7] }]; #IO_L23N_T3_A02_D18_14 Sch=jc_n[4] ## Pmod Header JD -#set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { jd[0] }]; #IO_L11N_T1_SRCC_35 Sch=jd[1] -#set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { jd[1] }]; #IO_L12N_T1_MRCC_35 Sch=jd[2] +set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { amp2_ain }]; #IO_L11N_T1_SRCC_35 Sch=jd[1] +set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { amp2_gain }]; #IO_L12N_T1_MRCC_35 Sch=jd[2] #set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { jd[2] }]; #IO_L13P_T2_MRCC_35 Sch=jd[3] -#set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { jd[3] }]; #IO_L13N_T2_MRCC_35 Sch=jd[4] +set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { amp2_shutdown_n }]; #IO_L13N_T2_MRCC_35 Sch=jd[4] #set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { jd[4] }]; #IO_L14P_T2_SRCC_35 Sch=jd[7] #set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { jd[5] }]; #IO_L14N_T2_SRCC_35 Sch=jd[8] #set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { jd[6] }]; #IO_L15P_T2_DQS_35 Sch=jd[9] diff --git a/tridoracpu/tridoracpu.srcs/tdraudio.v b/tridoracpu/tridoracpu.srcs/tdraudio.v new file mode 100644 index 0000000..dbd0dc3 --- /dev/null +++ b/tridoracpu/tridoracpu.srcs/tdraudio.v @@ -0,0 +1,74 @@ +`timescale 1ns / 1ps + +module tdraudio #(DATA_WIDTH=32) ( + input wire clk, + input wire reset, + input wire [3:0] reg_sel, + output wire [DATA_WIDTH-1:0] rd_data, + input wire [DATA_WIDTH-1:0] wr_data, + input wire rd_en, + input wire wr_en, + + output wire pdm_out, + output wire gain_en, + output wire shutdown_n + ); + + localparam CLOCK_DIV_WIDTH = 22; + + localparam TDRAU_REG_CTL = 0; /* control register */ + localparam TDRAU_REG_CLK = 1; /* clock divider register */ + + reg audio_out; + reg channel_enable; + reg [CLOCK_DIV_WIDTH-1:0] clock_div; + reg [CLOCK_DIV_WIDTH-1:0] div_count; + + assign pdm_out = audio_out; + assign rd_data = {{DATA_WIDTH-8-CLOCK_DIV_WIDTH{1'b0}}, div_count, {7{1'b0}}, channel_enable}; + assign gain_en = 0; + assign shutdown_n = channel_enable; + + /* channel enable flag */ + always @(posedge clk) + begin + if(reset) + channel_enable <= 0; + else if (wr_en && (reg_sel == TDRAU_REG_CTL)) + channel_enable <= wr_data[0]; + end + + /* clock divider register */ + always @(posedge clk) + begin + if(reset) + clock_div <= 0; + else if (wr_en && (reg_sel == TDRAU_REG_CLK)) + clock_div <= wr_data; + end + + /* divider counter */ + always @(posedge clk) + begin + if(channel_enable) + begin + if(div_count == 0) // reset counter if it reaches zero + div_count <= clock_div; + else + div_count <= div_count - 1; // else just decrement it + end + else + if (wr_en && (reg_sel == TDRAU_REG_CLK)) + div_count <= 0; // set counter to zero whenever the clock divider is set + end + + /* 1-bit audio output */ + always @(posedge clk) + begin + if (reset) + audio_out <= 0; + else + if (channel_enable && (div_count == 0)) + audio_out <= ~audio_out; + end +endmodule diff --git a/tridoracpu/tridoracpu.srcs/top.v b/tridoracpu/tridoracpu.srcs/top.v index 00066fe..81d236b 100644 --- a/tridoracpu/tridoracpu.srcs/top.v +++ b/tridoracpu/tridoracpu.srcs/top.v @@ -10,6 +10,7 @@ //`define clock clk_1hz `define ENABLE_VGAFB `define ENABLE_MICROSD +`define ENABLE_TDRAUDIO module top( input wire clk, @@ -60,6 +61,13 @@ module top( output wire sd_sck, input wire sd_cd `endif + +`ifdef ENABLE_TDRAUDIO + , + output wire amp2_ain, + output wire amp2_gain, + output wire amp2_shutdown_n +`endif ); reg clk_1hz; @@ -220,6 +228,7 @@ module top( assign uart_tx_data = mem_write_data[7:0]; assign uart_rd_data = { {WIDTH-10{1'b1}}, uart_rx_avail, uart_tx_busy, uart_rx_data }; + // interrupt controller reg timer_tick; reg[23:0] tick_count; wire [1:0] irq_in = { timer_tick, uart_rx_avail }; @@ -228,6 +237,25 @@ module top( wire irqc_seten = mem_write_data[7]; wire irqc_cs = io_enable && (io_slot == 3); +`ifdef ENABLE_TDRAUDIO + wire [WIDTH-1:0] tdraudio_wr_data; + wire [WIDTH-1:0] tdraudio_rd_data; + wire tdraudio_rd_en, tdraudio_wr_en; + + wire tdraudio_cs_en = io_enable && (io_slot == 4); + assign tdraudio_rd_en = tdraudio_cs_en && mem_read_enable; + assign tdraudio_wr_en = tdraudio_cs_en && mem_write_enable; + assign tdraudio_wr_data = mem_write_data; + + tdraudio tdraudio0(`clock, ~rst, + mem_addr[3:0], + tdraudio_rd_data, + tdraudio_wr_data, + tdraudio_rd_en, + tdraudio_wr_en, + amp2_ain, amp2_gain, amp2_shutdown_n); +`endif + assign io_rd_data = (io_slot == 0) ? uart_rd_data : `ifdef ENABLE_MICROSD (io_slot == 1) ? spi_rd_data : @@ -236,7 +264,9 @@ module top( (io_slot == 2) ? fb_rd_data : `endif (io_slot == 3) ? irqc_rd_data: - + `ifdef ENABLE_TDRAUDIO + (io_slot == 4) ? tdraudio_rd_data: + `endif -1; buart #(.CLKFREQ(`clkfreq)) uart0(`clock, rst, diff --git a/tridoracpu/tridoracpu.xpr b/tridoracpu/tridoracpu.xpr index 36b5512..c5b003f 100644 --- a/tridoracpu/tridoracpu.xpr +++ b/tridoracpu/tridoracpu.xpr @@ -111,7 +111,7 @@ - + @@ -142,7 +142,7 @@ - + @@ -173,14 +173,14 @@ - + - + @@ -205,6 +205,13 @@ + + + + + + +