mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
Proper reset generation
This commit is contained in:
parent
738b45dcbd
commit
411e1af980
6 changed files with 103 additions and 11 deletions
1
build.py
1
build.py
|
@ -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",
|
||||||
|
|
|
@ -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
|
||||||
|
|
23
milkymist/m1reset/__init__.py
Normal file
23
milkymist/m1reset/__init__.py
Normal 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})
|
|
@ -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
13
top.py
|
@ -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
62
verilog/m1reset/m1reset.v
Normal 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
|
Loading…
Reference in a new issue