diff --git a/doc/irqctrl.md b/doc/irqctrl.md index bf76999..580c123 100644 --- a/doc/irqctrl.md +++ b/doc/irqctrl.md @@ -9,13 +9,12 @@ The interrupt controller uses a single register at address: $980 |_bit_ |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00| |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- | -|_Value_|t |t |t |t |t |t |t |t |- |- |- |- |- |p2 |p1 |p0 | +|_Value_|t |t |t |t |t |t |t |t |- |- |- |- |- |- |p1 |p0 | |Bitfields|Description| |---------|-----------| | _t_ | unsigned 24 bit counter of timer ticks since reset -| _p2_ | IRQ 2 (audio) interrupt pending if 1 | _p1_ | IRQ 1 (timer tick) interrupt pending if 1 | _p0_ | IRQ 0 (UART) interrupt pending if 1 diff --git a/doc/tdraudio.md b/doc/tdraudio.md deleted file mode 100644 index 999ebfc..0000000 --- a/doc/tdraudio.md +++ /dev/null @@ -1,104 +0,0 @@ -# Audio Controller -The audio controller provides four channels of 16-bit PCM audio playback. - -It uses multiple registers starting at address $A00. - -Each of the four channels has three registers. - -For the first channel the register addresses are: - -|Address|Description| -|-------|-----------| -| $A00 | Control Register | -| $A01 | Clock Divider Register | -| $A02 | Amplitude Register | - -The register addresses for the second channel start at $A04, -the third channel at $A08 -and the fourth channel at $A0C. - -## Reading the control register - -|_bit_ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16| -|- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- | -|_Value_|- |- |- |- |- |- |- |- |- |-|- |- |- |- |- |- | - -|_bit_ |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00| -|- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- | -|_Value_|- |- |- |- |- |- |- |- |- |- |- |i |f | e | p | c | - - -|Bitfields|Description| -|---------|-----------| -| _i_ | interrupt is enabled for this channel when 1 | -| _f_ | sample buffer is full when 1 | -| _e_ | sample buffer is empty when 1 | -| _p_ | changes from 0 to 1 and vice versa on each sample clock | -| _c_ | channel is enabled if 1 | - -## Writing the control register - -|_bit_ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16| -|- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- | -|_Value_|- |- |- |- |- |- |- |- |- |-|- |- |- |- |- |- | - -|_bit_ |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00| -|- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- | -|_Value_|- |- |- |- |- |- |- |- |- |- |- |i |- | - | - | c | - - -|Bitfields|Description| -|---------|-----------| -| _c_ | enable channel if 1, disable if 0 | -| _i_ | enable channel interrupt if 1, disable if 0 | - - -## Writing the clock divider register - -|_bit_ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16| -|- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- | -|_Value_|d |d |d |d |d |d |d |d |d |d|d |d |d |d |d |d | - -|_bit_ |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00| -|- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- | -|_Value_|d |d |d |d |d |d |d |d |d |d|d |d |d |d |d |d | - - -|Bitfields|Description| -|---------|-----------| -| _d_ | an unsigned 32-bit value for the clock divider | - - -## Writing the amplitude register - -|_bit_ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16| -|- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- | -|_Value_|- |- |- |- |- |- |- |- |- |-|- |- |- |- |- |- | - -|_bit_ |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00| -|- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- |- | -|_Value_|a |a |a |a |a |a |a |a |a |a |a |a |a | a | a | a | - - -|Bitfields|Description| -|---------|-----------| -| _a_ | an unsigned 16-bit value for the amplitude (sample) value with a bias of 32768 | - -## Notes -The clock divider specifies the number of CPU clock ticks between two samples. - -Writing to the amplitude register adds the sample value to the sample buffer. The sample buffer is organized as a FIFO with 16 elements. - -Amplitude (sample) values are represented as unsigned, biased 16-bit numbers. The bias is 32768, so given an amplitude range of 1.0 to -1.0, a 1.0 is represented by 65535, 0.0 by 32768 and -1.0 by 0. - -Interrupt processing needs to be enabled for each channel if required. - -An interrupt on any channel will be signalled to the interrupt controller -as IRQ 2. The interrupt service routine should check all running channels -for an emtpy buffer. - -If an audio interrupt has occured on a channel, the interrupt enable flag -is cleared for that channel. It needs to be re-enabled in the interrupt service routine. - -Interrupts also need to be enabled on the interrupt controller, -and re-enabled there after each interrupt. diff --git a/examples/benchmarks.results.text b/examples/benchmarks.results.text index c05b034..19824ee 100644 --- a/examples/benchmarks.results.text +++ b/examples/benchmarks.results.text @@ -97,7 +97,7 @@ Running benchmarks.prog Arty-A7-35T 76.92MHz, 64KB SRAM, 256MB DRAM, 16B instruction cache, 16B wt data cache -running in SRAM +running in DRAM (except corelib, stdlib, runtime) Running benchmarks.prog empty loop 10M 00:00:07 @@ -124,7 +124,7 @@ Running benchmarks.prog Arty-A7-35T 76.92MHz, 64KB SRAM, 256MB DRAM, 16B instruction cache, 16B wb data cache -running in SRAM +running in DRAM (except corelib, stdlib, runtime) Running benchmarks.prog empty loop 10M 00:00:04 @@ -149,7 +149,7 @@ Running benchmarks.prog Arty-A7-35T 76.92MHz, 32KB SRAM, 256MB DRAM, 16B instruction cache, 16B wb data cache -running in SRAM +running in DRAM (except corelib, stdlib, runtime) Running benchmarks.prog empty loop 10M 00:00:04 @@ -169,28 +169,3 @@ Running benchmarks.prog array copy 128k 1K 00:00:39 exp() 10K 00:00:25 cos() 10K 00:00:05 - --------------------------------------------- -Arty-A7-35T -76.92MHz, 64KB SRAM, 256MB DRAM, - 16B instruction cache, 16B wb data cache -running in DRAM (except corelib, stdlib, runtime) - -Running benchmarks.prog - empty loop 10M 00:00:10 - write variable 10M 00:00:11 - read variable 10M 00:00:11 - integer addition 10M 00:00:13 - real addition 1M 00:00:27 - integer multiplication 1M 00:00:35 - real multiplication 1M 00:00:43 - integer division 1M 00:01:05 - real division 1M 00:00:51 - string indexing 1M 00:00:36 - string iteration 1M 00:00:20 - new/dispose 1k 1M 00:00:23 - new/dispose 128k 1M 00:00:23 - array copy 1k 10K 00:00:03 - array copy 128k 1K 00:00:48 - exp() 10K 00:00:28 - cos() 10K 00:00:04 diff --git a/examples/pcmtest.pas b/examples/pcmtest.pas deleted file mode 100644 index 423faaf..0000000 --- a/examples/pcmtest.pas +++ /dev/null @@ -1,47 +0,0 @@ -{$H1536} -program pcmtest; -uses pcmaudio; - -var filename:string; - buf:SndBufPtr; - f:file; - size:integer; - i:integer; - c:char; - sampleRate:integer; - err:integer; -begin - if ParamCount > 0 then - filename := ParamStr(1) - else - begin - write('Filename> '); - readln(filename); - end; - - err := 1; - if ParamCount > 1 then - val(ParamStr(2),sampleRate, err); - - if err <> 0 then - sampleRate := 16000; - - open(f, filename, ModeReadOnly); - size := FileSize(f); - new(buf, size); - - buf^ := ''; - write('Reading ', size, ' bytes...'); - for i := 1 to size do - begin - read(f,c); - AppendChar(buf^,c); - end; - writeln; - - close(f); - - PlaySample(buf, sampleRate); - - dispose(buf); -end. diff --git a/examples/pcmtest2.pas b/examples/pcmtest2.pas deleted file mode 100644 index f72e5e6..0000000 --- a/examples/pcmtest2.pas +++ /dev/null @@ -1,74 +0,0 @@ -{$H2560} -program pcmtest2; -uses pcmaudio; - -var filename:string; - buf:SndBufPtr; - sampleRate:integer; - err:integer; - done:boolean; - c:char; - -function readAudioFile(fname:string):SndBufPtr; -var i,size:integer; - c:char; - buf:SndBufPtr; - f:file; -begin - open(f, fname, ModeReadOnly); - size := FileSize(f); - new(buf, size); - - buf^ := ''; - write('Reading ', size, ' bytes...'); - for i := 1 to size do - begin - read(f,c); - AppendChar(buf^,c); - end; - writeln; - - close(f); - - readAudioFile := buf; -end; - -begin - if ParamCount > 0 then - filename := ParamStr(1) - else - begin - write('Filename> '); - readln(filename); - end; - - err := 1; - if ParamCount > 1 then - val(ParamStr(2), sampleRate, err); - if err > 0 then - sampleRate := 32000; - - buf := readAudioFile(filename); - - SampleQStart(buf, sampleRate); - - write('Press ESC to stop> '); - done := false; - while not done do - begin - read(c); - if c = #27 then - begin - done := true; writeln(';'); - end - else - if c = '?' then - begin - writeln; writeln('Queue: ', SampleQSize); - end; - end; - - SampleQStop; - - dispose(buf); -end. diff --git a/lib/pcmaudio.inc b/lib/pcmaudio.inc deleted file mode 100644 index 4c3cdb3..0000000 --- a/lib/pcmaudio.inc +++ /dev/null @@ -1,7 +0,0 @@ -type SndBuf = string[32768]; -type SndBufPtr = ^SndBuf; - -procedure PlaySample(buf:SndBufPtr;sampleRate:integer); external; -procedure SampleQStart(buf:SndBufPtr;sampleRate:integer); external; -procedure SampleQStop; external; -function SampleQSize:integer; external; diff --git a/lib/pcmaudio.s b/lib/pcmaudio.s deleted file mode 100644 index d1add4f..0000000 --- a/lib/pcmaudio.s +++ /dev/null @@ -1,247 +0,0 @@ - .EQU AUDIO_BASE $A00 - .EQU IRQC_REG $980 - .EQU IRQC_EN $80 - -; args: sample rate -START_PCMAUDIO: - ; calculate clock divider - LOADCP 77000000 - SWAP - LOADCP _DIV - CALL - - LOADC AUDIO_BASE + 1 - SWAP ; put clock divider on ToS -; LOADCP 4812 ; clock divider for 16KHz sample rate -; LOADCP 2406 ; clock divider for 32KHz sample rate - STOREI 1 - LOADCP 32768 ; set amplitude to biased 0 - STOREI - DROP - LOADC AUDIO_BASE - LOADC 17 ; enable channel, enable interrupt - STOREI - DROP - RET - -STOP_AUDIO: - LOADC AUDIO_BASE - LOADC 0 - STOREI - DROP - RET - -; args: pointer to pascal string, sample rate - .EQU PS_PTR 0 - .EQU PS_COUNT 4 - .EQU PS_FS 12 -PLAYSAMPLE: - FPADJ -PS_FS - - LOADCP START_PCMAUDIO - CALL - - DUP - LOADI ; get string size from header - SHR ; divide by 4 to get word count - SHR - - STORE PS_COUNT - INC 8 ; skip rest of header - STORE PS_PTR ; store sample data pointer - -PS_L0: - LOAD PS_PTR ; load pointer - INC.S1.X2Y 4 ; increment and keep old value - STORE PS_PTR ; store incremented value - - LOADI ; load 32 bit word - DUP - BROT ; get upper 16 bit word - BROT - LOADCP $FFFF - AND - - LOADCP PLAY_1SAMPLE - CALL - - LOADCP $FFFF ; get lower 16 bit word - AND - LOADCP PLAY_1SAMPLE - CALL - - LOAD PS_COUNT ; load word count - DEC 1 ; decrement - DUP - STORE PS_COUNT - CBRANCH.NZ PS_L0 ; loop if not zero - - LOADCP STOP_AUDIO - CALL - - FPADJ PS_FS - RET - -; play one sample, waiting -; for the clock divider, which -; is visible via the phase flag -; args: 16-bit unsigned sample -PLAY_1SAMPLE: - -PLAY1_L0: - LOADC AUDIO_BASE - LOADI - LOADC 8 ; get fifo_full flag - AND - CBRANCH.NZ PLAY1_L0 ; loop if fifo is full - - LOADC AUDIO_BASE+2 ; store amplitude value - SWAP - STOREI - DROP - RET - -; start interrupt-driven sample playback -; args: pointer to pascal string, sample rate -SAMPLEQSTART: - LOADCP START_PCMAUDIO - CALL - - LOADCP SMPLQ_COUNT - OVER - LOADI ; get string size from header - SHR ; divide by 4 to get word count - SHR - - STOREI - DROP - - LOADCP SMPLQ_PTR - SWAP - INC 8 ; skip rest of header - STOREI ; store sample data pointer - DROP - - LOADCP SMPLQ_ISR ; set interrupt handler - STOREREG IV - - LOADC IRQC_REG ; enable irq - LOADC IRQC_EN - STOREI - DROP - - RET - -SAMPLEQSTOP: - LOADCP SMPLQ_PTR - LOADC 0 - STOREI - DROP - - LOADCP STOP_AUDIO - CALL - - LOADC IRQC_REG ; disable irq - LOADC 0 - STOREI - DROP - RET - -SAMPLEQSIZE: - LOADCP SMPLQ_COUNT - LOADI - RET - -SMPLQ_PTR: .WORD 0 -SMPLQ_COUNT: .WORD 0 - -SMPLQ_ISR: - LOADC IRQC_REG - LOADI - LOADC 4 ; check for audio interrupt - AND - CBRANCH.Z SMPLQ_I_XT ; if flag not set, exit - -SMPLQ_I_L: - LOADCP SMPLQ_PTR - LOADI ; load word pointer - DUP - CBRANCH.NZ SMPLQ_I_B ; check for null pointer - DROP - BRANCH SMPLQ_I_XT ; if null, end interrupt routine -SMPLQ_I_B: - LOADI ; load next word - DUP - - BROT ; get high half-word - BROT - LOADCP $FFFF - AND - - LOADC AUDIO_BASE+2 - SWAP - STOREI ; write sample, keep addr - - SWAP ; addr to NoS, lower halfword on ToS - LOADCP $FFFF - AND - STOREI ; write sample - DROP - - ; decrement word count - LOADCP SMPLQ_COUNT - LOADI.S1.X2Y ; load counter, keep addr - DEC 1 - DUP - CBRANCH.Z SMPLQ_I_END ; end if zero - - STOREI ; store new counter value - DROP - - ; increment pointer - LOADCP SMPLQ_PTR - LOADI.S1.X2Y - INC 4 - STOREI - DROP - - ; check if fifo is full - LOADC AUDIO_BASE - LOADI - LOADC 8 ; fifo_full - AND - CBRANCH.Z SMPLQ_I_L ; next sample if not full - - LOADC AUDIO_BASE - LOADC 17 ; re-enable channel interrupt - STOREI - DROP - - BRANCH SMPLQ_I_XT - - ; end playback, set ptr and counter to zero -SMPLQ_I_END: - DROP - DROP - LOADCP SMPLQ_PTR - LOADC 0 - STOREI - DROP - LOADCP SMPLQ_COUNT - LOADC 0 - STOREI - DROP - - ; set amplitude out to zero (biased) - LOADC AUDIO_BASE+2 - LOADCP 32768 - STOREI - DROP - -SMPLQ_I_XT: - LOADC IRQC_REG ; re-enable interrupts - LOADC IRQC_EN - STOREI - DROP - LOADREG IR ; jump via interrupt return register - JUMP diff --git a/lib/runtime.s b/lib/runtime.s index 9eb35d7..ce60b8d 100644 --- a/lib/runtime.s +++ b/lib/runtime.s @@ -1931,12 +1931,6 @@ _CLEARESTACK_XT: ; Terminate program: clear estack and ; jump to coreloader PTERM: - ; just to be safe, disable interrupts - LOADC $980 - LOADC 0 - STOREI - DROP - LOADCP _CLEARESTACK CALL LOADCP LOADER_START diff --git a/lib/stdlib.pas b/lib/stdlib.pas index 84025b3..dd6294c 100644 --- a/lib/stdlib.pas +++ b/lib/stdlib.pas @@ -1844,8 +1844,6 @@ end; function filesize(var fil:file):integer; begin - checkerror(fil); - if fil.typ = IOChannel then filesize := -1 else diff --git a/tridoracpu/tridoracpu.srcs/Arty-A7-35-Master.xdc b/tridoracpu/tridoracpu.srcs/Arty-A7-35-Master.xdc index 2a33ae0..7c62767 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 { 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 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 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 { amp2_shutdown_n }]; #IO_L13N_T2_MRCC_35 Sch=jd[4] +#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 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/dram_bridge.v b/tridoracpu/tridoracpu.srcs/dram_bridge.v index 9bd2a92..d4f798b 100644 --- a/tridoracpu/tridoracpu.srcs/dram_bridge.v +++ b/tridoracpu/tridoracpu.srcs/dram_bridge.v @@ -165,7 +165,7 @@ module dram_bridge #(ADDR_WIDTH = 32, WIDTH = 32) assign app_wdf_data = { {4{mem_write_data}} }; assign mem_wait = (dram_read_enable & ~read_inprogress) | - (mem_write_enable & (~app_wdf_rdy | ~app_rdy)) | + (mem_write_enable & ~dcache_hit & (~app_wdf_rdy | ~app_rdy)) | (read_inprogress & ~app_rd_data_valid); assign app_en = (dram_read_enable & ~read_inprogress) | diff --git a/tridoracpu/tridoracpu.srcs/irqctrl.v b/tridoracpu/tridoracpu.srcs/irqctrl.v index b71df60..1a079bf 100644 --- a/tridoracpu/tridoracpu.srcs/irqctrl.v +++ b/tridoracpu/tridoracpu.srcs/irqctrl.v @@ -1,6 +1,6 @@ `timescale 1ns / 1ps -module irqctrl #(IRQ_LINES = 3, IRQ_DELAY_WIDTH = 4) ( +module irqctrl #(IRQ_LINES = 2, IRQ_DELAY_WIDTH = 4) ( input wire clk, input wire [IRQ_LINES-1:0] irq_in, input wire cs, diff --git a/tridoracpu/tridoracpu.srcs/tdraudio.v b/tridoracpu/tridoracpu.srcs/tdraudio.v deleted file mode 100644 index 0cc055e..0000000 --- a/tridoracpu/tridoracpu.srcs/tdraudio.v +++ /dev/null @@ -1,262 +0,0 @@ -`timescale 1ns / 1ps - -// waveform generator module (PCM) -module wavegen #(DATA_WIDTH=32, CLOCK_DIV_WIDTH=22, - AMP_WIDTH=16, AMP_BIAS=32768) ( - input wire clk, - input wire reset, - input wire [1: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 [AMP_WIDTH-1:0] amp_val, - output wire running, - output wire irq - ); - - localparam TDRAU_REG_CTL = 0; /* control register */ - localparam TDRAU_REG_CLK = 1; /* clock divider register */ - localparam TDRAU_REG_AMP = 2; /* amplitude (volume) register */ - - reg channel_enable; - reg [CLOCK_DIV_WIDTH-1:0] clock_div; - reg [CLOCK_DIV_WIDTH-1:0] div_count; - reg amp_phase; - reg [AMP_WIDTH-1:0] amp_out; - - - wire fifo_wr_en; - wire fifo_rd_en, fifo_full, fifo_empty; - wire [DATA_WIDTH-1:0] fifo_rd_data; - - fifo #(.ADDR_WIDTH(4), .DATA_WIDTH(16)) sample_buf( - clk, reset, - fifo_wr_en, fifo_rd_en, - wr_data, fifo_rd_data, - fifo_full, - fifo_empty - ); - - assign fifo_rd_en = (div_count == 0) && channel_enable && ~fifo_empty; - assign fifo_wr_en = wr_en && (reg_sel == TDRAU_REG_AMP); - - reg irq_buf, irq_enable; - assign irq = channel_enable && irq_buf; - - reg [DATA_WIDTH-1:0] rd_data_buf; - assign rd_data = rd_data_buf; - - assign amp_val = amp_out; - assign running = channel_enable; - - wire ctl_reg_write = wr_en && (reg_sel == TDRAU_REG_CTL); - - /* update read data buffer */ - always @(posedge clk) - begin - rd_data_buf <= {{DATA_WIDTH-8{1'b0}}, - {3{1'b0}}, irq_enable, fifo_full, fifo_empty, amp_phase, channel_enable}; - end - - /* irq signal to interrupt controller */ - always @(posedge clk) - begin - if(reset) - irq_buf <= 0; - else - if(fifo_empty && irq_enable) - irq_buf <= 1; - else - irq_buf <= 0; - end - - /* interrupt enable flag */ - always @(posedge clk) - begin - if(reset) - irq_enable <= 0; - else - if(ctl_reg_write) - irq_enable <= wr_data[4]; - else - if(irq_buf) - irq_enable <= 0; // disable interrupts after an interrupt - end - - /* channel enable flag */ - always @(posedge clk) - begin - if(reset) - channel_enable <= 0; - else if (ctl_reg_write) - 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)) // when setting divider, - div_count <= 1; // start cycle on next clock tick - end - - /* amplitude out */ - always @(posedge clk) - begin - if (reset) - begin - amp_out <= AMP_BIAS; - amp_phase <= 1; - end - else - if (channel_enable) - begin - if (div_count == 0) // invert amplitude on clock tick - begin - amp_out <= fifo_rd_data; - amp_phase <= ~amp_phase; - end - end - else - amp_out <= AMP_BIAS; - - // reset phase bit when enabling the channel - if (ctl_reg_write && wr_data[0] && ~channel_enable) - // when channel is being enabled, phase will be flipped on next tick - // because div_count will become zero - amp_phase <= 1; - end -endmodule - -module tdraudio #(DATA_WIDTH=32) ( - input wire clk, - input wire reset, - input wire [6:0] io_addr, - 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 irq_out, - output wire pdm_out, - output wire gain_sel, - output wire shutdown_n - ); - - localparam CLOCK_DIV_WIDTH = 22; - localparam AMP_WIDTH = 16; - localparam AMP_BIAS = 32768; - localparam DAC_WIDTH = 18; - - wire [4:0] chan_sel = io_addr[6:2]; - wire [1:0] reg_sel = io_addr[1:0]; - - wire [AMP_WIDTH-1:0] chan0_amp; - wire [DATA_WIDTH-1:0] chan0_rd_data; - wire chan0_running; - wire chan0_irq; - wire chan0_sel = chan_sel == 5'd0; - wire chan0_rd_en = chan0_sel && rd_en; - wire chan0_wr_en = chan0_sel && wr_en; - - wire [AMP_WIDTH-1:0] chan1_amp; - wire [DATA_WIDTH-1:0] chan1_rd_data; - wire chan1_running; - wire chan1_irq; - wire chan1_sel = chan_sel == 5'd1; - wire chan1_rd_en = chan1_sel && rd_en; - wire chan1_wr_en = chan1_sel && wr_en; - - wire [AMP_WIDTH-1:0] chan2_amp; - wire [DATA_WIDTH-1:0] chan2_rd_data; - wire chan2_running; - wire chan2_irq; - wire chan2_sel = chan_sel == 5'd2; - wire chan2_rd_en = chan2_sel && rd_en; - wire chan2_wr_en = chan2_sel && wr_en; - - wire [AMP_WIDTH-1:0] chan3_amp; - wire [DATA_WIDTH-1:0] chan3_rd_data; - wire chan3_running; - wire chan3_irq; - wire chan3_sel = chan_sel == 5'd3; - wire chan3_rd_en = chan3_sel && rd_en; - wire chan3_wr_en = chan3_sel && wr_en; - - wire running = chan0_running || chan1_running || chan2_running || chan3_running; - - assign rd_data = chan0_sel ? chan0_rd_data : - chan1_sel ? chan1_rd_data : - chan2_sel ? chan2_rd_data : - chan3_sel ? chan3_rd_data : - {DATA_WIDTH{1'b1}}; - - wavegen chan0(clk, reset, reg_sel, - chan0_rd_data, wr_data, - chan0_rd_en, chan0_wr_en, - chan0_amp, - chan0_running, chan0_irq); - - wavegen chan1(clk, reset, reg_sel, - chan1_rd_data, wr_data, - chan1_rd_en, chan1_wr_en, - chan1_amp, - chan1_running, chan1_irq); - - wavegen chan2(clk, reset, reg_sel, - chan2_rd_data, wr_data, - chan2_rd_en, chan2_wr_en, - chan2_amp, - chan2_irq, chan2_running); - - wavegen chan3(clk, reset, reg_sel, - chan3_rd_data, wr_data, - chan3_rd_en, chan3_wr_en, - chan3_amp, - chan3_running, chan3_irq); - - reg [DAC_WIDTH:0] deltasigma_acc; // one extra bit - wire [DAC_WIDTH:0] amp_sum = chan0_amp + chan1_amp + chan2_amp + chan3_amp; // also one overflow bit here - assign gain_sel = 1; // gain select: 0 -> 12dB, 1 -> 6dB - - // assign shutdown_n = running; - assign shutdown_n = 1; /* don't enable shutdown mode, it creates a mains hum */ - - reg irq_out_buf; - assign irq_out = irq_out_buf; - - always @(posedge clk) irq_out_buf <= chan0_irq || chan1_irq || chan2_irq || chan3_irq; - - /* delta-sigma DAC */ - always @(posedge clk) - begin - if(reset) - deltasigma_acc <= 0; - else -// if (running) - deltasigma_acc <= deltasigma_acc[DAC_WIDTH-1:0] + amp_sum; -// else -// deltasigma_acc <= deltasigma_acc[DAC_WIDTH-1:0] + (4*AMP_BIAS); - end - - /* 1-bit audio output */ - assign pdm_out = deltasigma_acc[DAC_WIDTH]; -endmodule diff --git a/tridoracpu/tridoracpu.srcs/top.v b/tridoracpu/tridoracpu.srcs/top.v index 6a70ef0..00066fe 100644 --- a/tridoracpu/tridoracpu.srcs/top.v +++ b/tridoracpu/tridoracpu.srcs/top.v @@ -10,7 +10,6 @@ //`define clock clk_1hz `define ENABLE_VGAFB `define ENABLE_MICROSD -`define ENABLE_TDRAUDIO module top( input wire clk, @@ -61,13 +60,6 @@ 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; @@ -228,35 +220,11 @@ 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 }; - wire audio_irq; -`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_irq; - - 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[6:0], - tdraudio_rd_data, - tdraudio_wr_data, - tdraudio_rd_en, - tdraudio_wr_en, - tdraudio_irq, - amp2_ain, amp2_gain, amp2_shutdown_n); - assign audio_irq = tdraudio_irq; -`endif - - // interrupt controller reg timer_tick; reg[23:0] tick_count; - wire [2:0] irq_in = { audio_irq, timer_tick, uart_rx_avail }; - wire [2:0] irqc_rd_data0; - wire [WIDTH-1:0] irqc_rd_data = { tick_count, 5'b0, irqc_rd_data0 }; + wire [1:0] irq_in = { timer_tick, uart_rx_avail }; + wire [1:0] irqc_rd_data0; + wire [WIDTH-1:0] irqc_rd_data = { tick_count, 6'b0, irqc_rd_data0 }; wire irqc_seten = mem_write_data[7]; wire irqc_cs = io_enable && (io_slot == 3); @@ -268,9 +236,7 @@ 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 3767063..36b5512 100644 --- a/tridoracpu/tridoracpu.xpr +++ b/tridoracpu/tridoracpu.xpr @@ -111,7 +111,7 @@ - + @@ -142,7 +142,7 @@ - + @@ -173,14 +173,14 @@ - + - + @@ -205,13 +205,6 @@ - - - - - - -