Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to create a ring oscillator #118

Closed
DurandA opened this issue Jul 1, 2019 · 5 comments
Closed

Unable to create a ring oscillator #118

DurandA opened this issue Jul 1, 2019 · 5 comments
Labels

Comments

@DurandA
Copy link

DurandA commented Jul 1, 2019

I am trying to build a ring oscillator (targeting iCE40) using nmigen. I first made a simple Verilog design (see above, adapted from Clifford's ringosc.v) and then tried to port it to nmigen:

class RingOscillator(Elaboratable):
    def elaborate(self, platform):
        user_led = platform.request("user_led", 0)

        m = Module()

        cd_chain = ClockDomain(async_reset=True)
        m.domains += cd_chain

        buffers_in = Signal(7)
        buffers_out = Signal(7)
        
        m.d.comb += buffers_in.eq(buffers_out[-1:] + buffers_out[0:-1])
        
        for buf_in, buf_out in zip(buffers_in, buffers_out):
            inverter = Instance("SB_LUT4",
                                    p_LUT_INIT=0b01,
                                    i_I0=buf_in,
                                    i_I1=Const(0),
                                    i_I2=Const(0),
                                    i_I3=Const(0),
                                    o_O=buf_out)
            m.submodules += inverter

        m.d.comb += cd_chain.clk.eq(buffers_out[-1])
        
        counter  = Signal(24)
        m.d.chain += counter.eq(counter + 1)
        m.d.comb += user_led.o.eq(counter[-1])

        return m

Unfortunately, the above code doesn't produce a working oscillator. It is unclear to me if I don't understand how to use nmigen clocks or if this is due to unwanted optimizations (or if I made a dumb mistake somewhere else).

Here is a simple working version in Verilog:

module top (
    output LED
);
    wire [6:0] buffers_in, buffers_out;
    assign buffers_in = {buffers_out[5:0], buffers_out[6]};

    SB_LUT4 #(
        .LUT_INIT(16'd1)
    ) buffers [6:0] (
        .O(buffers_out),
        .I0(buffers_in),
        .I1(1'b0),
        .I2(1'b0),
        .I3(1'b0)
    );

    reg [23:0] counter = 0;
    always @(posedge buffers_out[6]) begin
        counter <= counter + 1;
    end

    assign LED = counter[23];

endmodule

For both versions, nextpnr should be configured with --ignore-loops switch.

How to use a proper clock attached to the oscillator? Is this problem related to #57?

@peteut
Copy link
Contributor

peteut commented Jul 1, 2019

@DurandA did you forgot to assign ResetSignal, either using ResetSignal("chain") or cd_chain.rst?
Maybe you are looking for ClockDomain(reset_less=True).

@peteut
Copy link
Contributor

peteut commented Jul 1, 2019

m.d.comb += buffers_in.eq(buffers_out[-1:] + buffers_out[0:-1])

should spell

m.d.comb += buffers_in.eq(Cat(buffer_out[-1], buffers_out[:-1]))

to reflect the Verilog code

assign buffers_in = {buffers_out[5:0], buffers_out[6]};

@DurandA
Copy link
Author

DurandA commented Jul 1, 2019

m.d.comb += buffers_in.eq(buffers_out[-1:] + buffers_out[0:-1])

should spell

m.d.comb += buffers_in.eq(Cat(buffer_out[-1], buffers_out[:-1]))

to reflect the Verilog code

assign buffers_in = {buffers_out[5:0], buffers_out[6]};

Many thanks, this solved the issue. I thought that Python slices supported concatenation.

Sorry, something went wrong.

@DurandA DurandA closed this as completed Jul 1, 2019
@whitequark
Copy link
Contributor

I thought that Python slices supported concatenation.

Python doesn't have a slice object*, it has a slice operator. The slice operator applied to lists returns a list, and list's + operator performs concatenation. The slice operator applied to an nMigen value returns an nMigen value, and nMigen value's + operator performs addition.

* There is the slice class, but it's more of an implementation detail of the __getitem__ function than an actual language feature, and is not relevant here.

Sorry, something went wrong.

@DurandA
Copy link
Author

DurandA commented Jul 1, 2019

Python doesn't have a slice object*, it has a slice operator. The slice operator applied to lists returns a list, and list's + operator performs concatenation. The slice operator applied to an nMigen value returns an nMigen value, and nMigen value's + operator performs addition.

Thank you for the clarification! This is very much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants