Add (heavily work in progress) documentation.
To render correctly, the docs require: * pygments/pygments#1441
This commit is contained in:
parent
8dacbbb2b2
commit
399b8f9863
21 changed files with 1565 additions and 23 deletions
24
docs/_code/led_blinker.py
Normal file
24
docs/_code/led_blinker.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
from nmigen import *
|
||||
|
||||
|
||||
class LEDBlinker(Elaboratable):
|
||||
def elaborate(self, platform):
|
||||
m = Module()
|
||||
|
||||
led = platform.request("led")
|
||||
|
||||
half_freq = int(platform.default_clk_frequency // 2)
|
||||
timer = Signal(range(half_freq + 1))
|
||||
|
||||
with m.If(timer == half_freq):
|
||||
m.d.sync += led.eq(~led)
|
||||
m.d.sync += timer.eq(0)
|
||||
with m.Else():
|
||||
m.d.sync += timer.eq(timer + 1)
|
||||
|
||||
return m
|
||||
# --- BUILD ---
|
||||
from nmigen_boards.icestick import *
|
||||
|
||||
|
||||
ICEStickPlatform().build(LEDBlinker(), do_program=True)
|
||||
79
docs/_code/up_counter.py
Normal file
79
docs/_code/up_counter.py
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
from nmigen import *
|
||||
|
||||
|
||||
class UpCounter(Elaboratable):
|
||||
"""
|
||||
A 16-bit up counter with a fixed limit.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
limit : int
|
||||
The value at which the counter overflows.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
en : Signal, in
|
||||
The counter is incremented if ``en`` is asserted, and retains
|
||||
its value otherwise.
|
||||
ovf : Signal, out
|
||||
``ovf`` is asserted when the counter reaches its limit.
|
||||
"""
|
||||
def __init__(self, limit):
|
||||
self.limit = limit
|
||||
|
||||
# Ports
|
||||
self.en = Signal()
|
||||
self.ovf = Signal()
|
||||
|
||||
# State
|
||||
self.count = Signal(16)
|
||||
|
||||
def elaborate(self, platform):
|
||||
m = Module()
|
||||
|
||||
m.d.comb += self.ovf.eq(self.count == self.limit)
|
||||
|
||||
with m.If(self.en):
|
||||
with m.If(self.ovf):
|
||||
m.d.sync += self.count.eq(0)
|
||||
with m.Else():
|
||||
m.d.sync += self.count.eq(self.count + 1)
|
||||
|
||||
return m
|
||||
# --- TEST ---
|
||||
from nmigen.back.pysim import Simulator
|
||||
|
||||
|
||||
dut = UpCounter(25)
|
||||
def bench():
|
||||
# Disabled counter should not overflow.
|
||||
yield dut.en.eq(0)
|
||||
for _ in range(30):
|
||||
yield
|
||||
assert not (yield dut.ovf)
|
||||
|
||||
# Once enabled, the counter should overflow in 25 cycles.
|
||||
yield dut.en.eq(1)
|
||||
for _ in range(25):
|
||||
yield
|
||||
assert not (yield dut.ovf)
|
||||
yield
|
||||
assert (yield dut.ovf)
|
||||
|
||||
# The overflow should clear in one cycle.
|
||||
yield
|
||||
assert not (yield dut.ovf)
|
||||
|
||||
|
||||
sim = Simulator(dut)
|
||||
sim.add_clock(1e-6) # 1 MHz
|
||||
sim.add_sync_process(bench)
|
||||
with sim.write_vcd("up_counter.vcd"):
|
||||
sim.run()
|
||||
# --- CONVERT ---
|
||||
from nmigen.back import verilog
|
||||
|
||||
|
||||
top = UpCounter(25)
|
||||
with open("up_counter.v", "w") as f:
|
||||
f.write(verilog.convert(top, ports=[top.en, top.ovf]))
|
||||
49
docs/_code/up_counter.v
Normal file
49
docs/_code/up_counter.v
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
(* generator = "nMigen" *)
|
||||
module top(clk, rst, en, ovf);
|
||||
(* src = "<nmigen-root>/nmigen/hdl/ir.py:526" *)
|
||||
input clk;
|
||||
(* src = "<nmigen-root>/nmigen/hdl/ir.py:526" *)
|
||||
input rst;
|
||||
(* src = "up_counter.py:26" *)
|
||||
input en;
|
||||
(* src = "up_counter.py:27" *)
|
||||
output ovf;
|
||||
(* src = "up_counter.py:30" *)
|
||||
reg [15:0] count = 16'h0000;
|
||||
(* src = "up_counter.py:30" *)
|
||||
reg [15:0] \count$next ;
|
||||
(* src = "up_counter.py:35" *)
|
||||
wire \$1 ;
|
||||
(* src = "up_counter.py:41" *)
|
||||
wire [16:0] \$3 ;
|
||||
(* src = "up_counter.py:41" *)
|
||||
wire [16:0] \$4 ;
|
||||
assign \$1 = count == (* src = "up_counter.py:35" *) 5'h19;
|
||||
assign \$4 = count + (* src = "up_counter.py:41" *) 1'h1;
|
||||
always @(posedge clk)
|
||||
count <= \count$next ;
|
||||
always @* begin
|
||||
\count$next = count;
|
||||
(* src = "up_counter.py:37" *)
|
||||
casez (en)
|
||||
/* src = "up_counter.py:37" */
|
||||
1'h1:
|
||||
(* src = "up_counter.py:38" *)
|
||||
casez (ovf)
|
||||
/* src = "up_counter.py:38" */
|
||||
1'h1:
|
||||
\count$next = 16'h0000;
|
||||
/* src = "up_counter.py:40" */
|
||||
default:
|
||||
\count$next = \$3 [15:0];
|
||||
endcase
|
||||
endcase
|
||||
(* src = "<nmigen-root>/nmigen/hdl/xfrm.py:518" *)
|
||||
casez (rst)
|
||||
1'h1:
|
||||
\count$next = 16'h0000;
|
||||
endcase
|
||||
end
|
||||
assign \$3 = \$4 ;
|
||||
assign ovf = \$1 ;
|
||||
endmodule
|
||||
Loading…
Add table
Add a link
Reference in a new issue