C
Christopher Fairbairn
Guest
Hi,
I am just starting out with respect to utilising FPGAs within my designs. Up
to this point in time I've mostly been involved with microcontroller based
designs, but I'm seeing where FPGAs can help solve various types of tasks I
find myself in and hence wanting to learn how to use them properly.
I've brought a small development board and have gradually implemented
various designs for making various beeps and sirens on a speaker, and
decoders such as a binary to 7segment decoder etc etc. I term them "simple"
designs since they are designs that can be "completely wrong" but at the
same time still "work" (i.e. yes it does what I set out to do, but the
design techniques might not be the best, or it wouldn't work if I had a bit
a little more clock slew etc etc...).
I am at the stage where I think I am almost confident enough to design a
FPGA into a hobby project of my own with enough confidence that I'll be
able to develop the right VHDL source to make it "tick"...
To this end I've started attempting to simulate/develop a 68HC11 to Wishbone
interface (the idea being to graft an FPGA onto the databus of an existing
HC11 produt) and I'd like some advice on what I've got so far. Not knowing
much about data busses typically utilised within FPGA designs etc Wishbone
looked like a good idea, especially when sites such as www.opencores.org
appear to support it for their freely available cores.
My VHDL source for a wishbone master which has an HC11 data bus interface on
the other end is shown below. It's a slightly "confused" master, in that
it's not as seperted out as the Wishbone specification details, i.e. it's
got elements of an InterCon and SysCon module thrown in as well... Sorry
about the poor coding standard (the Wishbone/HC11 bus signals are named
using different conventions etc), I just thought I'd "throw it out there"
rather than worrying about tiding it up first...
entity hc11_wb_master is
port (
-- Wishbone bus interface
WB_CLK_O : out std_logic; -- Clock
WB_RST_O : out std_logic; -- Reset
WB_ADR_O : out std_logic_vector(1 downto 0);
WB_DAT_I : in std_logic_vector(7 downto 0);
WB_DAT_O : out std_logic_vector(7 downto 0);
WB_WE_O : out std_logic; -- Write enable
WB_STB_O : out std_logic; -- Strobe
-- HC11 bus interface
e_clk : in std_logic;
reset : in std_logic;
cs : in std_logic; -- chip select for FPGA (HC11's CS2)
rw : in std_logic; -- read/write* strobe
addr : in std_logic_vector(10 downto 0);
data : inout std_logic_vector(7 downto 0);
);
end hc11_wb_master;
architecture Behavioral of hc11_wb_master is
signal write_cycle : std_logic;
begin
WB_CLK_O <= not e_clk; // HC11 clocks on the opposite edge to Wishbone
-- Asserted if the HC11 bus cycle is a memory write
write_cycle = not(rw);
process (e_clk)
begin
if (falling_edge(e_clk)) then
WB_RST_O <= not reset; -- HC11 is active low reset
data <= "ZZZZZZZZ";
if (reset = '0') then
-- Reset condition - hold wishbone bus inactive
WB_STB_O <= '0';
else
-- Translate the various control signals from HC11 to wishbone
WB_WE_O <= write_cycle;
WB_ADR_O <= addr(1 downto 0);
WB_STB_O <= cs;
-- Transfer data in the correct direction...
if (cs = '1') then
if (write_cycle = '1') then
WB_DAT_O <= data;
else
data <= WB_DAT_I;
end if;
end if;
end if;
end if;
end process;
end Behavioral;
Now there are various things that with my present dismal knowledge I am not
sure about. It seems it simulates ok..., I have a testbench where I've
attached it to a UART module from www.opencores.org and I can see in the
resultant simulation a write to the UART and the resultant activity on the
UART's TX pin etc etc...
However I have questions...
For example the line
WB_CLK_O <= not e_clk;
I utilised to invert the polarity of the clock between the two busses. My
idea is to clock the wishbone bus via the HC11's E-clock to keep the
wishbone bus transactions synchronous to the HC11's bus operations (seems
logical to me). The problem is the HC11 reads/writes on the falling edge,
while the wishbone interface does it on the rising edge... But isn't this
inversion I've done inheriently evil or "bad design"?
I have read discussions about the problems of gated clocks causing problems
with respect to routing and propagation delays. Isn't this the same sort of
issue? Everything hanging off the wishbone interface is going to be clocked
via WB_CLK_O which although not "gated", it's going through a minimal
amount of logic from the actual clock signal entering the FPGA. Perhaps
it's not a concern? Perhaps the systhensis tools are smart enough to mean I
don't have to worry about it..
I am also interested with respect to how I've attempted to implement the
tri-stateable interface for the 8bit data port to the HC11's bus. Am I
heading in the right direction in this respect?
Another thing thats going to show how completely clueless I am... is with
respect to setup/hold timing. The logic I've implemented above (to my
knoweldge at least) will latch the wishbone data onto the HC11's databus on
the falling edge of the eclock (assuming the HC11 initiates a read cycle of
course).. but this is also the same time that I'm latching the incomming
address signals and obviously it's not going to have time to propogate
through the logic, cause the wishbone slave to dump the correct data onto
the databus and be latched... What am I doing wrong here, and in what way
would I go about starting to make changes to correct this... I assume the
only reason it's simulated fine so far is that I've done my simulation
before the synthesis stage, and hence there's no "timing/routing" related
info in the simulation. Am I correct in my understanding here?
Now knowing me the code I placed above is completely wrong for this and many
other reasons.. but that is why I would appreciate any advice you could
provide me. I'm doing this exercise purely as a learning exercise so the
more avanues I find for further learning the better
One thing this project has highlighted is the need for me to learn more
about writing better testbenches... I totally agree with the comments I've
seen in this newgroup about newbies starting out with a simulator and no
physical hardware. I sure wish I had started out that way
My aim with this project is to eventually get an HC11 talking to some
perhperials implemented within an FPGA that are wishbone slaves. The
perpherials are rather basic themselfs, mainly boiling down to a couple of
high speed counters at this stage.
Thanks,
Christopher Fairbairn.
PS: Can anyone suggest a good book on Simulation, in particular with
relation to VHDL? I've identified this as an area where I'm particular
weak, and as an area where improvements would make progress a bit smoother.
For example how do you go about reading in stimulius from a file so I don't
have to hardcode in bus transactions in my testbench, and can instead
simply read them in from a file containing "read 0x8000, write 0x7000" or
the equivalent...
I am just starting out with respect to utilising FPGAs within my designs. Up
to this point in time I've mostly been involved with microcontroller based
designs, but I'm seeing where FPGAs can help solve various types of tasks I
find myself in and hence wanting to learn how to use them properly.
I've brought a small development board and have gradually implemented
various designs for making various beeps and sirens on a speaker, and
decoders such as a binary to 7segment decoder etc etc. I term them "simple"
designs since they are designs that can be "completely wrong" but at the
same time still "work" (i.e. yes it does what I set out to do, but the
design techniques might not be the best, or it wouldn't work if I had a bit
a little more clock slew etc etc...).
I am at the stage where I think I am almost confident enough to design a
FPGA into a hobby project of my own with enough confidence that I'll be
able to develop the right VHDL source to make it "tick"...
To this end I've started attempting to simulate/develop a 68HC11 to Wishbone
interface (the idea being to graft an FPGA onto the databus of an existing
HC11 produt) and I'd like some advice on what I've got so far. Not knowing
much about data busses typically utilised within FPGA designs etc Wishbone
looked like a good idea, especially when sites such as www.opencores.org
appear to support it for their freely available cores.
My VHDL source for a wishbone master which has an HC11 data bus interface on
the other end is shown below. It's a slightly "confused" master, in that
it's not as seperted out as the Wishbone specification details, i.e. it's
got elements of an InterCon and SysCon module thrown in as well... Sorry
about the poor coding standard (the Wishbone/HC11 bus signals are named
using different conventions etc), I just thought I'd "throw it out there"
rather than worrying about tiding it up first...
entity hc11_wb_master is
port (
-- Wishbone bus interface
WB_CLK_O : out std_logic; -- Clock
WB_RST_O : out std_logic; -- Reset
WB_ADR_O : out std_logic_vector(1 downto 0);
WB_DAT_I : in std_logic_vector(7 downto 0);
WB_DAT_O : out std_logic_vector(7 downto 0);
WB_WE_O : out std_logic; -- Write enable
WB_STB_O : out std_logic; -- Strobe
-- HC11 bus interface
e_clk : in std_logic;
reset : in std_logic;
cs : in std_logic; -- chip select for FPGA (HC11's CS2)
rw : in std_logic; -- read/write* strobe
addr : in std_logic_vector(10 downto 0);
data : inout std_logic_vector(7 downto 0);
);
end hc11_wb_master;
architecture Behavioral of hc11_wb_master is
signal write_cycle : std_logic;
begin
WB_CLK_O <= not e_clk; // HC11 clocks on the opposite edge to Wishbone
-- Asserted if the HC11 bus cycle is a memory write
write_cycle = not(rw);
process (e_clk)
begin
if (falling_edge(e_clk)) then
WB_RST_O <= not reset; -- HC11 is active low reset
data <= "ZZZZZZZZ";
if (reset = '0') then
-- Reset condition - hold wishbone bus inactive
WB_STB_O <= '0';
else
-- Translate the various control signals from HC11 to wishbone
WB_WE_O <= write_cycle;
WB_ADR_O <= addr(1 downto 0);
WB_STB_O <= cs;
-- Transfer data in the correct direction...
if (cs = '1') then
if (write_cycle = '1') then
WB_DAT_O <= data;
else
data <= WB_DAT_I;
end if;
end if;
end if;
end if;
end process;
end Behavioral;
Now there are various things that with my present dismal knowledge I am not
sure about. It seems it simulates ok..., I have a testbench where I've
attached it to a UART module from www.opencores.org and I can see in the
resultant simulation a write to the UART and the resultant activity on the
UART's TX pin etc etc...
However I have questions...
For example the line
WB_CLK_O <= not e_clk;
I utilised to invert the polarity of the clock between the two busses. My
idea is to clock the wishbone bus via the HC11's E-clock to keep the
wishbone bus transactions synchronous to the HC11's bus operations (seems
logical to me). The problem is the HC11 reads/writes on the falling edge,
while the wishbone interface does it on the rising edge... But isn't this
inversion I've done inheriently evil or "bad design"?
I have read discussions about the problems of gated clocks causing problems
with respect to routing and propagation delays. Isn't this the same sort of
issue? Everything hanging off the wishbone interface is going to be clocked
via WB_CLK_O which although not "gated", it's going through a minimal
amount of logic from the actual clock signal entering the FPGA. Perhaps
it's not a concern? Perhaps the systhensis tools are smart enough to mean I
don't have to worry about it..
I am also interested with respect to how I've attempted to implement the
tri-stateable interface for the 8bit data port to the HC11's bus. Am I
heading in the right direction in this respect?
Another thing thats going to show how completely clueless I am... is with
respect to setup/hold timing. The logic I've implemented above (to my
knoweldge at least) will latch the wishbone data onto the HC11's databus on
the falling edge of the eclock (assuming the HC11 initiates a read cycle of
course).. but this is also the same time that I'm latching the incomming
address signals and obviously it's not going to have time to propogate
through the logic, cause the wishbone slave to dump the correct data onto
the databus and be latched... What am I doing wrong here, and in what way
would I go about starting to make changes to correct this... I assume the
only reason it's simulated fine so far is that I've done my simulation
before the synthesis stage, and hence there's no "timing/routing" related
info in the simulation. Am I correct in my understanding here?
Now knowing me the code I placed above is completely wrong for this and many
other reasons.. but that is why I would appreciate any advice you could
provide me. I'm doing this exercise purely as a learning exercise so the
more avanues I find for further learning the better
One thing this project has highlighted is the need for me to learn more
about writing better testbenches... I totally agree with the comments I've
seen in this newgroup about newbies starting out with a simulator and no
physical hardware. I sure wish I had started out that way
My aim with this project is to eventually get an HC11 talking to some
perhperials implemented within an FPGA that are wishbone slaves. The
perpherials are rather basic themselfs, mainly boiling down to a couple of
high speed counters at this stage.
Thanks,
Christopher Fairbairn.
PS: Can anyone suggest a good book on Simulation, in particular with
relation to VHDL? I've identified this as an area where I'm particular
weak, and as an area where improvements would make progress a bit smoother.
For example how do you go about reading in stimulius from a file so I don't
have to hardcode in bus transactions in my testbench, and can instead
simply read them in from a file containing "read 0x8000, write 0x7000" or
the equivalent...