Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #
- # This file is part of LiteX.
- #
- # Copyright (c) 2021 Romain Dolbeau <[email protected]>
- #module ps2_host(
- # input wire sys_clk,
- # input wire sys_rst,
- # inout wire ps2_clk,
- # inout wire ps2_data,
- #
- # input wire [7:0] tx_data,
- # input wire send_req,
- # output wire busy,
- #
- # output wire [7:0] rx_data,
- # output wire ready,
- # output wire error
- #);
- #module ps2interface(
- # clk,
- # rst,
- # ps2_clk,
- # ps2_data,
- # tx_data,
- # write,
- # rx_data,
- # read,
- # busy,
- # err
- #);
- # input clk;
- # input rst;
- # inout ps2_clk;
- # inout ps2_data;
- # input [7:0] tx_data;
- # input write;
- # output [7:0] rx_data;
- # output read;
- # output busy;
- # output err;
- import os
- #from os import path
- from migen import *
- from migen.genlib.fifo import SyncFIFOBuffered
- from litex.soc.interconnect.csr import *
- from litex.soc.interconnect.csr_eventmanager import *
- def _to_signal(obj):
- return obj.raw_bits() if isinstance(obj, Record) else obj
- class PS2HostWrapper(Module, AutoCSR):
- def __init__(self, platform, pads, sys_clk_freq = 100e6, digilent=False):
- self.platform = platform
- if (not digilent):
- self.module_name = "ps2_host"
- else:
- self.module_name = "ps2interface"
- #pads = _to_signal(pads)
- tx_data_i = Signal(8)
- send_req_i = Signal()
- busy_o = Signal()
- rx_data_o = Signal(8)
- ready_o = Signal()
- error_o = Signal()
- # is there a way to pass 'define SYS_CLOCK_HZ $sys_clk_freq' to Verilog?
- # default 100e6 so fine
- # data -> 0-7: data; 31: valid
- self.rx_data = CSRStorage(size = 32, reset = 0, write_from_dev=True)
- # data -> 0-7: data; 31: valid
- self.tx_data = CSRStorage(size = 32, reset = 0, write_from_dev=True)
- # ctrl -> 0: interrupt enable, 1: reset, 31 -> interrupt
- self.ctrl = CSRStorage(size = 32, reset = 0, write_from_dev=True)
- in_ctrl_1_n_d = Signal()
- self.comb += in_ctrl_1_n_d.eq(~self.ctrl.storage[1:2])
- if (not digilent):
- self.module_params = dict(
- i_sys_clk = ClockSignal("sys"),
- i_sys_rst = in_ctrl_1_n_d,
- io_ps2_clk = pads.ps2_clk,
- io_ps2_data = pads.ps2_data,
- i_tx_data = tx_data_i,
- i_send_req = send_req_i,
- o_busy = busy_o,
- o_rx_data = rx_data_o,
- o_ready = ready_o,
- o_error = error_o
- )
- else:
- self.module_params = dict(
- i_clk = ClockSignal("sys"),
- i_rst = in_ctrl_1_n_d,
- io_ps2_clk = pads.ps2_clk,
- io_ps2_data = pads.ps2_data,
- i_tx_data = tx_data_i,
- i_write = send_req_i,
- o_rx_data = rx_data_o,
- o_read = ready_o,
- o_busy = busy_o,
- o_err = error_o
- )
- self.submodules.rx_fifo = rx_fifo = SyncFIFOBuffered(width=8, depth=32) ## no fill control
- self.comb += rx_fifo.din.eq(rx_data_o)
- self.comb += rx_fifo.we.eq(ready_o)
- self.submodules.fsm = fsm = FSM(reset_state="IDLE")
- fsm.act("IDLE",
- self.rx_data.we.eq(0),
- self.tx_data.we.eq(0),
- self.ctrl.we.eq(0),
- rx_fifo.re.eq(0),
- send_req_i.eq(0),
- NextState("RESETKBD"))
- fsm.act("RESETKBD",
- self.rx_data.dat_w.eq(0xDEADBEEF), # recognizable value
- self.rx_data.we.eq(1),
- self.ctrl.dat_w.eq(0x00000002), # stop reset to verilog block
- self.ctrl.we.eq(1),
- tx_data_i.eq(0xFF), # send reset to KBD
- send_req_i.eq(1),
- NextState("RUN"))
- fsm.act("RUN",
- self.rx_data.we.eq(0),
- self.tx_data.we.eq(0),
- self.ctrl.we.eq(0),
- rx_fifo.re.eq(0),
- send_req_i.eq(0),
- If(rx_fifo.readable & ~self.ctrl.storage[31:32],
- self.rx_data.dat_w.eq(0x80000000 | rx_fifo.dout),
- self.rx_data.we.eq(1),
- self.ctrl.dat_w.eq(0x80000003), # must keep irq & !reset
- self.ctrl.we.eq(1),
- rx_fifo.re.eq(1)),
- If(~rx_fifo.readable & ~self.ctrl.storage[31:32],
- self.rx_data.dat_w.eq(0),
- self.rx_data.we.eq(1)
- ),
- If(self.tx_data.storage[31:32] & ~busy_o,
- tx_data_i.eq(self.tx_data.storage[0:8]),
- send_req_i.eq(1),
- self.tx_data.dat_w.eq(0),
- self.tx_data.we.eq(1)))
- ## irq
- self.submodules.ev = EventManager()
- in_ctrl_31_d = Signal()
- in_ctrl_0_d = Signal()
- self.comb += in_ctrl_31_d.eq(self.ctrl.storage[31:32])
- self.comb += in_ctrl_0_d.eq(self.ctrl.storage[0:1])
- #self.ev.keyev = EventSourceProcess(description="Key Event", edge="rising")
- self.ev.keyev = EventSourceLevel(description="Key Event")
- self.ev.finalize()
- self.comb += self.ev.keyev.trigger.eq(in_ctrl_31_d & in_ctrl_0_d)
- # instantiate verilog module
- self.specials += Instance(self.module_name, **self.module_params)
- # Add verilog sources
- self.add_sources(platform = self.platform, digilent = digilent)
- def add_sources(self, platform, digilent):
- if (not digilent):
- platform.add_source(os.path.join("/home/dolbeau/ps2_host_controller/trunk/hdl/ps2_host_clk_ctrl.v"), "verilog")
- platform.add_source(os.path.join("/home/dolbeau/ps2_host_controller/trunk/hdl/ps2_host_defines.v"), "verilog")
- platform.add_source(os.path.join("/home/dolbeau/ps2_host_controller/trunk/hdl/ps2_host_rx.v"), "verilog")
- #platform.add_source(os.path.join("/home/dolbeau/ps2_host_controller/trunk/hdl/ps2_host_testbench.v"), "verilog")
- platform.add_source(os.path.join("/home/dolbeau/ps2_host_controller/trunk/hdl/ps2_host_tx.v"), "verilog")
- platform.add_source(os.path.join("/home/dolbeau/ps2_host_controller/trunk/hdl/ps2_host.v"), "verilog")
- platform.add_source(os.path.join("/home/dolbeau/ps2_host_controller/trunk/hdl/ps2_host_watchdog.v"), "verilog")
- #platform.add_source(os.path.join("/home/dolbeau/ps2_host_controller/trunk/hdl/timescale.v"), "verilog")
- else:
- platform.add_source(os.path.join("/home/dolbeau/PmodPS2_Demo/ps2interface.v"), "verilog")
- # def do_finalize(self):
- # self.specials += Instance(self.module_name, **self.module_params)
- # self.add_sources(self.platform)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement