Ik probeer om met volgende code een PS/2 toetsenbord uit te lezen. Het opzet is vrij simpel: bij een dalende flank kopieer data en bij een stijgende flank schuif alles een plaats op. Allebij onder bepaalde voorwaarden uiteraard.

Het probleem is echter dat de synthesizer als foutmelding geeft:

Error (10028): Can't resolve multiple constant drivers for net "byteA[7]" at ps2parser.v(53)

wat volgens mij duidt op twee mogelijks tegensprekende assignments. Maar mijn code maakt echter onderscheidt tussen een dalende en stijgende flank, wat een tegensprekende assignment moet vermijden. Om het probleem te verhelpen heb ik dan de if-condities (clock hoog of laag) ingevoegd, maar ook dat bracht geen soelaas.

Hoe kan ik dit stukje code doen werken?

//If the stateCounter is smaller than 11 we are working with byte A,
//else the counter will have increased to 11 or higher and we will be working with byte B
always
	begin
		if(stateCounter < 11)
			lastByte = 1'b1;
		else
			lastByte = 1'b0;
		end

always @(negedge sclk_in)
	if(sclk_in == 1'b0)
	begin
		//Clock in one of bits of the data byte and place this bit at the MSB
		if(stateCounter < 9 && stateCounter > 0)
			begin
				byteA[7] = sda_in;
			end
		else if(stateCounter < 20 && stateCounter > 11)
			begin
				byteB[7] = sda_in;
			end
		stateCounter = stateCounter+1;
	end

always @(posedge sclk_in)
	if(sclk_in == 1'b1)
	begin
		//Shift the MSB to LSB if we are in a bit of the data byte and not
		//working the MSB (which does not need to be shifted)
		if(stateCounter > 1 && stateCounter < 8)
			byteA <= byteA >> 1;
		if(stateCounter > 12 && stateCounter < 19)
			byteB <= byteB >> 1;
	end

Allereerst: je code werkt op beide flanken, dit is not done.
Verander:

		if(stateCounter < 9 && stateCounter > 0)
			begin
				byteA[7] = sda_in;
			end
		else if(stateCounter < 20 && stateCounter > 11)
			begin
				byteB[7] = sda_in;
			end

Eens in:

		if(stateCounter < 9 && stateCounter > 0)
			begin
				byteA[7] <= sda_in;
			end
		else if(stateCounter < 20 && stateCounter > 11)
			begin
				byteB[7] <= sda_in;
			end

<= wordt gebruikt in geklokte processen, = wordt gebruikt in combinatorische processen

--edit--

Je bent begin en end vergeten op te geven bij je "always" constructie

always ... begin
...
end

[Bericht gewijzigd door eagle987 op (10%)]

@eagle987, wat moet er nu veranderd worden? ik zie geen verschil tussen Verander [Blok] en Eens in [Blok],

mvg,
noone.

De hele blok moet veranderd worden in het volgende:

always	begin

	if(stateCounter < 11)
		lastByte = 1'b1;
	else
		lastByte = 1'b0;
end

always (@negedge sclk_in) begin

	if(stateCounter < 9 && stateCounter > 0)
		byteA[7] <= sda_in;

	else begin
		if(stateCounter < 20 && stateCounter > 11)
			byteB[7] <= sda_in;
	end

	stateCounter <= stateCounter+1;
end

always (@posedge sclk_in) begin

	if(stateCounter > 1 && stateCounter < 8)
		byteA <= byteA >> 1;
	if(stateCounter > 12 && stateCounter < 19)
		byteB <= byteB >> 1;
end

Laat maar horen of er nog errors zijn.

Ik heb het hele stuk code weg gegooid en ben opnieuw begonnen. Het resultaat:

module ps2parser(sda_in, sclk_in, byteA, byteB, stateCounter);
//These two come from the keyboard
input sda_in;
input sclk_in;

//byte A is the first received character, byte B the second
output reg[7:0] byteA;
output reg[7:0] byteB;

//This counter keeps track of the current clock while receiving
output reg[4:0] stateCounter;

initial begin
	stateCounter <= 5'b0_0000;
	byteA <= 8'h00;
	byteB <= 8'h00;
end

always @(negedge sclk_in) begin
	//Clock in one of bits of the data byte and place this bit at the MSB, shift the six MSB's to the six LSB's
	if(stateCounter >= 1 && stateCounter <= 8) begin
		byteA <= {sda_in, byteA[7:1]};
	end else if(stateCounter >= 12 && stateCounter <= 19) begin
		byteB <= {sda_in, byteB[7:1]};
	end	
		
	if(stateCounter < 21) begin
		stateCounter <= stateCounter + 5'b0_0001;
	end else begin
		stateCounter <= 5'b0_0000;
	end		
end

endmodule

Nu compileert het stuk wel, maar als ik mijn toetsenbord aansluit krijg ik jibberisch: als ik op dezelfde toets druk krijg ik (vanaf een maagdelijke toestand) de waarden 16h8035, 16h0015 (de correcte waarde trouwens), ... Ook de stateCounter geeft vreemde waarden aan zoals 32, 12, ... die normaal gezien niet mogen voorkomen, gezien PS/2 met reeksen van 11 bits werkt.

Ziet iemand waarom dit stukje code niet doet wat ik verwacht?

Ik het de oplossing gevonden: de clock van het toetsenbord is erg vuil, daarom is het nodig om het clock-signaal eerst te filteren met een schuifregister.

Filteren met een schuifregister? Ik denk dat een schmitt-trigger beter geschikt zou zijn.

Als ik me niet vergis zitten er geen Schmitt-triggers ingebouwd in een Cyclone III FPGA (uitgezonderd de JTAG-lijnen) en ze uitwendige toevoegen is ook uitgesloten, daar ik met een experimenteerbordje werk.

Ik ga straks eens m'n scoop aan de klok van toetsenbord hangen, eens kijken hoe het er juist uitziet.