Skip to content

Instantly share code, notes, and snippets.

@cr1901
Last active September 21, 2015 00:54
Show Gist options
  • Save cr1901/5ed5bd1abb4108b5b74b to your computer and use it in GitHub Desktop.
Save cr1901/5ed5bd1abb4108b5b74b to your computer and use it in GitHub Desktop.
Clock Divider with Minimal Resource Usage
from migen import *
from migen.fhdl import verilog
class BaudGen(Module):
def __init__(self):
self.divider = Signal(16)
self.half_period_cnt = Signal(16)
self.next_cnt = Signal(16)
self.out = Signal(1)
# self.comb += [self.half_period_cnt[0:15].eq(self.divider[1:])]
self.comb += [self.next_cnt.eq(self.half_period_cnt - 1)]
self.comb += [self.out.eq(self.next_cnt[15])]
self.sync += [
# If the next cycle causes a change in sign...
If(self.half_period_cnt[15] ^ self.out,
# If next cycle is positive, ignore whether divider is odd.
# Else, check for odd divider and adjust period accordingly
If(self.out, self.half_period_cnt[0:15].eq(self.divider[1:] - 1)).
Else(self.half_period_cnt[0:15].eq(self.divider[1:] - 1
- self.divider[0]))).
Else(self.half_period_cnt.eq(self.next_cnt))]
if __name__ == "__main__":
with open("verilog_out/serial.v", "w") as fp:
m = BaudGen()
fp.write(str(verilog.convert(m, ios={m.divider, m.out})))
/* Machine-generated using Migen */
module top(
input [15:0] divider,
output out,
input sys_clk,
input sys_rst
);
reg [15:0] half_period_cnt = 1'd0;
wire [15:0] next_cnt;
// synthesis translate_off
reg dummy_s;
initial dummy_s <= 1'd0;
// synthesis translate_on
assign next_cnt = (half_period_cnt - 1'd1);
assign out = next_cnt[15];
always @(posedge sys_clk) begin
if (sys_rst) begin
half_period_cnt <= 1'd0;
end else begin
if ((half_period_cnt[15] ^ out)) begin
if (out) begin
half_period_cnt[14:0] <= (divider[15:1] - 1'd1);
end else begin
half_period_cnt[14:0] <= ((divider[15:1] - 1'd1) - divider[0]);
end
end else begin
half_period_cnt <= next_cnt;
end
end
end
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment