Proper reset generation

This commit is contained in:
Sebastien Bourdeauducq 2011-12-16 22:25:26 +01:00
parent 738b45dcbd
commit 411e1af980
6 changed files with 103 additions and 11 deletions

View file

@ -10,6 +10,7 @@ def add_core_dir(d):
def add_core_files(d, files): def add_core_files(d, files):
for f in files: for f in files:
verilog_sources.append(os.path.join("verilog", d, f)) verilog_sources.append(os.path.join("verilog", d, f))
add_core_dir("m1reset")
add_core_files("lm32", ["lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v", add_core_files("lm32", ["lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v",
"lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v", "lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v",
"lm32_shifter.v", "lm32_multiplier_spartan6.v", "lm32_mc_arithmetic.v", "lm32_shifter.v", "lm32_multiplier_spartan6.v", "lm32_mc_arithmetic.v",

View file

@ -1,4 +1,4 @@
def get(ns, norflash0, uart0): def get(ns, reset0, norflash0, uart0):
constraints = [] constraints = []
def add(signal, pin, vec=-1, iostandard="LVCMOS33", extra=""): def add(signal, pin, vec=-1, iostandard="LVCMOS33", extra=""):
constraints.append((ns.get_name(signal), vec, pin, iostandard, extra)) constraints.append((ns.get_name(signal), vec, pin, iostandard, extra))
@ -8,6 +8,11 @@ def get(ns, norflash0, uart0):
add(signal, p, i, iostandard, extra) add(signal, p, i, iostandard, extra)
i += 1 i += 1
add(reset0.trigger_reset, "AA4")
add(reset0.ac97_rst_n, "D6")
add(reset0.videoin_rst_n, "W17")
add(reset0.flash_rst_n, "P22", extra="SLEW = FAST | DRIVE = 8")
add_vec(norflash0.adr, ["L22", "L20", "K22", "K21", "J19", "H20", "F22", add_vec(norflash0.adr, ["L22", "L20", "K22", "K21", "J19", "H20", "F22",
"F21", "K17", "J17", "E22", "E20", "H18", "H19", "F20", "F21", "K17", "J17", "E22", "E20", "H18", "H19", "F20",
"G19", "C22", "C20", "D22", "D21", "F19", "F18", "D20", "D19"], "G19", "C22", "C20", "D22", "D21", "F19", "F18", "D20", "D19"],
@ -18,7 +23,6 @@ def get(ns, norflash0, uart0):
add(norflash0.oe_n, "M22", extra="SLEW = FAST | DRIVE = 8") add(norflash0.oe_n, "M22", extra="SLEW = FAST | DRIVE = 8")
add(norflash0.we_n, "N20", extra="SLEW = FAST | DRIVE = 8") add(norflash0.we_n, "N20", extra="SLEW = FAST | DRIVE = 8")
add(norflash0.ce_n, "M21", extra="SLEW = FAST | DRIVE = 8") add(norflash0.ce_n, "M21", extra="SLEW = FAST | DRIVE = 8")
add(norflash0.rst_n, "P22", extra="SLEW = FAST | DRIVE = 8")
add(uart0.tx, "L17", extra="SLEW = SLOW") add(uart0.tx, "L17", extra="SLEW = SLOW")
add(uart0.rx, "K18", extra="PULLUP") add(uart0.rx, "K18", extra="PULLUP")
@ -38,8 +42,6 @@ def get(ns, norflash0, uart0):
NET "sys_clk" LOC = AB11 | IOSTANDARD = LVCMOS33; NET "sys_clk" LOC = AB11 | IOSTANDARD = LVCMOS33;
NET "sys_clk" TNM_NET = "GRPclk50"; NET "sys_clk" TNM_NET = "GRPclk50";
TIMESPEC "TSclk50" = PERIOD "GRPclk50" 20 ns HIGH 50%; TIMESPEC "TSclk50" = PERIOD "GRPclk50" 20 ns HIGH 50%;
NET "sys_rst" LOC = AA4 | IOSTANDARD = LVCMOS33;
""" """
return r return r

View file

@ -0,0 +1,23 @@
from functools import partial
from migen.fhdl.structure import *
class Inst:
def __init__(self):
d = partial(declare_signal, self)
d("trigger_reset")
d("sys_rst")
d("ac97_rst_n")
d("videoin_rst_n")
d("flash_rst_n")
self._inst = Instance("m1reset",
[("sys_rst", self.sys_rst),
("ac97_rst_n", self.ac97_rst_n),
("videoin_rst_n", self.videoin_rst_n),
("flash_rst_n", self.flash_rst_n)],
[("trigger_reset", self.trigger_reset)],
clkport="sys_clk")
def get_fragment(self):
return Fragment(instances=[self._inst],
pads={self.ac97_rst_n, self.videoin_rst_n, self.flash_rst_n})

View file

@ -13,7 +13,6 @@ class Inst:
d("oe_n") d("oe_n")
d("we_n") d("we_n")
d("ce_n") d("ce_n")
d("rst_n")
self.timeline = timeline.Inst(self.bus.cyc_i & self.bus.stb_i, self.timeline = timeline.Inst(self.bus.cyc_i & self.bus.stb_i,
[(0, [self.adr.eq(Cat(0, self.bus.adr_i[2:adr_width]))]), [(0, [self.adr.eq(Cat(0, self.bus.adr_i[2:adr_width]))]),
(rd_timing, [ (rd_timing, [
@ -27,6 +26,6 @@ class Inst:
def get_fragment(self): def get_fragment(self):
comb = [self.oe_n.eq(0), self.we_n.eq(1), comb = [self.oe_n.eq(0), self.we_n.eq(1),
self.ce_n.eq(0), self.rst_n.eq(1)] self.ce_n.eq(0)]
return Fragment(comb, pads={self.adr, self.d, self.oe_n, self.we_n, self.ce_n, self.rst_n}) \ return Fragment(comb, pads={self.adr, self.d, self.oe_n, self.we_n, self.ce_n}) \
+ self.timeline.get_fragment() + self.timeline.get_fragment()

13
top.py
View file

@ -1,10 +1,13 @@
from migen.fhdl.structure import *
from migen.fhdl import convtools, verilog, autofragment from migen.fhdl import convtools, verilog, autofragment
from migen.bus import wishbone, csr, wishbone2csr from migen.bus import wishbone, csr, wishbone2csr
from milkymist import lm32, norflash, uart from milkymist import m1reset, lm32, norflash, uart
import constraints import constraints
def get(): def get():
reset0 = m1reset.Inst()
cpu0 = lm32.Inst() cpu0 = lm32.Inst()
norflash0 = norflash.Inst(25, 12) norflash0 = norflash.Inst(25, 12)
wishbone2csr0 = wishbone2csr.Inst() wishbone2csr0 = wishbone2csr.Inst()
@ -16,8 +19,10 @@ def get():
uart0 = uart.Inst(0, 50*1000*1000, baud=115200) uart0 = uart.Inst(0, 50*1000*1000, baud=115200)
csrcon0 = csr.Interconnect(wishbone2csr0.csr, [uart0.bus]) csrcon0 = csr.Interconnect(wishbone2csr0.csr, [uart0.bus])
frag = autofragment.from_local() frag = autofragment.from_local() + Fragment(pads={reset0.trigger_reset})
vns = convtools.Namespace() vns = convtools.Namespace()
src_verilog = verilog.Convert(frag, name="soc", ns=vns) src_verilog = verilog.Convert(frag, name="soc",
src_ucf = constraints.get(vns, norflash0, uart0) rst_signal=reset0.sys_rst,
ns=vns)
src_ucf = constraints.get(vns, reset0, norflash0, uart0)
return (src_verilog, src_ucf) return (src_verilog, src_ucf)

62
verilog/m1reset/m1reset.v Normal file
View file

@ -0,0 +1,62 @@
/*
* Milkymist-NG SoC
* Copyright (C) 2007, 2008, 2009, 2010, 2011 Sebastien Bourdeauducq
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
module m1reset(
input sys_clk,
input trigger_reset,
output reg sys_rst,
output ac97_rst_n,
output videoin_rst_n,
output flash_rst_n
);
reg [19:0] rst_debounce;
initial rst_debounce <= 20'hFFFFF;
initial sys_rst <= 1'b1;
always @(posedge sys_clk) begin
if(trigger_reset)
rst_debounce <= 20'hFFFFF;
else if(rst_debounce != 20'd0)
rst_debounce <= rst_debounce - 20'd1;
sys_rst <= rst_debounce != 20'd0;
end
assign ac97_rst_n = ~sys_rst;
assign videoin_rst_n = ~sys_rst;
/*
* We must release the Flash reset before the system reset
* because the Flash needs some time to come out of reset
* and the CPU begins fetching instructions from it
* as soon as the system reset is released.
* From datasheet, minimum reset pulse width is 100ns
* and reset-to-read time is 150ns.
*/
reg [7:0] flash_rstcounter;
initial flash_rstcounter <= 8'd0;
always @(posedge sys_clk) begin
if(trigger_reset)
flash_rstcounter <= 8'd0;
else if(~flash_rstcounter[7])
flash_rstcounter <= flash_rstcounter + 8'd1;
end
assign flash_rst_n = flash_rstcounter[7];
endmodule