Added adc->dac path test

This commit is contained in:
2026-03-04 23:35:02 +01:00
parent 3c13e3289a
commit 8cccea85e0
8 changed files with 204 additions and 12 deletions

View File

@@ -91,11 +91,10 @@ module mcu_peripherals (
);
wb_gpio_banks #(
.BASE_ADDR(GPIO_BASE_ADDR),
.NUM_BANKS(4)
.num_banks(4)
) gpio (
.i_wb_clk(i_clk),
.i_wb_rst(i_rst),
.i_clk(i_clk),
.i_rst(i_rst),
.i_wb_dat(gpio_wbs_dat_w),
.i_wb_adr(gpio_wbs_adr),
.i_wb_we(gpio_wbs_we),

View File

@@ -0,0 +1,54 @@
# Main clock input
NET "aclk" LOC = P126;
NET "aclk" TNM_NET = "SYS_CLK_PIN";
TIMESPEC TS_SYS_CLK_PIN = PERIOD "SYS_CLK_PIN" 10 ns HIGH 50 %;
# Boards button row
NET "aresetn" LOC = P120;
NET "aresetn" IOSTANDARD = LVCMOS33;
NET "aresetn" PULLUP;
NET "adc_a" LOC = P33;
NET "adc_a" IOSTANDARD = LVDS_33;
NET "adc_b" LOC = P32;
NET "adc_b" IOSTANDARD = LVDS_33;
NET "adc_o" LOC = P34;
NET "adc_o" IOSTANDARD = LVCMOS33;
NET "r2r[0]" LOC = P131;
NET "r2r[1]" LOC = P133;
NET "r2r[2]" LOC = P137;
NET "r2r[3]" LOC = P139;
NET "r2r[4]" LOC = P141;
NET "r2r[5]" LOC = P1;
NET "r2r[0]" IOSTANDARD = LVCMOS33;
NET "r2r[1]" IOSTANDARD = LVCMOS33;
NET "r2r[2]" IOSTANDARD = LVCMOS33;
NET "r2r[3]" IOSTANDARD = LVCMOS33;
NET "r2r[4]" IOSTANDARD = LVCMOS33;
NET "r2r[5]" IOSTANDARD = LVCMOS33;
NET "LED[0]" LOC = P119;
NET "LED[0]" IOSTANDARD = LVCMOS33;
NET "LED[0]" DRIVE = 8;
NET "LED[1]" LOC = P118;
NET "LED[1]" IOSTANDARD = LVCMOS33;
NET "LED[1]" DRIVE = 8;
NET "LED[2]" LOC = P117;
NET "LED[2]" IOSTANDARD = LVCMOS33;
NET "LED[2]" DRIVE = 8;
NET "LED[3]" LOC = P116;
NET "LED[3]" IOSTANDARD = LVCMOS33;
NET "LED[3]" DRIVE = 8;
NET "LED[4]" LOC = P115;
NET "LED[4]" IOSTANDARD = LVCMOS33;
NET "LED[4]" DRIVE = 8;
NET "LED[5]" LOC = P114;
NET "LED[5]" IOSTANDARD = LVCMOS33;
NET "LED[5]" DRIVE = 8;
NET "LED[6]" LOC = P112;
NET "LED[6]" IOSTANDARD = LVCMOS33;
NET "LED[6]" DRIVE = 8;
NET "LED[7]" LOC = P111;
NET "LED[7]" IOSTANDARD = LVCMOS33;
NET "LED[7]" DRIVE = 8;

View File

@@ -0,0 +1,46 @@
CAPI=2:
name: joppeb:system:mimas_sd_adc_r2r:1.0
description: Mimas top-level wiring sigma-delta ADC output directly to R2R DAC
filesets:
rtl:
depend:
- joppeb:primitive:clkgen
- joppeb:signal:sd_adc_q15
- joppeb:util:conv
files:
- rtl/toplevel.v
file_type: verilogSource
mimas:
files:
- mimas.ucf : {file_type : UCF}
- options.tcl : {file_type : tclSource}
targets:
default:
filesets:
- rtl
toplevel: toplevel
mimas:
filesets:
- rtl
- mimas
toplevel: toplevel
parameters:
- FPGA_SPARTAN6=true
default_tool: ise
tools:
ise:
family: Spartan6
device: xc6slx9
package: tqg144
speed: -2
parameters:
FPGA_SPARTAN6:
datatype: bool
description: Select Spartan-6 family specific implementations
paramtype: vlogdefine

View File

@@ -0,0 +1,2 @@
project set "Create Binary Configuration File" TRUE -process "Generate Programming File"
project set "Keep Hierarchy" Yes -process "Synthesize - XST"

View File

@@ -0,0 +1,91 @@
`timescale 1ns/1ps
module toplevel(
input wire aclk,
input wire aresetn,
input wire adc_a,
input wire adc_b,
output wire adc_o,
output wire [5:0] r2r,
output wire [7:0] LED
);
`include "conv.vh"
// Clocking
wire clk_100;
assign clk_100 = aclk;
wire clk_15;
clkgen #(
.CLK_IN_HZ(100000000),
.CLKFX_DIVIDE(20),
.CLKFX_MULTIPLY(3)
) clk_gen_15 (
.clk_in(clk_100),
.clk_out(clk_15)
);
// Asynchronous assert on reset button, synchronous release in clk_15 domain.
localparam [17:0] RESET_RELEASE_CYCLES = 18'd150000; // ~10 ms @ 15 MHz
reg [17:0] rst_cnt = 18'd0;
reg sys_reset_r = 1'b1;
always @(posedge clk_15 or negedge aresetn) begin
if (!aresetn) begin
rst_cnt <= 18'd0;
sys_reset_r <= 1'b1;
end else if (sys_reset_r) begin
if (rst_cnt == RESET_RELEASE_CYCLES - 1'b1)
sys_reset_r <= 1'b0;
else
rst_cnt <= rst_cnt + 1'b1;
end
end
wire signed [15:0] signal_q15;
wire signal_valid;
sd_adc_q15 #(
.R_OHM(3300),
.C_PF(220)
) sd_adc (
.i_clk_15(clk_15),
.i_rst_n(!sys_reset_r),
.i_adc_a(adc_a),
.i_adc_b(adc_b),
.o_adc(adc_o),
.o_signal_q15(signal_q15),
.o_signal_valid(signal_valid)
);
// signal_q15 is unipolar and biased (0-3.3V -> 0..32767)
reg signed [15:0] signal_unbiased_q15 = 16'sd0;
reg signal_unbiased_valid = 1'b0;
localparam bias = 2**14;
localparam gain = 2;
always @(posedge clk_15) begin
if (sys_reset_r) begin
signal_unbiased_q15 <= 16'sd0;
signal_unbiased_valid <= 1'b0;
end else begin
signal_unbiased_valid <= signal_valid;
if (signal_valid) begin
signal_unbiased_q15 <= (signal_q15 - $signed(bias)) * gain;
end
end
end
reg [5:0] dac_code = 6'd0;
always @(posedge clk_15) begin
if (sys_reset_r)
dac_code <= 6'd0;
else if (signal_unbiased_valid)
dac_code <= q15_to_uq16(signal_unbiased_q15) >> 10;
end
assign r2r = dac_code;
// Quick status indication: show ADC validity and most recent DAC code.
assign LED[0] = signal_valid;
assign LED[6:1] = dac_code;
assign LED[7] = sys_reset_r;
endmodule

View File

@@ -35,13 +35,13 @@ void main(){
irq_init();
*LEDGR = 1;
*TIMER_LD = 2 * 15000000/1000;
*TIMER_LD = 1000 * 15000;
for(;;){
for(int i=1000; i<10000; i+=10){
for(int i=500; i<6000; i+=10){
*R_FREQ = i;
*LEDS = i>>4;
// for(int j=0; j<80; j++) asm volatile("nop");
for(int j=0; j<800; j++) asm volatile("nop");
}
}
}