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
eagle987
Eerst waren het atomen, dan waren het protonen, neutronen, elektronen, nog later waren het quarks en nu blijken het snaren te zijn...
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%)]
noone
483726095 / Een foto zegt meer dan 1000 woorden.
@eagle987, wat moet er nu veranderd worden? ik zie geen verschil tussen Verander [Blok] en Eens in [Blok],
mvg,
noone.
eagle987
Eerst waren het atomen, dan waren het protonen, neutronen, elektronen, nog later waren het quarks en nu blijken het snaren te zijn...
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;
endLaat 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
endmoduleNu 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.
eagle987
Eerst waren het atomen, dan waren het protonen, neutronen, elektronen, nog later waren het quarks en nu blijken het snaren te 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.