Een update : printjes zijn onderweg van china (jlcpcb)

Frontpaneel is een dubbelzijdige print met zwart masker en witte opdruk. Kost haast niks en is de moeite niet om zelf te gaan vijlen in aluminium of plastic en dan zelf te gaan prutsen om dat te beletteren. Kostte 11$ voor 5 printen...
Het koper is intact voor en achter. Langs achter zijn er openingen in het soldeermasker om er afstandsbussen op te solderen. Wurth 9775066360R. Dit zijn afstandsbusjes voor SMD montage. Ze zijn gemaakt om te solderen. Zo heb je geen gaatjes nodig die het frontpaneel ontsieren. M3 schroefdraad.

https://github.com/vincent-himpe/CurveTraceNew/blob/main/finalfront.pn…
https://github.com/vincent-himpe/CurveTraceNew/blob/main/finalfront-ba…

Het voorpaneel zelf is een 4 lagen print. Kost ook haast niks meer tegenwoordig...

https://github.com/vincent-himpe/CurveTraceNew/blob/main/finalfrontboa…

Drukknopjes zijn E-switch TL1105 met bijhorende kapjes (1RLGY) die er op klikken. De leds zijn Sunled. met een 2mm flatt-top. Alles is courant te krijgen bij digikey/mouser en waarschijnlijk ook op TME.
Encoder is Bourns PC12 familie. de aslengte weet ik niet precies. hangt van de knop af , maar ze zijn beschikbaar in 15 17 20 22 25 en 30 lengte.. ik denk 22 of 25 moet het doen.

Let niet op die pinheader links van het display. die bestaat niet. is alleen om de mechanische uitlijning te doen. In werkelijkheid soldeer je daar afgeknipe weerstand poten in :)
Het display hangt achter het bord om de juiste afstand te krijgen voor de leds en drukknoppen
Deze print schroeft in het voorpaneel

https://github.com/vincent-himpe/CurveTraceNew/blob/main/finalfrontboa…
https://github.com/vincent-himpe/CurveTraceNew/blob/main/finalfrontboa…

Er zijn alleen weerstanden voor de leds, wat pullups en de I2C i/o expanders. (NXP of TI PCAL9555)
Deze expanders hebben interrupt mogelijkheid en heel wat programmeermogelijkheden. het zijn upgrades van de PCA9555. Een specialiteit is de programmeerbare state-latch. Als ene pin van toestand verandert krijg je een interrupt en de toestand wordt opgeslagen. Als je dus op een knopje drukt en weer loslaat is die wijziging opgeslagen. Je krijgt alleen een interrupt bij het indrukken, niet bij loslaten maar de toets-aanslag is opgeslagen.

Het idee is om de keyboard scan toe doen tijdens de sweep retract. Aangezien een nieuwe sweep start om de 4milliseconde kan ik gewoonweg de i2c bus lezen na de start. ( als er ene interrupt is van het keyboard).

Ik had origineel slechts 3 expanders. 1 voor leds, 1 voor toetsen en 1 50/50 ( er zijn 16 kanalen in 2 banken op die dingen) . Maar om de softwar eeenvoudiger te maken heb ik de middenste afgesplitst. Het is overkill en er zijn 9 kanalen niet in gebruik , maar het maakt de software ene flink stuk makkelijker.

De software architectuur heeft de leds en de toetsen beide als een 32 bit value opgeslagen. De transport routing hoeft dus enkel blokken van 16 bit per expander te schuiven. We gaan niet voor elke prul read/modify/writes gaan doen. Das veel te veel dataverkeer. De software zet of leest de bits van de twee variabelen, en de interrupt handler schuift alles in 1 keer door ,om de 4 milliseconden.

Die expanders kosten 1.2$ ... ik ga niet in software gaan prutsen en daar complexe routines voor gaan schrijven.

LCD display is in 4 bit mode. Dit is een Display van Eastrising : BuyDisplay.com. Eastrising is een van de grootste lcd module fabrikanten ter wereld. Het enig probleem is dat je ze alleen bij hen kan bestellen ( buydisplay.com) maar ze zijn spotgoedkoop. 7$ tegen 20$ bij digikey. En ze hebben allerhande kleuren (als je per-se een blauwe wilt... yuckkk ) Het speciale is de backlight module. Die zit verzonken en de displays zijn een flink pak dunner dan normale.

Je kan ze ook vinden op amazon en ebay.

De processor wordt een AVR64DA64 ( je kan ook de 64DB64 gebruiken. zelfde ding maar heeft hardware multiplier)

De processor keuze heeft heel wat voeten in de aarde gehad.
- makkelijk te krijgen
- makkelijk te solderen (geen QFN of BGA)
- goedkoop
- 5 volt voeding (5volt tolerantie alleen is niet genoeg, geen gepruts met level shifters)
- flink wat ram en rom (64kflash en 2k ram) meer dan genoeg.
- eenvoudig te begrijpen preripherals. ( zommige van die cortex dingen zijn een drama om uit te vlooien)

En de twee belangrijkste :
1) geen gepruts met programmeerkabels en dongles en avrdude and andere rotzooi . Ik haat dat gedoe met drivers die niet werken en klooierij met dingen zoals "Zadig". Ik heb een lade vol jtag probes, segger, u-links, j-links, avrisps, Stlinks and andere rommel in wel 10 versies die net meer werkt omdat ze te oud zijn, de fabrikant verdwenen is of de software niet werkt op platform xyz of de ieuwe versie van de software de oudere hardware niet ondersteunt.

De AVR64 programmeert en debug't via UPDI. Dit is een domme USB<>uart. Je kan een FTDI of CP2102 of CH340 er aan hangen en het werkt.

Ik zet gewoonweg een ch340 en een usb connector op het moederbord. USB kabel er in en vort met de geit. Er zit een switch die UPDI loskoppelt en omleidt naar een uart.

2) de beschikbaarheid van een BASIC compiler. Geen gepruts met 'C' of 'Python'
- Bascom-AVR
- Great-Cow Basic
Great-cow is gratis. Bascom is betalend. Ik heb de licentie voor Bascom . Werkt lekker en de simulator heeft LCD display simulatie.

Er waren nog een pak andere factoren zoals de nood aan een spannings referentie voor de a/d. Ze zijn slim geweest bij deze processor en hebben een 2.048 volt referentie aan boord. Dit maakt dat je geen floating point nodig hebt ! Geen gedoe met kromme waarden zoals bij een 1.2 volt of 2.5 volt referentie spanning.

Aangezien de analoge hardware met spanningen tussen 0 en 2 volt werkt (zowel voor aansturen als meten) landt dit netjes in het 2.048 volt bereik. Als ik de 12 bit omzetter uitlees en daar een shift-right van 1 bit op uitvoer heb ik direct de gemeten waarde in volt. als ik 2000 lees is dat 2 volt. geen berekeningen van doen !
Schaal dat omhoog met 8 bit (x256) en stop dat in een 32 bit variabele en je kan alles doen met integer math. eenmaal klaar : deel door 256 en je hebt je waardes.

Ik heb een testbord gemaakt voor de AVR64.
https://github.com/vincent-himpe/AVR64DA64-Breakout/blob/main/breakout…

Geinspireerd op de mikroe borden. Elke I/O pin heeft ene led/drukknop en pinheader. die in en uitschakelbaar zijn. er zijn 3 pinheader pinnetjes + 1 grond per i/o poort. zo kan je 2 draadjes op een poort zetten en heb je nog eentje over voor je scoop of logic analyser + een grond voor je probe

dit bord is universeel maar ik heb er twee extra connectors op gezet : 1 voor een los LCD display en de connector met de pinout voor het forntpaneel van de curvetracer. zo kan ik direct aan de slag.
Er staat ook een i2c digitale potmeter en een dac op alsook een FRAM (eeprom zonder schrijf cyclus. ferro-electric ram. RAM maar nonvolatile)

De updi programmer en updi/uart schakelaar is ook aan boord. plug en play.CH340B gebaseerd. Ik heb specifiek de B versie gekozen omdat die een eeprom aan boord heeft waar je een serienummer kan inzetten. Geen gevloek om uit te vlooien op welke compoort het ding nu weer zit ... Windows registreert het serienummer en koppelt daar de bijhorende poort aan. USB devices die geen serienummer dragen zijn first-come first serve. ALs je dus twee van die dingen aankoppelt weet je noiit wie op welke poort landt. Bij devices met een serienummer blijft de "poort" bij het nummer. je mag ze dus in en uit trekken : de poort is altijd de zelfde.

Volgende week zou ik de printjes moeten hebben. Ik heb het development bord laten bestuken door JLCPCB (alleen de SMD componenten) 72 ledjes, 72 drukknopjes ... en de bijhorende weerstandjes ... laat ze er maar op schieten. T'was iets van 140$ bestukt voor 5 borden. das 28$ per bord. Ik ga er mijn tijd niet aan hangen.

Zoho ... iemand is druk geweest ...

Ik heb in het verleden wel wat geprutst met bascom ... de free versie was historisch een tikje buggy, en de editor is ... tja, niet heel ver verwijderd van notepad. Het ding doet amper wat voor je.
Great-Cow ken ik niet, dat is wellicht nog eens een blik waard.

In wat voor een behuizing wil je het geheel gaan lepelen?

how. die stond private.. open gezet.
De documentatie van dat bord volgt.

Great-cow gebruikt gewoon een C-compiler als backend.

De behuizing is ene standaard Hammond RM2095M kastje
Ze zijn goedkoop , makkelijk te krijgen en handig. Desktop model. Denk "bench multimeter"

Heel vele wikken en wegen in dit project. Ik probeer iets te maken wat makkelijk na te bouwen is en geen exotische onderdelen gebruikt. Met exoten bedoel ik BGA en QFN en 042 componenten : dingen die niet makkelijk te verwerken zijn.

0603 werkt lekker met ee moderne soldeerbout ditto voor TQFP.
Dingen laten maken in china ( printen en bestukking) vie JLCPCB of PCBWAY is tegenwoordig zo goedkoop. Laat al die passieven er daar op schieten en zet er zelf de ic's op.

Ze hanteren een system van "basic" componenten. Als je die gebruikt rekenen ze geen kosten aan. Hun machienes staan geladen met die onderdelen. De meest 1% weerstanden, een pak condensatoren , diodes etc.

Bij het maken van dat AV bord heb ik daar mee rekening gehouden. Voor elk component dat niet in dat "basic" gamma zit rekeken ze 3 dollar handarbeid aan om een operator de rol te laten halen en op de machine te zetten. De leds, drukknopjes en weerstanden zijn haast allemaal "basic". De thru-hole rekeken ze ook handenarbeid aan. Ondanks dit bord gemaakt is voor wave soldering ( er staan geen SMd op de achterkant) doen ze dat toch met de hand. Dus dat heb ik ze laten overslaan. hun connectors zijn wel spotgoedkoop dus als je geen pinheaders in huis hebt loont het wel om ze daar te latne plaatsen. Maar ik heb toevallig een ganse emmer van die pinheaders staan ( een zak os 10 van elk 250 stuks ...) Die zet ik wel zelf.

De productie BOM van dat bord heeft de juiste JLCPCB codes aan boord en je kan dat zo inlezen daar. De processor moet je omzetten naar een 64DB64 omdat ze de DA niet in voorraad hebben. Hij kost een paar dollar meer. Het enige verchil is die multiply unit maar die gebruik ik toch niet.

Dingen zoals de DAC, potmeter , encoders etc zitten niet in de BOM. Die zitten niet in hun BASIC pakket en je hebt die niet altijd nodig. Ik heb ze op het bord gezet om te kunnen experimenteren met bepaalde zaken vooraleer ik de hoofdprint laat maken.

Die PWM generator maakt een 4mS puls met een 99.5% duty cycle. De bedoeling is de "sweep" te emuleren. Door dat signaal aan de interrupt te hangen kan ik de scoop nabootsen. de potmeter staat me toe de duty cycle te veranderen. Als ik zie dat de interrupt afwerking te lang duurt kan ik spelen met de duty cycle van de sweep. ( door de terugslag langer te maken krijgt de interrupt handler meer tijd om alles klaar te zetten voor de volgende sweep.)

[Bericht gewijzigd door free_electron op (89%)]

kleine update ..

Achterkant frontpaneel:

https://github.com/vincent-himpe/CurveTraceNew/blob/main/images/front_back.png?raw=true

voorkant frontpaneel :

https://github.com/vincent-himpe/CurveTraceNew/blob/main/images/front_front.png?raw=true

Nice! Dat zijn zo te zien zelfs foto's en geen renders.

jup. fotos van voorpaneel
ik moet er nog de SMD onderdelen op zetten. Maar het mechanische werk past alvast in het kastje.

Een update. Verlof achter de rug (2 weken digitale detox).

Na wat ge-experimenteer in software blijkt dat er te veel jitter zit op verschillende dingen en er veel te veel gepruts nodig is in de interrupt afhandeling. Een deel van het probleem is de analoge sweepgenerator met comparatoren. Dat spul drift....

De ganse logica heeft veel kunst en vliegwerk nodig in de software om alles op tijd te kunnen afhaspelen.

Tijd om de sweepgenerator digitaal te maken.

Eerste idee : een vrijlopende teller (8 bit) die een dac (voor x) aanstuurt. dit maakt een mooie zaagtand. Hang daar een paar 74688 8 bit comparatorne achter en je hebt triggers voor de cursors. De waardes worden opgeslagen in 74574 registers.
Werkt mooi.

De software kan die updaten. Cursor generatie heeft wat extra flipflops nodig (7474) en wat gates...
Verrek. als ik die cursor registers omzet naar 8 bit up/down counter met laad mogelijkheid kan ik de encoders daar direkt aan hangen.... scheelt weer software werk. laat de hardware al dat spul doen.
En ik kan het zelfde doen voor trace selectie....
En sinds die nu ook in de hardware wereld leeft kan ik de verticale step dac daar ook sturen. Maar daar heb ik 5 registers voor nodig. Dit wordt een flinke bak TTL....

hmmm. -lightbulb- : een CPLD ! ideaal voor dit soort werk. voor 6$ heb ik een 5M160 die al dat werk aankan.
Blijk dat de MAX V simpelweg kan geprogrammeerd worden met een FTDI in MPSSE mode (JTAG).
Als ik de FTDI232 vervag door een 2232 ( 2 poorten) . heb ik er eentje voor communicatie / programmering van de microprocessor (Atmel UPDI) , en de tweede voor de cpld. Er is dus geen nood aan externe dongles.... mooi.

Maar we gaan de logica niet meer met schematjes ontwerpen.... SystemVerilog to the rescue !

Effe Quartus II 13.xx downloaden en installeren.

wat experimenterne later en we krijgen dit :



/* NOTE : this code uses the principle of scheduled logic. If you don't know what that is : the verilog (and als VHDL) standard mandate that code shall be evaluated in the order it is written. The practical aspect is that a later line of statements takes precedence over an earlier one.

Example:
  x <= x+;
 .... some more stuff ...
if (reset)  x <= 0;

The reset now has priority. There is no need for if-then-else constructs. Since the last line gets evaluated last , it determines the final outcome.

Scheduled logic eliminates undefined states completely and removes the complexity of nested if-then-else constructs)
*/
module sweepcontrol 
(
   // ----------------------- inputs ---------------------

   // master clock
   input logic clk,
	
	// data and address bus
	input logic [7:0]  data_in,
	input logic [3:0]  address_in,
	input logic write,
	
	// rotary encoder signals
	input logic rot_phase_a , rot_phase_b,
	
	// sampling enable
	input logic enable_sampling,
	
	// ----------------------- outputs ---------------------

	// dac output
	output logic [7:0] dac,
		
   // sampler gate signals		
	output reg sample_gate_a , sample_gate_b ,
	
	// channel selection
	output reg [1:0] channel_select,   // drives relays or multiplexer
	output reg channel_ab,       // notifies cpu what channel is sampled
	
	// sampling done 
	output reg sample_ready,     // notifies cpu samples have been collected
	
	// cursor generation
	output reg [1:0] cursor_state,
   
	// voltage dac
	output reg [7:0] dac_y,
	
	// general purpose encoder
	output reg [7:0] encoder_value
);


// internal registers  

reg [7:0] cursor_a , cursor_b ;
reg [7:0] rotary_limit;
reg [11:0] loopcounter;
reg auto_channel;
reg [2:0] selected_trace;
reg [7:0] step1;
reg [7:0] step2;
reg [7:0] step3;
reg [7:0] step4;
reg [7:0] step5;
reg [3:0] edge_detector;
reg [1:0] rotary_binding;

// This is a pure combinatorial block 
// We bring out the lowest 8 bit of the loopcounter to drive the dac

always_comb begin
   dac[7:0] <=loopcounter [7:0];
end

always_ff @(posedge clk) begin
   
	// Always running upcounter. on counter overrun increment sweep counter
	loopcounter <= loopcounter +11'd1;
	if (loopcounter == 11'b100_11111111) begin
		loopcounter <=0;
		if (auto_channel ==1) begin
		   case (channel_select)
			  2'b00 : channel_select <= 2'b00;
			  2'b01 : channel_select <= 2'b10;
			  2'b10 : channel_select <= 2'b01;
			  2'b11 : channel_select <= 2'b00;   // this can't happen , but if it does : turn all off
			endcase
		end
	end	
	
	// this can run always too : update vertical dac 
	case (loopcounter[10:8])
	   3'b000 : dac_y <= step1;
		3'b001 : dac_y <= step2;
		3'b010 : dac_y <= step3;
		3'b011 : dac_y <= step4;
		3'b100 : dac_y <= step5;
	endcase
	
	
	if (channel_select == 2'b10) channel_ab <=1;
	if (channel_select == 2'b01) channel_ab <=0;
	
	// rotary encoder edge detector
	
	edge_detector[3:0] <= { edge_detector [2:0],rot_phase_a};
	
	// sampling logic
	
	if (loopcounter[10:8] == selected_trace) begin
	   if (sample_ready == 1'b0) begin
			if (loopcounter[7:0] == 8'b0) begin
				 sample_gate_a <= 1'b1;
				 sample_gate_b <= 1'b1;
			end
			case (cursor_state)
			2'b00   :	begin
								if (loopcounter [7:0] == cursor_a) begin
									cursor_state  <= 2'b01;
									sample_gate_a <= 1'b0;
								end
								if (loopcounter [7:0] == cursor_b)begin
									cursor_state  <= 2'b01;
									sample_gate_b <= 1'b0;
									sample_ready  <= 1'b1;
								end;	
							end 
			2'b01   :   cursor_state <= 2'b11;
			2'b11   :   cursor_state <= 2'b00;
			default :   cursor_state <= 2'b00;
			endcase
		end
		else begin
			if (enable_sampling == 1'b1) sample_ready <=1'b0;
		end
	end	
	
	// cursor control
	if (edge_detector == 4'b0111) begin
		case (rotary_binding)
		2'b00 :  if (rot_phase_b ==0) begin
		            if (cursor_b !=255) cursor_a <= cursor_a+ 8'd1;
					end
					else begin
					   if (cursor_a !=0) cursor_a <= cursor_a-8'd1;
					end
					
		2'b01 :  if (rot_phase_b ==0) begin
		            if (cursor_b !=255) cursor_b <= cursor_b+8'd1;
					end
					else begin
					   if (cursor_b !=0) cursor_b <= cursor_b-8'd1;
					end
		2'b10 : 	if (rot_phase_b ==0) begin
		            if (selected_trace != 3'b100) selected_trace <= selected_trace+3'd1;
					end
					else begin
					   if (selected_trace !=0) selected_trace <= selected_trace-3'd1;
					end	
		2'b11 :	if (rot_phase_b ==0) begin
		            if (encoder_value != rotary_limit) encoder_value <= encoder_value + 8'd1;
					end
					else begin
					   if (encoder_value !=0) encoder_value <= encoder_value -8'd1;
					end	
		
		endcase
	end
	
	
	
	// process the register writes. Since this happens later it takes priority (scheduled logic)
	if (write ==1) begin
		case (address_in)
			4'b0000 : cursor_a       <= data_in;
			4'b0001 : cursor_b       <= data_in;
			4'b0010 : selected_trace <= data_in [2:0];
			4'b0011 : rotary_limit   <= data_in;
			4'b0100 : begin
							if (auto_channel==0) begin                                     // don't allow this when in autochannel
								if (data_in[1:0] != 2'b11) channel_select <= data_in[1:0];  // protect from user stupidity. block enabling both channels
							end	
						end	
			4'b0101 : auto_channel   <= data_in[0];
         4'b0110 : rotary_binding [1:0] <= data_in[1:0];
			4'b0111 : begin                                                             // reset command
							sample_ready <=1'b0;                                            // force sample write register
							cursor_state <=2'b0;
							channel_select <=2'b0;
							sample_gate_a <=1'b0;
							sample_gate_b <=1'b0;
							loopcounter <=0;
							dac_y <=0;
						 end	
			
			4'b1000 : step1 <= data_in;
			4'b1001 : step2 <= data_in;
			4'b1010 : step3 <= data_in;
			4'b1011 : step4 <= data_in;
			4'b1100 : step5 <= data_in;
			5'b1111 : encoder_value <=data_in;
		endcase
	end
	
end

endmodule

Dit ding draait autonoom.
De software laadt de 5 waardes voor de step generator. en de boel werkt vanzelf.
De software kan de cursors positioneren, maar kan ook de encoder koppelen aan een van de cursors / trace selectie. De encoder bedient dan de cursor of trace autonoom.
De samplers worden gestuurd vanuit de cursor logica. Als de juiste trace voorbij komt vuren de samplers af. Als de tweede sampler klaar is krijgt de processor een interrupt en kan die de a/d conversie doen. De processor heeft alle tijd van de wereld om dat te voltooien. Zolang de processor de samplers niet vrijgeeft vuren die niet opnieuw af. Aangezien een 5-trace sweep minstens 20 milliseconden (50 sweep/seconde om geflikker tegen te gaan) duurt is dat flink tijd zat.

De harde logica kan ook multiplexen tussen de kanalen. zo krijg je 10 traces ( 5 van kanaal a, en 5 van kanaal b) ter zelfder tijd te zien. ideaal om 2 transistors te matchen. De cursors verdubbelen dan ook maar volgen elkaar ( er is slechts 1 positie , identiek voor de twee traces) . de software kan dan op het display de delta laten zien tussen de kanalen alsook tussen de cursors.

Het kan in princiepe allemaal in software gedaan worden maar alles is onderhavig aan interrupts. Er gebeurt te veel en de software wordt een warboel. Het simuleert ook niet makkelijk. De meeste software simulatoren hebben geen ondersteuning voor interrupt werk. De CPLD omgeving kan dat wel.

ik ben nu een maal veel sterker in hardware dan in software....

Andersom zal het denk ook wel gebeuren dat een software programeur te moeilijk aan het doen is met software terwijl daar een CPLD bij moet.

Ben nog altijd van plan om ooit iets een keer met een CLPD te gaan doen maar hoe en waar begen je dan.

Als ik zo naar je stuk software kijk dan zie het er haast makkelijk uit.
Een aantal dingen herken ik wel van Arduino met C/C++. Niet dat het hetzelfde is maar het is wel te herkennen wat de blokken doen.

Voor mij een nogal spannende ontwikkeling. Ik heb wel al lange tijd de wens gehad om eens iets met CPLD's en/of FPGA's te gaan doen, maar het is er nooit van gekomen. Dit is wel een mooie nieuwe motivatie!
Ik zie nu ook meer mogelijkheid voor een optionele hard-copy functie (
Hameg HM8148 ?)

CPLD / FPGA is makkelijk ... als je de juist omgeving hebt !
Altera Quartus is gratis en je kan schematjes tekenen met TTL ic'tjes. Je kan ook Verilog / VHDL / systemverilog maken. En het kan schematjes omzetten naar verilog ! heel leuk om te leren hoe je iets maakt.

Als je daar mee weg wilt : Van 0 en 1 tot FPGA (shameless plug :p )
https://webservices.bibliotheek.be/index.php?func=cover&ISBN=9789053812488&VLACCnr=7527135&CDR=&EAN=&ISMN=&EBS=&coversize=large

20 jaar geleden was al dat spul peperduur ne had je dongles nodig (byteblaster). nog vroeger was die software niet gratis... en de devices zelf zeer duur.

Nu heb je al een dikke cpld voor 5$ ... en ze programmeren met een simpele ftdi uart/mpsse chip. De software is gratis en heeft schema , hdl en simulator aan boord (toch die van Altera. Lattice is nog steeds een kreng en zielinks ligt ook nog beter links )

[Bericht gewijzigd door free_electron op (30%)]

Zo'n 27 jaar geleden heb ik op de HTS wel kennis gemaakt met het fenomeen FPGA, maar dat was programmeren in VHDL en dat was voor mij eigenlijk meteen een dooddoener: VHDL vond ik toen te ingewikkeld (Hoewel ik wel alle opdrachten succesvol heb afgerond). Verilog schijnt veel begrijpelijker te zijn.

Misschien toch eerst maar eens beginnen bij het begin: PAL's/GAL's ?

ahh. very hard design language ... past gelijk een tang op een varken....

VHDL is een generic hardware language (je kan daar zelfs een vijs mee beschrijven) waar ze via een library logica kunnen mee beschrijven. Het is een "afterthought"

Verilog is iets wat van meet-af-aan gemaakt is om logica mee te beschrijven. het is flexibeler. zeker nu Verilog 2005 en systemverilog bestaan. Veel van het keyboard werk is verdwenen.

De vergelijking met c : je moet een header file maken om je functies foward te declareren. Dat is onnozel. De compiler moet dat zelf kunnen vinden. Die miserie bestond ook in verilog : je maakt een definitie met all in in en uitgangen , en dan moet je later gans die reutemeteut herhalen om het type te definieren (combinatorisch of register). Dat is allemaal extra tikwerk en het leidt tot "fauten" die je dan eerst moet corrigeren vooraleer het wil compileren.

Met systemverilog is dat allemaal weg. je schrijft het 1 keer. geen nood aan headers en dergelijke.

De Altera ide helpt je met autocomplete.

En als je leert hoe een synthesizer werkt en het princiepe van scheduling werkt dan is logic maken heel makkelijk , voorspelbaar en haast bullet proof (zonder verborgen of missing condities).

Scheduling is iets wat eigen is aan de standaard voor Verilog en VHDL, maar het wordt haast nergens duidelijk uitgelegd. De focus ligt altijd op een "software" benadering. Het is HARDWARE !

in kort : wat i scheduled logic ?

de standaarden van verilog en vhdl definieren dat "statements will be evaluated in the order they are written".

Voorbeeld :
x <= x+1;
blablabla..
if (reset) x<=0;

x telt altijd op.
Als reset hoog is (in systemverilog geen nood om te schrijven "reset ==1") : zet x op 0.

Aangezien dat laatste statement later komt , krijgt het voorrang. ( zie het zo : het staat laatst in de volgorde van instructies, dus dichter bij de uitgang. Dat is ook hoe de synthesizer werkt. dat eerste statement maakt een register (flipflops) aan, voert de uitgang terug naar een blok wat +1 doet. en van dat +1 blok gaan we terug naar dat register. dat tweede statement knipt die verbinding van dat +1 blok naar de registers door en zet daar een multiplexer. Dat reset signaal controleert de multiplexer. als reset nul is wordt het +1 blok aan de ingang van het register gehangen. Als reset 1 is hangen we de waarde '0' aan het register.

Er zijn geen onafgedekte paden in dergelijk systeem.

Voorbeeld : maak een teller met enable , up/down , reset en parallel load.


 reg [7:0] counter;   // maak een 8 bit register.


always @(posedge clk) begin  // wanneer we een clock krijgen :

if (updown) counter <=counter +1 else counter <= counter -1;  // we gaan op of neer afhankelijk van het updown signaal
if (!enable) counter <=counter  // als we niet enabled zijn tellen we niet.. we blijven de huidige waarde houden.
if (load) counter <= parallel_in // als we moeten laden : haal data op
if (reset) counter <=0; // reset heeft prioriteit (staat lager)

het eerste statement telt op / af onder controle van het updown signaal.
het tweede statement blokkeert het tellen als enable nul is ( ! enable). die eerste lijn mag staan dansen wat het wil , die teller verandert niet.
het derde statement kan de counter laden. ook al is de teller aan het dansen , of disabled : het register moet en zal laden.
en het laatste statement heeft het meeste macht : als die reset komt gaat die counter onverbiddelijk op nul.

Er is geen enkel nood aan if then else constructies. Er zijn geen ongedefinieerde paden. je hoeft dit zelfs niet te simuleren. Het zal werken.

Al die multiplexers and adders/subtractors zijn een grote wolk combinatorische logica. dat word ta llemaal gesimplifieerd naar wat and en or gates.
En dergelijke logica mapt nu eenmaal perfect op een cpld/fpga. Die is namelijk ook zo gebouwd : een bank flipflops met een enorme wolk and/or poorten ervoor.

Geen idee hoe je het doet, maar zoals jij het uitlegt, komt het als eenvoudig en duidelijk over! Ik krijg er zin in!

Waarschijnlijk is je boek op dezelfde wijze geschreven?

https://github.com/vincent-himpe/CurveTraceNew/blob/main/images/synthesis.png?raw=true

stap voor stap hoe de synthesizer dat uitwerkt.

een multiplexer is niks anders dan een simpele booleaanse vergelijking ((a & !control)+(b & control)).

Dus gans die logica wolk is niks anders dan domme AND en OR poorten wat inverters om te schakelen tussen a en b. Die formules worden lang maar de logic reducer (een super duper karnaugh kaart motor. egenlijk het Quine - McKlusky algorithme) perst dat samen.

Een adder en subtractor is ook niks anders dan wat AND en OR poorten. dus daar hoe je ook niet bang van te zijn. Voor elke tak is dat een karnaugh kaart van 5 x 4.

5 aan linkerkant:
+1
-1
counter
data_in
0

4 bovenaan:
updown
enable
load
reset

En je hebt dat voor elke flipflop, dus 8 keer.
Een CPLD lacht daar mee, een FPGA giert het uit.

Op zaterdag 8 november 2025 21:42:16 schreef MNM(tm):
Geen idee hoe je het doet, maar zoals jij het uitlegt, komt het als eenvoudig en duidelijk over! Ik krijg er zin in!

Waarschijnlijk is je boek op dezelfde wijze geschreven?

Ja daar ben ik het mee eens.
Maar ik denk ook dat dat komt door hoe verilog is opgebouwd. Maar er zijn wel een een paar dingen die je moet weten.

De vergelijking met c :

Ik wou geen vergelijking maken met C, Maar mee dat er dingen herkenbaar zijn.

Het enige wat ik nu even niet snap is dit.
Ik kan het natuurlijk ook opzoeken maar ik denk ook dat er meer zijn die aich afvragen wat word er mee bedoelt.

if (reset) counter <=0;

Ik lees dit als.
Voer een reset uit als counter kleiner of gelijk is aan 0

Maar volgens je uitleg begrijp ik dit:
Als het reset signaal actief is maak counter gelijk aan 0

Wat ik lees is dat er een conditionele voorwaarde wordt gesteld "if (reset)", wat een true of en false kan opleveren. In geval van true wordt de navolgende 'instructie' uitgevoerd: "counter <= 0" (zet waarde 0 in het register met de naam 'counter').

Als er iemand een keer (als het ontwerp af is) PCB's gaat leveren en de geprogrammeerde IC's ga ik er ook 1 maken. Zeker als hij zonder PC kan werken.

Misschien kunnen we er tzt een soort van groep project van maken. PCBs en programmeren is voor mij een erg grote stap en geen geschikte apparatuur, maar bv SMD solderen is geen probleem, ik heb genoeg ervaring en apparatuur. Dat kan ik dan bv wel voor anderen doen die daar een probleem mee hebben, dingen testen of afregelen/kalibreren kan ik ook (Ik heb zelfs een Tek 576 als vergelijk) Ik kan ook bv een tutorial/manual schrijven, dat heb ik ook voor een VNA gedaan. Die cursus werd toen in India op een universiteit gebruikt (ze vroegen keurig toestemming). Ik speel al zo'n 15 jaar met curvetraces)

het ganse project staat op github en de borden kunnen bij jlcpcb gemaakt worden.
geprogrammeerde ic's zijn niet nodig. De processor en cpld zijn zo gekozen dat je geen kunst en vliegwerk nodig hebt. de USB poort op het bord kan zowel de processor als CPLD laden.

Geen nood aan programmeer dongles.

de processor gebruikt UPDI (seriele poort via de FTDI chip) en gratis software van ATMEL (microchip) om die te laden. De CPLD gebruikt JTAG , ook over de FTDI chip (MPSSE mode). direct te laden vanuit Quartus.

Ik ga een FT2232 gebruiken (2 seriele poorten, ene als UPDI/UART aan de processor, de tweede als JTAG aan de CPLD.

De keuze van de cpu en cpld zijn heel zorgvuldig zo gedaan dat je geen programmers, dongles, pinheaders en weetikveel wat rommel nodig hebt ( die dan weer drivers nodig hebben, niet werken op jouw operating system, of niet de juiste versie zijn. ). Een (echt) FTDI chippie werkt overal.

Ik heb zelf een gloeiende hekel aan die dongles. ik heb er een ganse schuif vol van. J-links, seggers, Keil Ulinks, ST programmers, Hitech xmos en nog een gans pak andere. Allemaal met hun eigen software die alleen werkt met versie xyz op operating systeem abc.. Ik heb ene tijd geleden een tiental seggers weggesmeten. die dingen waren peperduur. maar het zijn oude hardware versies die niet meer ondersteund worden met drivers alleen voor windows 98. kopen kopen en blijven kopen. Gedaan ermee. Als het niet over een seriele poort kan werk ik er niet meer mee. Processors moeten uit de fabriek komen met een usb/uart bootloader. Er zelf ene inflashen is ook weer ene kip-ei probleem.

spuugzat ben ik het.

Het ganse ontwerp is zo in elkaar gezet dat je niks nodig hebt op een soldeerbout na.
allis is 0603 of groter en ik mijd zelfs dingen zoals tssop .Op de processor en cpld na is niks 0.5mm en een paar i/o expanders. allemaal 1.27mm so8 verpakkingen.

de volgende stap nu is een partieel board maken met processor en cpld en een deel van de generator. zodat ik de DAC en analoge blokken kan testen. daarnaa volgt het echte moederbord.

[Bericht gewijzigd door free_electron op (12%)]

En daar ben ik het volledig mee eens. Ik heb ook een bloedhekel aan al die proprietary protocollen en interfaces om een chip iets zinnigs te kunnen laten doen. Het moet met I2C of SPI kunnen. De rest kan de boom in. JTAG vind ik ook een irritante interface.

Ik vind het een zeer mooi project!!

Ik was eigenlijk wel weer benieuwd naar een status update van dit project?

Inmiddels zitten we al weer in de derde week van mei. Is er al nieuws?