Reputation: 1552
New to verilog here.
The Ice40 has an RGB led driver that can also be assigned as a normal IO.
Trying to access the pin without setting it as IO will give this error one IceCube2
Error during constrained IO placement E2792: Instance ipInertedIOPad_LED_B incorrectly constrained at SB_IO_OD location
To do so, the following verilog is used:
SB_IO_OD #( // open drain IP instance
.PIN_TYPE(6'b011001) // configure as output
) pin_out_driver (
.PACKAGEPIN(LED_B), // connect to this pin
.DOUT0(ledb) // output the state of "led"
);
So the final verilog code looks like (simplified to 1 led):
module top (output LED_R, output LED_G, output LED_B);
reg ledb = 0;
reg [3:0] cnt;
SB_IO_OD #( // open drain IP instance
.PIN_TYPE(6'b011001) // configure as output
) pin_out_driver (
.PACKAGEPIN(LED_B), // connect to this pin
.DOUT0(ledb) // output the state of "led"
);
always
begin
ledb = ~cnt[2];
end
always @(posedge clkout)
begin
cnt <= cnt + 1;
end
endmodule
and it does work.
However, I assign the led in an always block, which is sequential as I understand. Would the "correct" way to assign ledb as a wire, but then it is not compatible with the SB_IO_OD.
Is this the correct way to do it, or there is a non-sequential way to assign the led, basically not assigning in the always block.
Upvotes: 0
Views: 806
Reputation: 1552
After some digging, I believe this is the correct way. It also uses much less logic cells
Working code on IceCube2, simple LED blinker:
module top (output LED_R, output LED_G, output LED_B);
wire [2:0] leds;
reg [2:0] cnt;
SB_IO_OD #( // open drain IP instance
.PIN_TYPE(6'b011001) // configure as output
) pin_out_driver (
.PACKAGEPIN(LED_B), // connect to this pin
.DOUT0(leds[0]) // output the state of "led"
);
SB_IO_OD #( // open drain IP instance
.PIN_TYPE(6'b011001) // configure as output
) pin_out_driver2 (
.PACKAGEPIN(LED_G), // connect to this pin
.DOUT0(leds[1]) // output the state of "led"
);
SB_IO_OD #( // open drain IP instance
.PIN_TYPE(6'b011001) // configure as output
) pin_out_driver3 (
.PACKAGEPIN(LED_R), // connect to this pin
.DOUT0(leds[2]) // output the state of "led"
);
wire sysclk;
SB_HFOSC #(.CLKHF_DIV("0b00")) osc (
.CLKHFEN(1'b1),
.CLKHFPU(1'b1),
.CLKHF(sysclk)
) /* synthesis ROUTE_THROUGH_FABRIC = 0 */;
wire clkout;
clockdivider #(.bits(28)) div(
.clkin(sysclk),
.clkout(clkout),
.div(28'd48000000)
);
assign leds = {~cnt[2:0]};
always @(posedge clkout)
begin
cnt <= cnt + 1;
end
endmodule
Upvotes: 0