Sign in

username:

password:



Not a member?

Search fpga-cpu



Search tips

Subscribe to fpga-cpu



fpga-cpu by Keywords

Altera | CISCifying | IDE | ISA | Java | JHDL | JTAG | LBU | MicroBlaze | PAR | PCI | RISC | SoC | Spartan | Transputers | Verilog | VHDL | Virtex | VLIW | WebPack | Xilinx | Xsoc | YARD-1A

Ads

Discussion Groups

Discussion Groups | FPGA-CPU | help: a synchronizer issue...

This list is for discussion of the design and implementation of field-programmable gate array based processors and integrated systems. It is also for discussion and community support of the XSOC Project (see http://www.fpgacpu.org/xsoc).

help: a synchronizer issue... - Umair siddiqui - Sep 4 11:20:00 2005

Please I need your urgent support, related to ACK_I
input of Wishbone bus...

I ve designed a CPU in vhdl (i am trying to release it
with name HPC-16 on OC)
supporting only single write and single read bus
operations. like any other WB master,
it provide slave STB_O and sample the ACK_I on next
rising edge. -Since the WB is completely synchronous, should give
ACK_I directly to control unit of
processor, or pass ACK_I through two stage
synchronizer (2 - cascading DFF). i just require
fucntional correctness...

-suppose if i use synchronizer, and futher suppose for
simple configuration I simply
connect STB_O of processor to ACK_I. now control unit
will recieve the "ack_sync" after
two clk periods (in zero-delay simulation exactly on
2nd clk period, in cpu rtl code i donot
inserted "after <delay-time>").
just like WB master, control unit after getting ACK_I
immediately deassert the STB_O and continue
its work (internal operation or next read/write
operation) and *donot* wait for "ack_sync" = 0

(output from synchronizer). at this point should
control-unit asynchronously reset the

synchronizer as well? and/or should control-unit wait
until "ack_sync" become 0, for next

read/write cycle?
__________________________________________________
">http://mail.yahoo.com





(You need to be a member of fpga-cpu -- send a blank email to fpga-cpu-subscribe@yahoogroups.com )


Re: help: a synchronizer issue... - Martin Schoeberl - Sep 4 13:03:00 2005

> Please I need your urgent support, related to ACK_I
> input of Wishbone bus...
>
> I ve designed a CPU in vhdl (i am trying to release it
> with name HPC-16 on OC)
> supporting only single write and single read bus
> operations. like any other WB master,
> it provide slave STB_O and sample the ACK_I on next
> rising edge. > -Since the WB is completely synchronous, should give
> ACK_I directly to control unit of
> processor, or pass ACK_I through two stage
> synchronizer (2 - cascading DFF). i just require
> fucntional correctness...

the WB bus is used *internal* in the chip, therefore you
don't need synchronizers.
You only need them for external signal or for clock domain
crossing.

Martin




(You need to be a member of fpga-cpu -- send a blank email to fpga-cpu-subscribe@yahoogroups.com )

Re: help: a synchronizer issue... - umairsiddiqui0800 - Sep 6 18:37:00 2005

the bus controling issues
are creating problems. The complete code of cpu along with
documentation is
posted on OpenCores.org as *HPC-16* project. cpu only supports single
read/write cycles. Currently I just simulating the CPU on modelsim,
not tested on cpu. All signal assignments are in zero time, no timing
info in CPU RTL or RAM models. i.e no "after unit_time".
this is my first cpu...please help
////////////////////////////////////////////
--// this code of sync, i tried both archs,
--// first one delays the "ack_sync" arrival
--// second one donot delay the async arrival

entity sync is
port
(
d : in std_logic;
clk : in std_logic;
q : out std_logic
);
end sync;

architecture Behavioral of sync is
signal t : std_logic;
begin
process(clk)
begin
if rising_edge(CLK) then
t <= d;
q <= t;
end if;
end process;
end Behavioral;

architecture behave2 of sync is
signal t : std_logic;
begin
process(clk , d)
begin
if d = '1' then
t <= '1';
q <= '1';
elsif rising_edge(clk) then
t <= '0';
q <= t;
end if;
end process;
end behave2;

/////////////////////////////////////
--// control unit code fragments to
--// highlight suspicious code related to
--// bus controlling

entity con1 is
port(
CLK_I : in std_logic;
RST_I : in std_logic;
ACK_I : in std_logic;
SEL_O : out std_logic_vector(1 downto 0);
STB_O : out std_logic;
CYC_O : out std_logic;
WE_O : out std_logic;
ir_high : in std_logic_vector(7 downto 0);
...
-- ***************************************** --
-- ** DAT_IO (not separate DAT_I & DAT_O) ** --
-- ** and ADR_O are ports of datapath ** --
-- ***************************************** --
-- ** may be DAT_IO is creating all evil! ** --
-- ***************************************** --
);
end con1;
architecture rtl of con1 is
signal rst_sync : std_logic;
signal ack_sync : std_logic;
signal intr_sync : std_logic;
signal cur_state , nxt_state : state;
signal cur_ic : ic;
...
begin
rsync : sync
port map
(
d => RST_I, clk => CLK_I, q => rst_sync
);

async : sync
port map
(
d => ACK_I, clk => CLK_I, q => ack_sync
);
--////////////////////////////////////////////////////////
-- combinational predecoding
decode:
cur_ic <= ic_mov_rn_rm when ir_high = mov_rn_rm else
ic_mov_sp_rm when ir_high = mov_sp_rm else
ic_mov_rn_sp when ir_high = mov_rn_sp else
ic_ld_rn_rb when ir_high = ld_rn_rb else
ic_ld_rn_rb_disp when ir_high = ld_rn_rb_disp else
...
ic_hlt when ir_high(7 downto 3) = hlt else
ic_invalid;
--/////////////////////////////////////////////////////////////
-- main fsm-------------
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
cur_state <= reset;
elsif rising_edge(CLK_I) then
cur_state <= nxt_state;
end if;
end process; process(cur_state, cur_ic, ir_high(2 downto 0), ack_sync, rst_sync,
<other signals>)
begin
-- defualt assigns to avoid latch
SEL_O <= "00"; STB_O <= '0'; CYC_O <= '0'; WE_O <= '0'; <other
asigns>
-- ****************************************************
-- ** note: no default assign for "nxt_state"
-- ** should i add: "nxt_state <= reset"
-- ****************************************************
--//////////////////////////////////////
case cur_state is
--//////////////////////////////////////
when reset =>
-- generate control signals to reset the Program Counter
(pc) and FLAGS
if rst_sync = '0' then
nxt_state <= fetch0;
else
nxt_state <= reset;
end if;
--//////////////////////////////////////
when fetch0 =>
-- assign pc contents to memory address reg(connected to
address bus): mar <= pc
-- increament pc by two: pc <= pc + 2
nxt_state <= fetch1;
--///////////////////////////////////////
when fetch1 =>
-- start instruction fetch cycle
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1';
-- prepare instruction register (ir) for instruction
loading
ir_ce <= '1';
nxt_state <= fetch2;
--///////////////////////////////////////
when fetch2 =>
if ack_sync = '1' then
--
********************************************************* --
-- ** instruction register should be loaded at this
point ** --
-- ** otherwise control unit should stay in this state.
** --
-- ** this another reason for adding *sync* to ack_i
** --
-- ** (no need to add wait state circuit for SPARTAN 3
** --
-- ** BRAMS)
** --
-- ** ?? is this a clean way ??
** --
--
********************************************************* --
-- ** any way stop the bus cycle, since we have
recieved ** --
-- ** the *ack_sync*
** --
--
********************************************************* --
-- ** another issue:
** --
-- ** in a "zero delay simulation", if stb_o controls
the ** --
-- ** controls the chip-select of RAM, the "cs" of ram
** --
-- ** will be deasserted, resulting in immediate high-z
on** --
-- ** data bus, in fact my whole simulation start
running ** --
-- ** in delta time, if i remove the sync from ack_i!
** --
--
********************************************************* --
-- ** note: for any read or write cycle, the cpu
** --
-- ** *does not wait* for ack_sync to become deasserted
** --
-- ** so in simulation, ack_sync generated for fetch2
** --
-- ** is falsely reused for exec2.
** --
-- ** this would be obvious if use first arch of sync,
** --
-- ** in second arch you will observe a glitch at this
** --
-- ** time.
** --
--
********************************************************* --
nxt_state <= exec0;
else
-- continue instruction fetch & prepare ir and stay in
this state
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; I_CYC_O <=
'1';
ir_ce <= '1';
nxt_state <= fetch2;
end if;
--///////////////////////////////////////
-- ** execution phase 0** --
when exec0 =>
-- ** based on current instruction type! ** --
case cur_ic is
-- **************************************** --
-- ** several types of instructions, ** --
-- ** please consider *int* and *iret* ** --
-- ** interrupt call and return ** --
-- **************************************** --
-- ** interrupt call: int <4-bit integer>** --
-- ** FLAGS and then PC ** --
-- ** are pushed into stack, then PC ** --
-- ** is assigned {vector no. x 8} ** --
-- **************************************** --
-- ** interrupt ret: iret ** --
-- ** memory words are poped into PC and ** --
-- ** then into FLAGS ** --
-- **************************************** --
when ic_int =>
-- stack pointer is decrmented by two : sp = old sp
- 2
-- mar is also assigned with this new value: mar =
old sp - 2
-- "mem data reg for output" (mdro) which is
connected to data bus
-- is assigned zero extended FLAGS: mdro = flags
nxt_state <= exec1;
----------------------------------------
when ic_iret =>
-- increament the sp by two: sp = old sp + 2
-- but assign mar old value: mar = old sp
nxt_state <= exec1;
----------------------------------------
-- other instruction types
----------------------------------------
when ic_invalid =>
-- handle invalid instructions by throwing exception
-- separate "state chain" to handle the issue
nxt_state <= invalid0;
----------------------------------------------

end case;
--///////////////////////////////////////
-- ** execution phase 1** --
when exec1 =>
case cur_ic is
----------------------------------------------
when ic_iret =>
-- read data word (PC)
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1';
-- prepare "mem data reg for input" (mdri) for data
loading
mdri_ce <= '1';
--
nxt_state <= exec2;
----------------------------------------------
when ic_int =>
-- assert the tri state control
mdro_oe <= '1';
-- write data word (FLAGS)
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <=
'1';
--
nxt_state <= exec2;
----------------------------------------------
-- other instruction types
----------------------------------------------
-- ***************************************** --
when others =>
null;
-- ***************************************** --
end case;
--///////////////////////////////////////
-- ** execution phase 2** --
when exec2 =>
case cur_ic is
when ic_int =>
if ack_sync = '1' then
-- *****************************************
-- ** now we can start another bus cycle:
-- ** prepare to push PC
-- *****************************************
-- mar = old sp -2
-- sp = old sp - 2
-- mdro = pc
nxt_state <= exec3;
else
--*****************************************
--** otherwise FLAGS may not be written
--** continue the write cycle and stay in this
state
--*****************************************
mdro_oe <= '1';
-- try writing data word
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O
<= '1';
--
nxt_state <= exec2;
end if;
-----------------------------------------
when ic_iret =>
if ack_sync = '1' then
-- ****************************************
-- ** mdri might be loaded with mem word,
-- ** copy it to pc, prepare for another
-- ** pop
-- ****************************************
-- pc = mdri
-- sp = old sp + 2
-- mar = old sp
--
nxt_state <= exec3;
else
-- continue reading data word
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
-- other instruction type
--------------------------------------------
when others =>
null;
-------------------------------------------
--///////////////////////////////////////
when exec3 =>
case cur_ic is
when ic_int =>
mdro_oe <= '1';
-- start writting PC (write bus cycle)
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <=
'1';
--
nxt_state <= exec4;
----------------------------------------------
when ic_iret =>
mdri_ce <= '1';
-- try reading FLAGS (read bus cycle)
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1';
--
nxt_state <= exec4;
----------------------------------------------
when others =>
null;
----------------------------------------------
end case;
--///////////////////////////////////////
when exec4 =>
case cur_ic is
----------------------------------------------
when ic_int =>
if ack_sync = '1' then
-- pc = ext(ir(3..0)) * 8
-- execution complete, poll the interrupt pin
nxt_state <= int_chk;
else
mdro_oe <= '1';
-- continue writting PC
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O
<= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_iret =>
if ack_sync = '1' then
-- flags = mdri
--
nxt_state <= int_chk;
else
mdri_ce <= '1';
-- try reading FLAGS
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when others =>
null;
----------------------------------------------

end case;
--//////////////////////////////////////
-- rest of states
--/////////////////////////////////////
end case;
end process;
end rtl;
//////////////////////////////////////////////////////////////////////
/////////////////////




(You need to be a member of fpga-cpu -- send a blank email to fpga-cpu-subscribe@yahoogroups.com )

help req with cpu simulation... - umairsiddiqui0800 - Sep 29 18:03:00 2005

Kindly help with this simulation issue...............
in "test2.vhd", the testbench for this simulation
contain only ram (ramNx16.vhd) and cpu.

(for code and documentation:
http://www.opencores.org/projects.cgi/web/hpc-16) i converted the program given below in binary

################################
## this program test:
## mov, li and hlt instructions
################################
0:li r0, 5555h
4:mov r1, r0
6:mov sp, r1
8:mov r5, sp
10:hlt
##############################

all instructions are executed correctly in simulation... since there is no need for wait states, i'have just connected the
the cpu "stb_o" port to cpu "ack_i"... in figure

http://www.geocities.com/umairsiddiqui0800/my_pics/hpc-
16_sim_problem.jpg

consider the signal
"/test2/cpu/control/rst_i"
"/test2/cpu/control/rst_sync"
"/test2/cpu/control/ack_i"
"/test2/cpu/control/ack_sync"

i'm usng same synchronizer, for both input...
but you can see that "ack_sync" is 2 clk late than
and "rst_sync" is 1 clk late...

also
you can see the glich in "ack_sync"...

how this thing can be corrected???

please help with this issue...




(You need to be a member of fpga-cpu -- send a blank email to fpga-cpu-subscribe@yahoogroups.com )