A frequently asked question is how to implement a tri-state. Tri-states
are not commonly implemented in the main digital logic but can be used
on external interfaces. For more information, description, and
background please review the following:
[1] http://www.myhdl.org/doku.php/meps:mep-103
[2] http://www.myhdl.org/doku.php/meps:mep-105
[3] http://www.myhdl.org/doc/current/whatsnew/0.7.html#shadow-signals
I gave a shot at creating a tri-state example, everything generated as
expected *BUT* for this example the bi-dir signal was not defined as an
inout in the Verilog? It was defined as an inout in the VHDL.
~~~~[Code Example]~~~~
from myhdl import *
def top(sda, scl, sda_i, sda_o, scl_i, scl_o):
"""Simple I2C bi-dir converter.
This example will break the I2C bi-directional signals into
uni-dir explicit signals.
"""
sda_d = sda.driver()
scl_d = scl.driver()
@always_comb
def hdl():
sda_i.next = sda
sda_d.next = False if not sda_o else None
scl_i.next = scl
scl_d.next = False if not scl_o else None
return hdl
def convert():
clk = Signal(False)
rst = Signal(False)
sda = TristateSignal(True)
scl = TristateSignal(True)
sda_i = Signal(False)
sda_o = Signal(False)
scl_i = Signal(False)
scl_o = Signal(False)
toVerilog(top, sda, scl, sda_i, sda_o, scl_i, scl_o)
toVHDL(top, sda, scl, sda_i, sda_o, scl_i, scl_o)
if __name__ == '__main__':
convert()
~~~~[End Code Example]~~~~
Regards,
Chris
Here are the converted files
~~~~[top.vhd]~~~~
-- File: top.vhd
-- Generated by MyHDL 0.8dev
-- Date: Wed Mar 21 08:25:04 2012
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use std.textio.all;
use work.pck_myhdl_08dev.all;
entity top is
port (
sda: inout std_logic;
scl: inout std_logic;
sda_i: out std_logic;
sda_o: in std_logic;
scl_i: out std_logic;
scl_o: in std_logic
);
end entity top;
-- Simple I2C bi-dir converter.
-- This example will break the I2C bi-directional signals into
-- uni-dir explicit signals. Useful for driving I2C buses.
architecture MyHDL of top is
signal scl_d: std_logic;
signal sda_d: std_logic;
begin
scl <= None;
scl <= scl_d;
sda <= None;
sda <= sda_d;
sda_i <= sda;
sda_d <= '0' when (not to_boolean(sda_o)) else to_std_logic((others =>
'Z'));
scl_i <= scl;
scl_d <= '0' when (not to_boolean(scl_o)) else to_std_logic((others =>
'Z'));
end architecture MyHDL;
~~~~[top.v]~~~~
// File: top.v
// Generated by MyHDL 0.8dev
// Date: Wed Mar 21 08:25:04 2012
`timescale 1ns/10ps
module top (
sda,
scl,
sda_i,
sda_o,
scl_i,
scl_o
);
// Simple I2C bi-dir converter.
// This example will break the I2C bi-directional signals into
// uni-dir explicit signals. Useful for driving I2C buses.
output sda;
wire sda;
output scl;
wire scl;
output sda_i;
wire sda_i;
input sda_o;
output scl_i;
wire scl_i;
input scl_o;
wire scl_d;
wire sda_d;
assign scl = scl_d;
assign sda = sda_d;
assign sda_i = sda;
assign sda_d = (!sda_o) ? 1'b0 : 'bz;
assign scl_i = scl;
assign scl_d = (!scl_o) ? 1'b0 : 'bz;
endmodule
|