hoglet wrote:
This doesn't look like sensible Verilog to me.
Specifically, you are assigning to signalChangePending in two seperate blocks, which is not legal.
Aha! Thanks, that's what I was missing. I didn't realize there was that restriction. Changed the example to this and it builds as expected:
Code:
module Bug
(
output reg signal,
input wire CLK
);
reg currentState = 0;
reg signalChangePending = 0;
always @(posedge CLK) begin
if (signalChangePending) begin
signal <= ~signal;
end
end
always @(negedge CLK) begin
if (signalChangePending) begin
signalChangePending <= 0;
end
else if (currentState == 1) begin
signalChangePending <= 1;
currentState <= 0;
end
else begin
currentState <= 1;
end
end
endmodule
// Pin assignment for the experimental Yosys FLoow
//
//PIN: CHIP "Bug" ASSIGNED TO AN PLCC84
//PIN: signal : 74
//PIN: CLK : 83
As for what this was trying to do, well it was a contrived stripped down example of an issue I hit trying to write a real verilog definition of a bus controller for a 68000 system. This is a bit of an unusual system designed to push into the corner-cases of the 68000 behaviour. I'm doing some strange things, one of which is testing the bus retry logic of the 68000. I was trying to honor this section of the 68000 Users Manual related to signal timing:
"5.6 THE RELATIONSHIP OF DTACK, BERR, AND HALT
To properly control termination of a bus cycle for a retry or a bus error condition, DTACK,
BERR, and HALT should be asserted and negated on the rising edge of the processor
clock. This relationship assures that when two signals are asserted simultaneously, the
required setup time (specification #47, Section 9 Electrical Characteristics) for both of
them is met during the same bus state. External circuitry should be designed to
incorporate this precaution. A related specification, #48, can be ignored when DTACK,
BERR, and HALT are asserted and negated on the rising edge of the processor clock."I had an event I detected that occurs on a falling edge, and I was trying to flag the three control signals DTACK, BERR, or HALT on the next rising clock edge as a result. This resulted in me setting a "signalChangePending" flag for each one, which I was setting from one block, and picking up and clearing from another. Now that I understand that's not legal I can use a different approach.
I've got 25+ years in software development, but when it comes to Verilog, to date my experience is mostly in browsing and unpacking things other people have written. This is the first time I'm trying to build something from scratch, so I'm going to run into a lot of beginner mistakes I'm sure. I'm off reading more now about multiple clock domains and how this stuff all gets synthesized. Happy to accept tutorial/book/reference recommendations! Mostly working my way systematically through the reference at
https://www.chipverify.com/tutorials/verilog right now.