OpenCores
URL https://opencores.org/ocsvn/microprocessor/microprocessor/trunk

Subversion Repositories microprocessor

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/trunk/bench/VHDL/ALU.vhd
0,0 → 1,86
-------------------------------------------------------------------------------
-- ALU
-- 12 opcodes
--
-------------------------------------------------------------------------------
 
library IEEE;
 
use IEEE.STD_LOGIC_1164.all;
 
entity FA_8bits is
port (
clk : in std_logic ;
selec : in std_logic_vector (3 downto 0);
FA_in1 : in std_logic_vector (7 downto 0);
FA_in2 : in std_logic_vector (7 downto 0);
FA_out : out std_logic_vector (7 downto 0);
carry : out std_logic ;
overf : out std_logic
);
end FA_8bits ;
 
architecture archi_FA_8bits of FA_8bits is
 
signal cc_FA : std_logic_vector (8 downto 0);
signal out2FA1 : std_logic_vector (7 downto 0);
signal out2FA2 : std_logic_vector (7 downto 0);
signal ck : std_logic_vector (7 downto 0);
signal c0 : std_logic ;
 
 
component FA -- Full adder
port (
x,y,cin,clk : in std_logic ;
s,cout : out std_logic
);
end component ;
 
component selec1 -- select logic unit
port (
a1,b1 : in std_logic ;
selec : in std_logic_vector (3 downto 0);
s1: out std_logic
) ;
end component ;
 
component selec2 -- select arithmitic unit
port (
b1 : in std_logic ;
selec : in std_logic_vector (3 downto 0);
s2: out std_logic
);
end component ;
 
begin
carry_unit : entity work.selec3(archi_selec3)
port map (selec,c0);
cc_FA(0) <= c0;
 
 
Logic_unit :for k in 7 downto 0 generate
 
FA_8bits : selec1 port map (FA_in1(k),FA_in2(k),selec,out2FA1(k));
end generate Logic_unit ;
 
Arith_unit :for k in 7 downto 0 generate
 
FA_8bits : selec2 port map (FA_in2(k),selec,out2FA2(k));
end generate Arith_unit ;
 
 
FullA_unit :for k in 7 downto 0 generate
 
FA_8bits : fa port map (out2FA1(k),out2FA2(k),cc_FA(k),ck(k),FA_out(k),cc_FA(k+1)); -- les blocs d'additionaire complet
ck(k)<=clk ;
end generate FullA_unit ;
 
carry<=cc_FA(8);
overf<=cc_FA(7) xor cc_FA(8);
 
end archi_FA_8bits ;
/trunk/bench/VHDL/Adress.vhd
0,0 → 1,94
-------------------------------------------------------------------------------
-- Adress Unit
--
--
-------------------------------------------------------------------------------
 
library IEEE;
 
use IEEE.STD_LOGIC_1164.all;
 
entity adress_data is
port(
ctrl_adress : in std_logic_vector (1 downto 0);
adress_8 : in std_logic_vector (7 downto 0);
adress_16 : out std_logic_vector (15 downto 0)
);
end adress_data ;
 
architecture archi_adress_data of adress_data is
signal s_adress_16 : std_logic_vector (15 downto 0);
 
begin
process (ctrl_adress,adress_8)
begin
case ctrl_adress is
when "10"=>
s_adress_16(7 downto 0)<= adress_8 ;
when "01"=>
s_adress_16(15 downto 8)<= adress_8 ;
when "11"=>
adress_16 <= s_adress_16 ;
when others =>
end case ;
end process ;
end archi_adress_data ;
 
--------------------------
--------------------------
 
library IEEE;
 
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
 
entity pc_adress is
port (
pc_inc : in std_logic ;
reset : in std_logic ;
adress : out std_logic_vector (15 downto 0);
adress_16_in : in std_logic_vector (15 downto 0);
ctrl_adress_pc : in std_logic ;
ctrl_adress_out : in std_logic ;
ret_adress_out : out std_logic_vector (15 downto 0);
lock_pc : in std_logic
);
end pc_adress ;
 
architecture archi_pc_adress of pc_adress is
begin
 
process (reset,pc_inc,ctrl_adress_pc,adress_16_in,ctrl_adress_out)
variable pc : std_logic_vector (15 downto 0);
begin
if (ctrl_adress_pc='1')then
pc := adress_16_in ;
else
if reset = '1' then
pc :="0000000000000000" ;
adress<="0000000000000000" ;
else
if (pc_inc'event and pc_inc='1')then
if pc<65535 then
if (lock_pc='0')then
pc := pc + 1 ;
end if ;
else
pc:="0000000000000000" ;
end if;
end if ;
end if ;
end if ;
 
 
if ctrl_adress_out='1' then
adress <= pc ;
ret_adress_out <= pc ;
end if ;
 
end process ;
 
end archi_pc_adress ;
/trunk/bench/VHDL/Compar.vhd
0,0 → 1,85
-------------------------------------------------------------------------------
-- Unit comparison
--
--
-------------------------------------------------------------------------------
 
library IEEE;
 
use IEEE.STD_LOGIC_1164.all;
 
entity compar is
port (
d_in1 : in std_logic_vector (8 downto 1);
d_in2 : in std_logic_vector (8 downto 1);
selec_f : in std_logic_vector (1 downto 0);
clk : in std_logic ;
d_out : out std_logic
);
end compar ;
 
architecture archi_compar of compar is
 
component compar1
port (
x : in std_logic ;
y : in std_logic ;
ck : in std_logic ;
Sin0 : in std_logic ;
Sin1 : in std_logic ;
Sout0 : out std_logic ;
Sout1 : out std_logic ;
Sout2 : out std_logic
);
end component ;
 
signal cc1_compar : std_logic_vector (8 downto 0) ;
signal cc2_compar : std_logic_vector (8 downto 0) ;
signal cc3_compar : std_logic_vector (8 downto 1) ;
signal ck : std_logic_vector (8 downto 1) ;
signal res1 : std_logic ;
signal res2 : std_logic ;
signal res3 : std_logic ;
 
begin
cc1_compar(8)<= '0' ;
cc2_compar(8)<= '0' ;
compar_unit : for k in 1 to 8 generate
cmp : compar1 port map (d_in1(k),d_in2(k),ck(k),cc1_compar(k),cc2_compar(k),cc1_compar(k-1),cc2_compar(k-1),cc3_compar(k));
ck(k)<=clk ;
end generate ;
res1 <= cc1_compar(1)or cc1_compar(2)or cc1_compar(3)or cc1_compar(4)or cc1_compar(5)or cc1_compar(6)or cc1_compar(7)or cc1_compar(8);
res2 <= cc2_compar(1)or cc2_compar(2)or cc2_compar(3)or cc2_compar(4)or cc2_compar(5)or cc2_compar(6)or cc2_compar(7)or cc2_compar(8);
res3 <= cc3_compar(1)and cc3_compar(2)and cc3_compar(3)and cc3_compar(4)and cc3_compar(5)and cc3_compar(6)and cc3_compar(7)and cc3_compar(8);
 
process (clk)
begin
if (clk'event and clk='1')then
case selec_f is
when "01"=>
if (res1='1') then
d_out <= '1'; --in1<in2
end if ;
---------
when "10"=>
if (res2='1') then
d_out <= '1'; --in1>in2
end if ;
---------
when "11"=>
if (res3='1') then
d_out <= '1'; --in1=in2
end if ;
---------
when "00"=>
d_out <= '0';
when others =>
end case;
end if;
end process ;
end archi_compar ;
/trunk/bench/VHDL/Controle.vhd
0,0 → 1,153
-------------------------------------------------------------------------------
-- Control Unit
--
--
-------------------------------------------------------------------------------
 
library IEEE;
 
use IEEE.STD_LOGIC_1164.all;
 
entity ctrl is
port (
clk : in std_logic ;
data_in : in std_logic_vector (7 downto 0);
reset : in std_logic ;
d_compar2ctrl : in std_logic ;
wo : out std_logic ;
oe : out std_logic ;
pc_inc : out std_logic ;
d_ctrl2compar : out std_logic_vector (7 downto 0);
selec_fonc_compar: out std_logic_vector (1 downto 0);
adress_in : in std_logic_vector (15 downto 0);
ctrl_alu : out std_logic_vector (3 downto 0);
ctrl_adress : out std_logic_vector (1 downto 0);
adress_8 : out std_logic_vector (7 downto 0);
d_ALU2ctrl : in std_logic_vector (7 downto 0);
d_ctrl2ALU : out std_logic_vector (7 downto 0);
c_adress_out : out std_logic ;
carry_flag : in std_logic ;
ovf_flag : in std_logic ;
c_inALU : out std_logic ;
data_flag : out std_logic_vector (4 downto 0);
selec_data_out : out std_logic_vector (1 downto 0);
out_data : out std_logic_vector (7 downto 0);
c_inCompar : out std_logic ;
c_AdressOut2 : out std_logic ;
p2ctrl : in std_logic ;
ctrl2p : out std_logic ;
lock_ctrl2pc : out std_logic
);
end ctrl ;
 
architecture archi_ctrl of ctrl is
 
signal c_reg_resu1 : std_logic_vector (2 downto 0);
signal reg1 : std_logic_vector (7 downto 0);
signal reg2: std_logic_vector (7 downto 0);
signal reg_flag : std_logic_vector (4 downto 0);
signal s_flag2FSM : std_logic_vector (4 downto 0);
signal s_flag_compar: std_logic ;
signal s_addres_out : std_logic ;
signal s_inALU : std_logic ;
signal s_data_out : std_logic ;
signal s_flag_out : std_logic ;
signal s_compar : std_logic ;
 
component FSM
port (
clk : in std_logic ;
d_in_FSM : in std_logic_vector (7 downto 0);
reset : in std_logic ;
compar2FSM : in std_logic ;
wo : out std_logic ;
oe : out std_logic ;
pc_inc : out std_logic ;
data2compar : out std_logic_vector (7 downto 0);
selec_fonc_compar: out std_logic_vector (1 downto 0);
selec_reg_resu1 : out std_logic_vector (2 downto 0);
adress_in : in std_logic_vector (15 downto 0);
ctrl_alu : out std_logic_vector (3 downto 0);
ctrl_adress : out std_logic_vector (1 downto 0);
adress_8 : out std_logic_vector (7 downto 0);
c_data_out : out std_logic ;
c_adress_out : out std_logic ;
s_flag_out : out std_logic ;
c_inALU : out std_logic ;
resu_compar : out std_logic ;
reg_resu2 : in std_logic_vector (7 downto 0);
c_in_compar : out std_logic ;
c_adress2_out : out std_logic ;
reg_flag2FSM : in std_logic_vector (4 downto 0);
p2fsm : in std_logic ;
fsm2p : out std_logic ;
lock_fsm2pc : out std_logic
);
end component;
 
 
 
begin
FSM_state : entity work.FSM(archi_FSM)
port map (clk,data_in,reset,d_compar2ctrl,wo,oe,pc_inc,
d_ctrl2compar,selec_fonc_compar,c_reg_resu1,
adress_in,ctrl_alu,ctrl_adress,adress_8,
s_data_out,s_addres_out,s_flag_out,
s_inALU,s_flag_compar,reg1,s_compar,
c_AdressOut2,s_flag2FSM,p2ctrl,ctrl2p,lock_ctrl2pc);
 
c_inALU<=s_inALU ;
d_ctrl2ALU<=reg1 ;
c_inCompar<=s_compar ;
c_adress_out<=s_addres_out ;
 
reg_flag(0) <= (not reg1(0))and (not reg1(1))and (not reg1(2))and (not reg1(3))and (not reg1(4))and (not reg1(5))and (not reg1(6))and (not reg1(7)); -- zero flag
reg_flag(1) <= (((((((reg1(0)xor reg1(1))xor reg1(2))xor reg1(3))xor reg1(4))xor reg1(5))xor reg1(6))xor reg1(7)); -- parity flag
reg_flag(2) <= carry_flag ; -- carry flag
reg_flag(3) <= ovf_flag ; -- overflow flag
reg_flag(4) <= s_flag_compar ; -- comparison flag
 
data_flag<=reg_flag ;
selec_data_out<= s_flag_out & s_data_out ;
s_flag2FSM<=reg_flag ;
 
process (reset,clk)
begin
if reset ='1' then
reg1<="00000000" ;
out_data<="00000000" ;
reg2<="00000000" ;
else
if rising_edge(clk) then
case c_reg_resu1 is
when "000"=>
reg2 <= reg1 ; -- result. out
out_data <= reg2 ;
when "001"=>
reg2<='0'&reg1(7 downto 1); -- shift right with 0
when "010"=>
reg2<='1'&reg1(7 downto 1); -- shift right with 1
when "011"=>
reg2<=reg1(6 downto 0)&'0'; -- shift left with 0
when "100"=>
reg2<=reg1(6 downto 0)&'1'; -- shift left with 1
when "101"=>
reg2<=reg1(0)&reg1(7 downto 1); -- rot right
out_data <= reg2 ;
when "110"=>
reg2<=reg1(6 downto 0)&reg1(7); -- rot left
out_data <= reg2 ;
when "111"=>
reg1<=d_ALU2ctrl ;
when others =>
end case ;
end if ;
end if ;
 
end process ;
end archi_ctrl ;
 
/trunk/bench/VHDL/FSM.vhd
0,0 → 1,468
-------------------------------------------------------------------------------
-- FSM (Finite State Machine)
--
--
-------------------------------------------------------------------------------
 
library IEEE;
 
use IEEE.STD_LOGIC_1164.all;
 
entity FSM is
port (
clk : in std_logic ;
d_in_FSM : in std_logic_vector (7 downto 0);
reset : in std_logic ;
compar2FSM : in std_logic ;
wo : out std_logic ;
oe : out std_logic ;
pc_inc : out std_logic ;
data2compar : out std_logic_vector (7 downto 0);
selec_fonc_compar: out std_logic_vector (1 downto 0);
selec_reg_resu1 : out std_logic_vector (2 downto 0);
adress_in : in std_logic_vector (15 downto 0);
ctrl_alu : out std_logic_vector (3 downto 0);
ctrl_adress : out std_logic_vector (1 downto 0);
adress_8 : out std_logic_vector (7 downto 0);
c_data_out : out std_logic ;
c_adress_out : out std_logic ;
c_flag_out : out std_logic ;
c_inALU : out std_logic ;
resu_compar : out std_logic ;
reg_resu2 : in std_logic_vector (7 downto 0);
c_in_compar : out std_logic ;
c_adress2_out : out std_logic ;
reg_flag2FSM : in std_logic_vector (4 downto 0);
p2fsm : in std_logic ;
fsm2p : out std_logic ;
lock_fsm2pc : out std_logic
);
end FSM ;
 
architecture archi_FSM of FSM is
 
type stat_type is (s0,s01,s1,s2,s21,s22,s23,s24,s25,s26,s27,s28,
s29,s3,s31,s32,s33,s34,s35,s36,s37,s4,s41,s42,s43,s44,s45,s46,
s5,s6,s7,s_ck1,s_ck2,s_ck3,s_ck4,s_ck5,s_ck6,s_ck7,s_ck8,s_ck9,
s_ck10,s_ck11,s8,s81,s9,s91,s92,s93,s94,s95,s96,s97,s98,s99,s10,s10a,
s10b,s10c,s10d,s10e,s10f,s10g,s10h);
 
 
signal tempo : std_logic_vector (7 downto 0);
signal tempo1 : std_logic_vector (3 downto 0);
signal temp_adress : std_logic_vector (15 downto 0);
signal statu : std_logic ;
signal var_flag : std_logic ;
signal lock_fsm : std_logic ;
signal state : stat_type ;
 
begin
process (reset,clk,d_in_FSM)
begin
if (reset='1') then
c_flag_out<='0';
pc_inc<='0';
selec_reg_resu1<="000";
ctrl_alu<="0000";
var_flag<='0';
ctrl_adress<="00";
wo <='0';
oe <='1';
adress_8<="00000000";
statu<='0';
c_inALU<='0';
c_adress_out<='0';
selec_fonc_compar<="00";
c_in_compar<='0';
fsm2p<='0';
data2compar<="00000000";
temp_adress<="0000000000000000";
tempo<="00000000";
c_data_out<='0';
resu_compar<='0';
c_adress2_out<='1';
lock_fsm<='1';
tempo1<="0000";
lock_fsm2pc<='0';
state<=s0;
else
if (clk'event and clk='1')then
if (p2fsm='0')then
wo <='0';
oe <='1';
lock_fsm2pc<='0';
else
if(p2fsm='1')then
if (lock_fsm='1') then
oe <='0';
fsm2p<='1';
lock_fsm2pc<='1';
end if;
end if;
end if;
tempo<=d_in_FSM ;
case state is
when s0 =>
pc_inc<='0';
if (lock_fsm='1') then
pc_inc<='1';
statu<= '0' ;
state<=s01;
end if ;
when s01 =>
pc_inc<='0';
state<=s1;
when s1=>
if statu = '0' then
case tempo is
when "00000001"=> --------------------- begin of ALU
ctrl_alu<="0001";
state<=s3;
when "00000010"=>
ctrl_alu<="0010";
state<=s3;
when "00000011"=>
ctrl_alu<="0011";
state<=s3;
when "00000100"=>
tempo1<="0100";
state<=s2;
when "00000101"=>
tempo1<="0101";
state<=s2;
when "00000110"=>
tempo1<="0110";
state<=s2;
when "00000111"=>
tempo1<="0111";
state<=s2;
when "00001000"=>
tempo1<="1000";
state<=s2;
when "00001001"=>
ctrl_alu<="1001";
state<=s3;
when "00001010"=>
ctrl_alu<="1010" ;
state<=s3;
when "00001011"=>
ctrl_alu<="1011";
state<=s3;
when "00001100"=>
ctrl_alu<="1100" ;
state<=s3; ----------------------- end of ALU
when "00010000"=> -------- acces to adress
state<=s4;
when "00100000"=> -------- return to address PC
state<=s9;
when "00110000"=> -- comparison >,<,=
state<=s5;
when "01000000"=>
state<=s6;
when "01010000"=>
state<=s7;
when "01100000"=> -- Release of the result
c_data_out<='1';
state<=s0;
when "01110000"=> -- load flag register
c_flag_out<='1';
pc_inc<='1';
state<=s0;
when "10000000"=> -- shift/rot
selec_reg_resu1<="001";
pc_inc<='1';
state<=s0;
when "10010000"=>
selec_reg_resu1<="010";
pc_inc<='1';
state<=s0;
when "10100000"=>
selec_reg_resu1<="011";
pc_inc<='1';
state<=s0;
when "10110000"=>
selec_reg_resu1<="100";
pc_inc<='1';
state<=s0;
when "11000000"=>
selec_reg_resu1<="101";
pc_inc<='1';
state<=s0;
when "11010000"=>
selec_reg_resu1<="110";
pc_inc<='1';
state<=s0;
when "11110000"=> -- whrite
state<=s8;
when "10000001"=> -- if zero
var_flag<=reg_flag2FSM(0);
state<=s10;
when "11110010"=> -- if parity
var_flag<=reg_flag2FSM(1);
state<=s10;
when "11110011"=> -- if 'comparison'
var_flag<=reg_flag2FSM(4);
state<=s10;
when "11110100"=> -- if cary
var_flag<=reg_flag2FSM(2);
state<=s10;
when "11110101"=> -- if overflow
var_flag<=reg_flag2FSM(3);
state<=s10;
when others =>
end case ;
end if ;
when s2=> ----- opcode a ,b =
lock_fsm<='0';
statu<= '1' ;
c_inALU<='1';
pc_inc<='1';
state<=s21;
when s21=>
pc_inc<='0';
state<=s22;
when s22 =>
ctrl_alu <= tempo1 ;
state<=s23;
when s23=> --- 1st clk
state<=s24;
when s24=> --- clk
state<=s25;
when s25=> --- clk
state<=s26;
when s26=> --- clk
state<=s27;
when s27=> --- clk
state<=s28;
when s28=> --- clk
selec_reg_resu1<= "111"; -- record the result in the register
state<=s29;
when s29=>
selec_reg_resu1<= "000";
pc_inc<='1';
c_inALU<='0';
lock_fsm<='1';
ctrl_alu <= "0000" ;
state<=s0;
when s3=> ------- opcode a =
lock_fsm<='0';
statu<= '1' ;
c_inALU<='1';
pc_inc<='1';
state<=s31;
when s31=>
pc_inc<='0';
state<=s32;
when s32 => --- 1stclk
state<=s33;
when s33 => --- clk
state<=s34;
when s34 => --- clk
state<=s35;
when s35=> --- clk
state<=s36;
when s36 => --- clk
selec_reg_resu1<= "111"; -- record the result in the register
state<=s37;
when s37 =>
selec_reg_resu1<= "000";
pc_inc<='1';
c_inALU<='0';
lock_fsm<='1';
ctrl_alu <= "0000" ;
state<=s0;
when s4=>
lock_fsm<='0';
temp_adress<=adress_in ;
pc_inc<='1';
state<=s41;
when s41=>
pc_inc<='0';
adress_8<=tempo ;
ctrl_adress<="01" ;
state<=s42;
when s42=>
pc_inc<='1';
state<=s43;
when s43 =>
pc_inc<='0';
adress_8<=tempo ;
ctrl_adress<="10" ;
state<=s44;
when s44 =>
ctrl_adress<="11" ;
state<=s45;
when s45=>
ctrl_adress<="00" ;
c_adress_out <= '1';
state<=s46;
when s46=>
c_adress_out <= '0';
lock_fsm<='1';
state<=s0;
when s5=> --- comparison <
selec_reg_resu1<= "000";
data2compar<=reg_resu2 ;
selec_fonc_compar<="01" ;
pc_inc<='1';
state<=s_ck1;
when s6=> --- comparison >
selec_reg_resu1<= "000";
data2compar<=reg_resu2 ;
selec_fonc_compar<="10" ;
pc_inc<='1';
state<=s_ck1;
when s7=> --- comparison =
selec_reg_resu1<= "000";
data2compar<=reg_resu2 ;
selec_fonc_compar<="11" ;
pc_inc<='1';
state<=s_ck1;
when s_ck1 =>
lock_fsm<='0';
pc_inc<='0';
c_in_compar<='1';
statu<= '1' ;
state<=s_ck2;
when s_ck2=> -- 1st clk
state<=s_ck3;
when s_ck3=> -- clk
state<=s_ck4;
when s_ck4 => -- clk
state<=s_ck5;
when s_ck5=> -- clk
state<=s_ck6;
when s_ck6=> -- clk
state<=s_ck7;
when s_ck7=> -- clk
state<=s_ck8;
when s_ck8=> -- clk
state<=s_ck9;
when s_ck9=> -- clk
state<=s_ck10;
when s_ck10=> -- clk
state<=s_ck11;
when s_ck11=> -- clk
resu_compar <= compar2FSM ;
pc_inc<='1';
c_in_compar<='0';
lock_fsm<='1';
state<=s0;
when s8=> -- whrite
pc_inc<='1';
wo <='1';
oe <='1';
c_data_out<='1';
state<=s81;
when s81=>
pc_inc<='0';
c_data_out<='0';
state<=s0;
when s9=> -- return to adress
lock_fsm<='0';
c_adress2_out<='0' ;
pc_inc<='0';
adress_8<=temp_adress(7 downto 0) ;
ctrl_adress<="10" ;
state<=s91;
when s91=>
adress_8<=temp_adress(15 downto 8) ;
ctrl_adress<="01" ;
state<=s92;
when s92=>
ctrl_adress<="11" ;
c_adress_out <= '1';
state<=s93;
when s93 =>
c_adress_out <= '0';
state<=s94;
when s94 =>
pc_inc<='1';
ctrl_adress<="00" ;
state<=s95;
when s95 =>
pc_inc<='0';
state<=s96;
when s96 =>
pc_inc<='1';
state<=s97;
when s97 =>
pc_inc<='0';
state<=s98 ;
when s98 =>
pc_inc<='1';
state<=s99 ;
when s99 =>
pc_inc<='0';
c_adress2_out<='1' ;
lock_fsm<='1';
state<=s0;
when s10 => -- is yes ;;
if var_flag = '1' then
pc_inc<='1';
state<=s0;
else
state<=s10a ;
end if ;
when s10a =>
tempo<="00000000";
lock_fsm<='0';
pc_inc<='1';
state<=s10b;
when s10b =>
pc_inc<='0';
state<=s10c;
when s10c =>
pc_inc<='1';
state<=s10d;
when s10d =>
pc_inc<='0';
state<=s10e;
when s10e =>
pc_inc<='1';
state<=s10f;
when s10f =>
pc_inc<='0';
state<=s10g;
when s10g =>
pc_inc<='1';
state<=s10h;
when s10h =>
c_adress2_out <= '1';
lock_fsm<='1';
state<=s0 ;
when others =>
end case ;
end if ;
end if;
 
end process ;
 
end archi_FSM ;
/trunk/bench/VHDL/UPRO.vhd
0,0 → 1,192
--=============================================================================
-- Project: basic Microprocessor(ZA208) http://za208.blogspot.com
-- Copyright: GNU General Public License version 3 (GPLv3) (http://www.gnu.org)(http://www.fsf.org/)
-- Author: Hadef Mohamed Yacine, Barkat Cherif
-- created : 14/04/2008
-- Revision: 26/05/2008 ; 29/05/2008
-- Last revised: 12/06/2008
-- Synthesis : synthesis and implement in 'Xilinx :"SPARTAN 3 VQ100"'
-- Workfile: upro.vhd ;; Workspace : PFE
-- University: Mentouri - Constantine
-------------------------------------------------------------------------------
-- Description:
-- Microprocessor with 28 instructions
-- (9 instructions of arithmitic and logic calculates)
-------------------------------------------------------------------------------
 
--=============================================================================
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity upro is
port (
data_in : in std_logic_vector (7 downto 0);
data_out : out std_logic_vector (7 downto 0);
addrs : out std_logic_vector (15 downto 0);
reset : in std_logic ;
wo : out std_logic ;
oe : out std_logic ;
clk : in std_logic ;
per_i : in std_logic ;
per_o : out std_logic
);
end upro;
architecture archi_upro of upro is
 
signal s_alu_in : std_logic_vector (7 downto 0) ;
signal s_alu_out : std_logic_vector (7 downto 0) ;
signal s_alu : std_logic_vector (3 downto 0) ;
signal s_adress8 : std_logic_vector (7 downto 0) ;
signal s_c_adress : std_logic_vector (1 downto 0) ;
signal s_comp_in : std_logic_vector (7 downto 0) ;
signal s_fonc_compar: std_logic_vector (1 downto 0);
signal s_c_adress1 : std_logic_vector (15 downto 0) ;
signal s_c_adress2 : std_logic_vector (15 downto 0) ;
signal s_data2ALU : std_logic_vector (7 downto 0) ;
signal s_reg_out : std_logic_vector (7 downto 0);
signal s_reg_f : std_logic_vector (4 downto 0) ;
signal s_out : std_logic_vector (1 downto 0) ;
signal s_d2compar : std_logic_vector (7 downto 0) ;
signal s_incr : std_logic ;
signal s_compar : std_logic ;
signal s_cc_adres : std_logic ;
signal s_carry : std_logic ;
signal s_overf : std_logic ;
signal s_inALU : std_logic ;
signal s_c_in_compar : std_logic ;
signal s_c_out_PC : std_logic ;
signal s_lock_pc : std_logic ;
 
 
component FA_8bits
port (
clk : in std_logic ;
selec : in std_logic_vector (3 downto 0);
FA_in1 : in std_logic_vector (7 downto 0);
FA_in2 : in std_logic_vector (7 downto 0);
FA_out : out std_logic_vector (7 downto 0);
carry : out std_logic ;
overf : out std_logic
);
end component ;
 
 
component adress_data
port(
ctrl_adress : in std_logic_vector (1 downto 0);
adress_8 : in std_logic_vector (7 downto 0);
adress_16 : out std_logic_vector (15 downto 0)
);
end component ;
 
 
component pc_adress
port (
pc_inc : in std_logic ;
reset : in std_logic ;
adress : out std_logic_vector (15 downto 0);
adress_16_in : in std_logic_vector (15 downto 0);
ctrl_adress_pc : in std_logic ;
ctrl_adress_out : in std_logic ;
ret_adress_out : out std_logic_vector (15 downto 0);
lock_pc : in std_logic
);
end component ;
component ctrl
port (
clk : in std_logic ;
data_in : in std_logic_vector (7 downto 0);
reset : in std_logic ;
d_compar2ctrl : in std_logic ;
wo : out std_logic ;
oe : out std_logic ;
pc_inc : out std_logic ;
d_ctrl2compar : out std_logic_vector (7 downto 0);
selec_fonc_compar: out std_logic_vector (1 downto 0);
adress_in : in std_logic_vector (15 downto 0);
ctrl_alu : out std_logic_vector (3 downto 0);
ctrl_adress : out std_logic_vector (1 downto 0);
adress_8 : out std_logic_vector (7 downto 0);
d_ALU2ctrl : in std_logic_vector (7 downto 0);
d_ctrl2ALU : out std_logic_vector (7 downto 0);
c_adress_out : out std_logic ;
carry_flag : in std_logic ;
ovf_flag : in std_logic ;
c_inALU : out std_logic ;
data_flag : out std_logic_vector (4 downto 0);
selec_data_out : out std_logic_vector (1 downto 0);
out_data : out std_logic_vector (7 downto 0);
c_inCompar : out std_logic ;
c_AdressOut2 : out std_logic ;
p2ctrl : in std_logic ;
ctrl2p : out std_logic ;
lock_ctrl2pc : out std_logic
);
end component ;
 
 
component compar
port (
d_in1 : in std_logic_vector (8 downto 1);
d_in2 : in std_logic_vector (8 downto 1);
selec_f : in std_logic_vector (1 downto 0);
clk : in std_logic ;
d_out : out std_logic
);
end component ;
 
begin
upro_a : entity work.FA_8bits(archi_FA_8bits)
port map (clk,s_alu,s_data2ALU,s_alu_in,s_alu_out,s_carry,s_overf);
upro_b : entity work.adress_data(archi_adress_data)
port map (s_c_adress,s_adress8,s_c_adress1);
upro_c : entity work.pc_adress(archi_pc_adress)
port map (s_incr,reset,addrs,s_c_adress1,s_cc_adres,s_c_out_PC,s_c_adress2,s_lock_pc);
upro_d : entity work.ctrl(archi_ctrl)
port map (clk,data_in,reset,s_compar,wo,oe,s_incr,s_comp_in,
s_fonc_compar,s_c_adress2,s_alu,s_c_adress,
s_adress8,s_alu_out,s_alu_in,s_cc_adres,s_carry,s_overf,
s_inALU,s_reg_f,s_out,s_reg_out,s_c_in_compar,s_c_out_PC,per_i,per_o,s_lock_pc);
upro_e : entity work.compar(archi_compar)
port map (s_d2compar,s_comp_in,s_fonc_compar,clk,s_compar);
 
 
process (clk,s_inALU,s_c_in_compar,s_out,s_reg_out,s_reg_f)
begin
 
if rising_edge(CLK) then
if s_inALU='1'then
s_data2ALU <= data_in ;
end if ;
end if ;
 
if rising_edge(CLK) then
if s_c_in_compar='1'then
s_d2compar <= data_in ;
end if ;
end if ;
 
case s_out is
when "01"=>
data_out <=s_reg_out ;
when "10"=>
data_out <= "000"&s_reg_f ;
when others =>
end case ;
 
end process ;
 
end archi_upro;
/trunk/bench/VHDL/UPRO_lib.vhd
0,0 → 1,222
-------------------------------------------------------------------------------
-- function, procedure librery
--
--
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
 
package upro_lib is
 
 
end upro_lib ;
 
-----------------------------------------------
-----------------------------------------------
 
library IEEE; -- begin of Full adder
use IEEE.STD_LOGIC_1164.all;
 
entity fa is
port ( x,y,cin,clk : in std_logic ; s,cout:out std_logic ) ;
end fa ;
 
architecture archi_fa of fa is
begin
process (clk)
begin
if (clk'event and (clk = '1') and (clk'last_value = '0')) then
s<=(x xor y) xor cin ;
cout<=((x xor y) and cin) or (x and y) ;
end if;
 
end process ;
end archi_fa ; --- end of Full adder
 
-----------------------------------------------
-----------------------------------------------
 
library IEEE; -- begin of select1 ALU
use IEEE.STD_LOGIC_1164.all;
 
entity selec1 is
port ( a1,b1 : in std_logic ;
selec : in std_logic_vector (3 downto 0);
s1: out std_logic
) ;
end selec1 ;
 
architecture archi_selec1 of selec1 is
begin
process (selec,a1,b1)
begin
case selec is
when "0001" =>
s1<= a1; -- load a1
when "0010" =>
s1<= not a1; -- inverse a1
when "0011" =>
s1<= b1; -- b1-1
when "0100" =>
s1<= a1 xor b1; -- a1 xor b1
when "0101" =>
s1<= a1 and b1; -- a1 and b1
when "0110" =>
s1<= a1 or b1; -- a1 or b1
when "0111" =>
s1<= a1 ; -- a1 + b1
when "1000" =>
s1<= a1 ; -- a1 - b1
when "1001" =>
s1<= a1 ; -- a1 - 1
when "1010" =>
s1<= a1 ; -- a1 + 1
when "1011" =>
s1<= b1; -- b1+1
when "1100" =>
s1<= '0'; -- not b
when others => null ;
end case ;
 
end process ;
end archi_selec1 ; -- end of selec1
 
-----------------------------------------------
-----------------------------------------------
 
library IEEE; -- begin of select2 ALU
use IEEE.STD_LOGIC_1164.all;
 
entity selec2 is
port ( b1: in std_logic ;
selec : in std_logic_vector (3 downto 0);
s2: out std_logic
) ;
end selec2 ;
 
architecture archi_selec2 of selec2 is
begin
process (selec,b1)
begin
case selec is
when "0001" =>
s2<= '0'; -- load a1
when "0010" =>
s2<= '0'; -- inverse a1
when "0011" =>
s2<= '0'; -- b1-1
when "0100" =>
s2<= '0'; -- a1 xor b1
when "0101" =>
s2<= '0'; -- a1 and b1
when "0110" =>
s2<= '0'; -- a1 or b1
when "0111" =>
s2<= b1 ; -- a1 + b1
when "1000" =>
s2<= not b1 ; -- a1 - b1
when "1001" =>
s2<= '1' ; -- a1 - 1
when "1010" =>
s2<= '0' ; -- a1 + 1
when "1011" =>
s2<= '1'; -- b1+1
when "1100" =>
s2<= not b1 ; -- not b
when others => null ;
end case ;
 
end process ;
end archi_selec2 ; -- end of selec2
-----------------------------------------------
-----------------------------------------------
 
library IEEE; -- debut de select3 ALU
use IEEE.STD_LOGIC_1164.all;
 
entity selec3 is
port (
selec : in std_logic_vector (3 downto 0);
s3: out std_logic
) ;
end selec3 ;
 
architecture archi_selec3 of selec3 is
begin
process (selec)
begin
case selec is
when "1000" =>
s3<= '1' ; -- a1-b1
when "1010" =>
s3<= '1' ; -- a1+1
when "0011" =>
s3<= '1' ; -- b1+1
when others =>
s3<= '0' ; -- others operations
end case ;
 
end process ;
end archi_selec3 ; -- end of selec3
 
-----------------------------------------------
-----------------------------------------------
 
library IEEE; -- comparison
use IEEE.STD_LOGIC_1164.all;
 
entity compar1 is
port (
x : in std_logic ;
y : in std_logic ;
ck : in std_logic ;
Sin0 : in std_logic ;
Sin1 : in std_logic ;
Sout0 : out std_logic ;
Sout1 : out std_logic ;
Sout2 : out std_logic
) ;
end compar1 ;
 
architecture archi_compar1 of compar1 is
signal s_in : std_logic_vector (1 downto 0);
begin
 
process (ck,Sin1,Sin0)
begin
s_in <= (not Sin1)&(not Sin0) ;
 
if (ck'event and ck='1')then
if (s_in ="11")then
Sout1<= (x) and (not y) ; -- x>y = '1'
Sout0<= (y) and (not x) ; -- x<y = '1'
Sout2<= not((y) xor (x)) ; -- x=y = '1'
end if ;
end if ;
end process ;
end archi_compar1 ;
 
-----------------------------------------------
-----------------------------------------------
 
package body upro_lib is
 
end upro_lib ;
 
 
/trunk/rtl/verilog/spi_top.v
0,0 → 1,287
//////////////////////////////////////////////////////////////////////
//// ////
//// spi_top.v ////
//// ////
//// This file is part of the SPI IP core project ////
//// http://www.opencores.org/projects/spi/ ////
//// ////
//// Author(s): ////
//// - Simon Srot (simons@opencores.org) ////
//// ////
//// All additional information is avaliable in the Readme.txt ////
//// file. ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source 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 Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
 
 
`include "spi_defines.v"
`include "timescale.v"
 
module spi_top
(
// Wishbone signals
wb_clk_i, wb_rst_i, wb_adr_i, wb_dat_i, wb_dat_o, wb_sel_i,
wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_err_o, wb_int_o,
 
// SPI signals
ss_pad_o, sclk_pad_o, mosi_pad_o, miso_pad_i
);
 
parameter Tp = 1;
 
// Wishbone signals
input wb_clk_i; // master clock input
input wb_rst_i; // synchronous active high reset
input [4:0] wb_adr_i; // lower address bits
input [32-1:0] wb_dat_i; // databus input
output [32-1:0] wb_dat_o; // databus output
input [3:0] wb_sel_i; // byte select inputs
input wb_we_i; // write enable input
input wb_stb_i; // stobe/core select signal
input wb_cyc_i; // valid bus cycle input
output wb_ack_o; // bus cycle acknowledge output
output wb_err_o; // termination w/ error
output wb_int_o; // interrupt request signal output
// SPI signals
output [`SPI_SS_NB-1:0] ss_pad_o; // slave select
output sclk_pad_o; // serial clock
output mosi_pad_o; // master out slave in
input miso_pad_i; // master in slave out
reg [32-1:0] wb_dat_o;
reg wb_ack_o;
reg wb_int_o;
// Internal signals
reg [`SPI_DIVIDER_LEN-1:0] divider; // Divider register
reg [`SPI_CTRL_BIT_NB-1:0] ctrl; // Control and status register
reg [`SPI_SS_NB-1:0] ss; // Slave select register
reg [32-1:0] wb_dat; // wb data out
wire [`SPI_MAX_CHAR-1:0] rx; // Rx register
wire rx_negedge; // miso is sampled on negative edge
wire tx_negedge; // mosi is driven on negative edge
wire [`SPI_CHAR_LEN_BITS-1:0] char_len; // char len
wire go; // go
wire lsb; // lsb first on line
wire ie; // interrupt enable
wire ass; // automatic slave select
wire spi_divider_sel; // divider register select
wire spi_ctrl_sel; // ctrl register select
wire [3:0] spi_tx_sel; // tx_l register select
wire spi_ss_sel; // ss register select
wire tip; // transfer in progress
wire pos_edge; // recognize posedge of sclk
wire neg_edge; // recognize negedge of sclk
wire last_bit; // marks last character bit
// Address decoder
assign spi_divider_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_DEVIDE);
assign spi_ctrl_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_CTRL);
assign spi_tx_sel[0] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_0);
assign spi_tx_sel[1] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_1);
assign spi_tx_sel[2] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_2);
assign spi_tx_sel[3] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_3);
assign spi_ss_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_SS);
// Read from registers
always @(wb_adr_i or rx or ctrl or divider or ss)
begin
case (wb_adr_i[`SPI_OFS_BITS])
`ifdef SPI_MAX_CHAR_128
`SPI_RX_0: wb_dat = rx[31:0];
`SPI_RX_1: wb_dat = rx[63:32];
`SPI_RX_2: wb_dat = rx[95:64];
`SPI_RX_3: wb_dat = {{128-`SPI_MAX_CHAR{1'b0}}, rx[`SPI_MAX_CHAR-1:96]};
`else
`ifdef SPI_MAX_CHAR_64
`SPI_RX_0: wb_dat = rx[31:0];
`SPI_RX_1: wb_dat = {{64-`SPI_MAX_CHAR{1'b0}}, rx[`SPI_MAX_CHAR-1:32]};
`SPI_RX_2: wb_dat = 32'b0;
`SPI_RX_3: wb_dat = 32'b0;
`else
`SPI_RX_0: wb_dat = {{32-`SPI_MAX_CHAR{1'b0}}, rx[`SPI_MAX_CHAR-1:0]};
`SPI_RX_1: wb_dat = 32'b0;
`SPI_RX_2: wb_dat = 32'b0;
`SPI_RX_3: wb_dat = 32'b0;
`endif
`endif
`SPI_CTRL: wb_dat = {{32-`SPI_CTRL_BIT_NB{1'b0}}, ctrl};
`SPI_DEVIDE: wb_dat = {{32-`SPI_DIVIDER_LEN{1'b0}}, divider};
`SPI_SS: wb_dat = {{32-`SPI_SS_NB{1'b0}}, ss};
default: wb_dat = 32'bx;
endcase
end
// Wb data out
always @(posedge wb_clk_i or posedge wb_rst_i)
begin
if (wb_rst_i)
wb_dat_o <= #Tp 32'b0;
else
wb_dat_o <= #Tp wb_dat;
end
// Wb acknowledge
always @(posedge wb_clk_i or posedge wb_rst_i)
begin
if (wb_rst_i)
wb_ack_o <= #Tp 1'b0;
else
wb_ack_o <= #Tp wb_cyc_i & wb_stb_i & ~wb_ack_o;
end
// Wb error
assign wb_err_o = 1'b0;
// Interrupt
always @(posedge wb_clk_i or posedge wb_rst_i)
begin
if (wb_rst_i)
wb_int_o <= #Tp 1'b0;
else if (ie && tip && last_bit && pos_edge)
wb_int_o <= #Tp 1'b1;
else if (wb_ack_o)
wb_int_o <= #Tp 1'b0;
end
// Divider register
always @(posedge wb_clk_i or posedge wb_rst_i)
begin
if (wb_rst_i)
divider <= #Tp {`SPI_DIVIDER_LEN{1'b0}};
else if (spi_divider_sel && wb_we_i && !tip)
begin
`ifdef SPI_DIVIDER_LEN_8
if (wb_sel_i[0])
divider <= #Tp wb_dat_i[`SPI_DIVIDER_LEN-1:0];
`endif
`ifdef SPI_DIVIDER_LEN_16
if (wb_sel_i[0])
divider[7:0] <= #Tp wb_dat_i[7:0];
if (wb_sel_i[1])
divider[`SPI_DIVIDER_LEN-1:8] <= #Tp wb_dat_i[`SPI_DIVIDER_LEN-1:8];
`endif
`ifdef SPI_DIVIDER_LEN_24
if (wb_sel_i[0])
divider[7:0] <= #Tp wb_dat_i[7:0];
if (wb_sel_i[1])
divider[15:8] <= #Tp wb_dat_i[15:8];
if (wb_sel_i[2])
divider[`SPI_DIVIDER_LEN-1:16] <= #Tp wb_dat_i[`SPI_DIVIDER_LEN-1:16];
`endif
`ifdef SPI_DIVIDER_LEN_32
if (wb_sel_i[0])
divider[7:0] <= #Tp wb_dat_i[7:0];
if (wb_sel_i[1])
divider[15:8] <= #Tp wb_dat_i[15:8];
if (wb_sel_i[2])
divider[23:16] <= #Tp wb_dat_i[23:16];
if (wb_sel_i[3])
divider[`SPI_DIVIDER_LEN-1:24] <= #Tp wb_dat_i[`SPI_DIVIDER_LEN-1:24];
`endif
end
end
// Ctrl register
always @(posedge wb_clk_i or posedge wb_rst_i)
begin
if (wb_rst_i)
ctrl <= #Tp {`SPI_CTRL_BIT_NB{1'b0}};
else if(spi_ctrl_sel && wb_we_i && !tip)
begin
if (wb_sel_i[0])
ctrl[7:0] <= #Tp wb_dat_i[7:0] | {7'b0, ctrl[0]};
if (wb_sel_i[1])
ctrl[`SPI_CTRL_BIT_NB-1:8] <= #Tp wb_dat_i[`SPI_CTRL_BIT_NB-1:8];
end
else if(tip && last_bit && pos_edge)
ctrl[`SPI_CTRL_GO] <= #Tp 1'b0;
end
assign rx_negedge = ctrl[`SPI_CTRL_RX_NEGEDGE];
assign tx_negedge = ctrl[`SPI_CTRL_TX_NEGEDGE];
assign go = ctrl[`SPI_CTRL_GO];
assign char_len = ctrl[`SPI_CTRL_CHAR_LEN];
assign lsb = ctrl[`SPI_CTRL_LSB];
assign ie = ctrl[`SPI_CTRL_IE];
assign ass = ctrl[`SPI_CTRL_ASS];
// Slave select register
always @(posedge wb_clk_i or posedge wb_rst_i)
begin
if (wb_rst_i)
ss <= #Tp {`SPI_SS_NB{1'b0}};
else if(spi_ss_sel && wb_we_i && !tip)
begin
`ifdef SPI_SS_NB_8
if (wb_sel_i[0])
ss <= #Tp wb_dat_i[`SPI_SS_NB-1:0];
`endif
`ifdef SPI_SS_NB_16
if (wb_sel_i[0])
ss[7:0] <= #Tp wb_dat_i[7:0];
if (wb_sel_i[1])
ss[`SPI_SS_NB-1:8] <= #Tp wb_dat_i[`SPI_SS_NB-1:8];
`endif
`ifdef SPI_SS_NB_24
if (wb_sel_i[0])
ss[7:0] <= #Tp wb_dat_i[7:0];
if (wb_sel_i[1])
ss[15:8] <= #Tp wb_dat_i[15:8];
if (wb_sel_i[2])
ss[`SPI_SS_NB-1:16] <= #Tp wb_dat_i[`SPI_SS_NB-1:16];
`endif
`ifdef SPI_SS_NB_32
if (wb_sel_i[0])
ss[7:0] <= #Tp wb_dat_i[7:0];
if (wb_sel_i[1])
ss[15:8] <= #Tp wb_dat_i[15:8];
if (wb_sel_i[2])
ss[23:16] <= #Tp wb_dat_i[23:16];
if (wb_sel_i[3])
ss[`SPI_SS_NB-1:24] <= #Tp wb_dat_i[`SPI_SS_NB-1:24];
`endif
end
end
assign ss_pad_o = ~((ss & {`SPI_SS_NB{tip & ass}}) | (ss & {`SPI_SS_NB{!ass}}));
spi_clgen clgen (.clk_in(wb_clk_i), .rst(wb_rst_i), .go(go), .enable(tip), .last_clk(last_bit),
.divider(divider), .clk_out(sclk_pad_o), .pos_edge(pos_edge),
.neg_edge(neg_edge));
spi_shift shift (.clk(wb_clk_i), .rst(wb_rst_i), .len(char_len[`SPI_CHAR_LEN_BITS-1:0]),
.latch(spi_tx_sel[3:0] & {4{wb_we_i}}), .byte_sel(wb_sel_i), .lsb(lsb),
.go(go), .pos_edge(pos_edge), .neg_edge(neg_edge),
.rx_negedge(rx_negedge), .tx_negedge(tx_negedge),
.tip(tip), .last(last_bit),
.p_in(wb_dat_i), .p_out(rx),
.s_clk(sclk_pad_o), .s_in(miso_pad_i), .s_out(mosi_pad_o));
endmodule
/trunk/rtl/verilog/spi_clgen.v
0,0 → 1,108
//////////////////////////////////////////////////////////////////////
//// ////
//// spi_clgen.v ////
//// ////
//// This file is part of the SPI IP core project ////
//// http://www.opencores.org/projects/spi/ ////
//// ////
//// Author(s): ////
//// - Simon Srot (simons@opencores.org) ////
//// ////
//// All additional information is avaliable in the Readme.txt ////
//// file. ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source 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 Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
 
`include "spi_defines.v"
`include "timescale.v"
 
module spi_clgen (clk_in, rst, go, enable, last_clk, divider, clk_out, pos_edge, neg_edge);
 
parameter Tp = 1;
input clk_in; // input clock (system clock)
input rst; // reset
input enable; // clock enable
input go; // start transfer
input last_clk; // last clock
input [`SPI_DIVIDER_LEN-1:0] divider; // clock divider (output clock is divided by this value)
output clk_out; // output clock
output pos_edge; // pulse marking positive edge of clk_out
output neg_edge; // pulse marking negative edge of clk_out
reg clk_out;
reg pos_edge;
reg neg_edge;
reg [`SPI_DIVIDER_LEN-1:0] cnt; // clock counter
wire cnt_zero; // conter is equal to zero
wire cnt_one; // conter is equal to one
assign cnt_zero = cnt == {`SPI_DIVIDER_LEN{1'b0}};
assign cnt_one = cnt == {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1};
// Counter counts half period
always @(posedge clk_in or posedge rst)
begin
if(rst)
cnt <= #Tp {`SPI_DIVIDER_LEN{1'b1}};
else
begin
if(!enable || cnt_zero)
cnt <= #Tp divider;
else
cnt <= #Tp cnt - {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1};
end
end
// clk_out is asserted every other half period
always @(posedge clk_in or posedge rst)
begin
if(rst)
clk_out <= #Tp 1'b0;
else
clk_out <= #Tp (enable && cnt_zero && (!last_clk || clk_out)) ? ~clk_out : clk_out;
end
// Pos and neg edge signals
always @(posedge clk_in or posedge rst)
begin
if(rst)
begin
pos_edge <= #Tp 1'b0;
neg_edge <= #Tp 1'b0;
end
else
begin
pos_edge <= #Tp (enable && !clk_out && cnt_one) || (!(|divider) && clk_out) || (!(|divider) && go && !enable);
neg_edge <= #Tp (enable && clk_out && cnt_one) || (!(|divider) && !clk_out && enable);
end
end
endmodule
/trunk/rtl/verilog/timescale.v
0,0 → 1,2
`timescale 1ns / 10ps
 
/trunk/rtl/verilog/spi_defines.v
0,0 → 1,159
//////////////////////////////////////////////////////////////////////
//// ////
//// spi_define.v ////
//// ////
//// This file is part of the SPI IP core project ////
//// http://www.opencores.org/projects/spi/ ////
//// ////
//// Author(s): ////
//// - Simon Srot (simons@opencores.org) ////
//// ////
//// All additional information is avaliable in the Readme.txt ////
//// file. ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source 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 Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
 
//
// Number of bits used for devider register. If used in system with
// low frequency of system clock this can be reduced.
// Use SPI_DIVIDER_LEN for fine tuning theexact number.
//
//`define SPI_DIVIDER_LEN_8
`define SPI_DIVIDER_LEN_16
//`define SPI_DIVIDER_LEN_24
//`define SPI_DIVIDER_LEN_32
 
`ifdef SPI_DIVIDER_LEN_8
`define SPI_DIVIDER_LEN 8 // Can be set from 1 to 8
`endif
`ifdef SPI_DIVIDER_LEN_16
`define SPI_DIVIDER_LEN 16 // Can be set from 9 to 16
`endif
`ifdef SPI_DIVIDER_LEN_24
`define SPI_DIVIDER_LEN 24 // Can be set from 17 to 24
`endif
`ifdef SPI_DIVIDER_LEN_32
`define SPI_DIVIDER_LEN 32 // Can be set from 25 to 32
`endif
 
//
// Maximum nuber of bits that can be send/received at once.
// Use SPI_MAX_CHAR for fine tuning the exact number, when using
// SPI_MAX_CHAR_32, SPI_MAX_CHAR_24, SPI_MAX_CHAR_16, SPI_MAX_CHAR_8.
//
`define SPI_MAX_CHAR_128
//`define SPI_MAX_CHAR_64
//`define SPI_MAX_CHAR_32
//`define SPI_MAX_CHAR_24
//`define SPI_MAX_CHAR_16
//`define SPI_MAX_CHAR_8
 
`ifdef SPI_MAX_CHAR_128
`define SPI_MAX_CHAR 128 // Can only be set to 128
`define SPI_CHAR_LEN_BITS 7
`endif
`ifdef SPI_MAX_CHAR_64
`define SPI_MAX_CHAR 64 // Can only be set to 64
`define SPI_CHAR_LEN_BITS 6
`endif
`ifdef SPI_MAX_CHAR_32
`define SPI_MAX_CHAR 32 // Can be set from 25 to 32
`define SPI_CHAR_LEN_BITS 5
`endif
`ifdef SPI_MAX_CHAR_24
`define SPI_MAX_CHAR 24 // Can be set from 17 to 24
`define SPI_CHAR_LEN_BITS 5
`endif
`ifdef SPI_MAX_CHAR_16
`define SPI_MAX_CHAR 16 // Can be set from 9 to 16
`define SPI_CHAR_LEN_BITS 4
`endif
`ifdef SPI_MAX_CHAR_8
`define SPI_MAX_CHAR 8 // Can be set from 1 to 8
`define SPI_CHAR_LEN_BITS 3
`endif
 
//
// Number of device select signals. Use SPI_SS_NB for fine tuning the
// exact number.
//
`define SPI_SS_NB_8
//`define SPI_SS_NB_16
//`define SPI_SS_NB_24
//`define SPI_SS_NB_32
 
`ifdef SPI_SS_NB_8
`define SPI_SS_NB 8 // Can be set from 1 to 8
`endif
`ifdef SPI_SS_NB_16
`define SPI_SS_NB 16 // Can be set from 9 to 16
`endif
`ifdef SPI_SS_NB_24
`define SPI_SS_NB 24 // Can be set from 17 to 24
`endif
`ifdef SPI_SS_NB_32
`define SPI_SS_NB 32 // Can be set from 25 to 32
`endif
 
//
// Bits of WISHBONE address used for partial decoding of SPI registers.
//
`define SPI_OFS_BITS 4:2
 
//
// Register offset
//
`define SPI_RX_0 0
`define SPI_RX_1 1
`define SPI_RX_2 2
`define SPI_RX_3 3
`define SPI_TX_0 0
`define SPI_TX_1 1
`define SPI_TX_2 2
`define SPI_TX_3 3
`define SPI_CTRL 4
`define SPI_DEVIDE 5
`define SPI_SS 6
 
//
// Number of bits in ctrl register
//
`define SPI_CTRL_BIT_NB 14
 
//
// Control register bit position
//
`define SPI_CTRL_ASS 13
`define SPI_CTRL_IE 12
`define SPI_CTRL_LSB 11
`define SPI_CTRL_TX_NEGEDGE 10
`define SPI_CTRL_RX_NEGEDGE 9
`define SPI_CTRL_GO 8
`define SPI_CTRL_RES_1 7
`define SPI_CTRL_CHAR_LEN 6:0
 
/trunk/rtl/verilog/spi_shift.v
0,0 → 1,238
//////////////////////////////////////////////////////////////////////
//// ////
//// spi_shift.v ////
//// ////
//// This file is part of the SPI IP core project ////
//// http://www.opencores.org/projects/spi/ ////
//// ////
//// Author(s): ////
//// - Simon Srot (simons@opencores.org) ////
//// ////
//// All additional information is avaliable in the Readme.txt ////
//// file. ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source 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 Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
 
`include "spi_defines.v"
`include "timescale.v"
 
module spi_shift (clk, rst, latch, byte_sel, len, lsb, go,
pos_edge, neg_edge, rx_negedge, tx_negedge,
tip, last,
p_in, p_out, s_clk, s_in, s_out);
 
parameter Tp = 1;
input clk; // system clock
input rst; // reset
input [3:0] latch; // latch signal for storing the data in shift register
input [3:0] byte_sel; // byte select signals for storing the data in shift register
input [`SPI_CHAR_LEN_BITS-1:0] len; // data len in bits (minus one)
input lsb; // lbs first on the line
input go; // start stansfer
input pos_edge; // recognize posedge of sclk
input neg_edge; // recognize negedge of sclk
input rx_negedge; // s_in is sampled on negative edge
input tx_negedge; // s_out is driven on negative edge
output tip; // transfer in progress
output last; // last bit
input [31:0] p_in; // parallel in
output [`SPI_MAX_CHAR-1:0] p_out; // parallel out
input s_clk; // serial clock
input s_in; // serial in
output s_out; // serial out
reg s_out;
reg tip;
reg [`SPI_CHAR_LEN_BITS:0] cnt; // data bit count
reg [`SPI_MAX_CHAR-1:0] data; // shift register
wire [`SPI_CHAR_LEN_BITS:0] tx_bit_pos; // next bit position
wire [`SPI_CHAR_LEN_BITS:0] rx_bit_pos; // next bit position
wire rx_clk; // rx clock enable
wire tx_clk; // tx clock enable
assign p_out = data;
assign tx_bit_pos = lsb ? {!(|len), len} - cnt : cnt - {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1};
assign rx_bit_pos = lsb ? {!(|len), len} - (rx_negedge ? cnt + {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1} : cnt) :
(rx_negedge ? cnt : cnt - {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1});
assign last = !(|cnt);
assign rx_clk = (rx_negedge ? neg_edge : pos_edge) && (!last || s_clk);
assign tx_clk = (tx_negedge ? neg_edge : pos_edge) && !last;
// Character bit counter
always @(posedge clk or posedge rst)
begin
if(rst)
cnt <= #Tp {`SPI_CHAR_LEN_BITS+1{1'b0}};
else
begin
if(tip)
cnt <= #Tp pos_edge ? (cnt - {{`SPI_CHAR_LEN_BITS{1'b0}}, 1'b1}) : cnt;
else
cnt <= #Tp !(|len) ? {1'b1, {`SPI_CHAR_LEN_BITS{1'b0}}} : {1'b0, len};
end
end
// Transfer in progress
always @(posedge clk or posedge rst)
begin
if(rst)
tip <= #Tp 1'b0;
else if(go && ~tip)
tip <= #Tp 1'b1;
else if(tip && last && pos_edge)
tip <= #Tp 1'b0;
end
// Sending bits to the line
always @(posedge clk or posedge rst)
begin
if (rst)
s_out <= #Tp 1'b0;
else
s_out <= #Tp (tx_clk || !tip) ? data[tx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] : s_out;
end
// Receiving bits from the line
always @(posedge clk or posedge rst)
begin
if (rst)
data <= #Tp {`SPI_MAX_CHAR{1'b0}};
`ifdef SPI_MAX_CHAR_128
else if (latch[0] && !tip)
begin
if (byte_sel[3])
data[31:24] <= #Tp p_in[31:24];
if (byte_sel[2])
data[23:16] <= #Tp p_in[23:16];
if (byte_sel[1])
data[15:8] <= #Tp p_in[15:8];
if (byte_sel[0])
data[7:0] <= #Tp p_in[7:0];
end
else if (latch[1] && !tip)
begin
if (byte_sel[3])
data[63:56] <= #Tp p_in[31:24];
if (byte_sel[2])
data[55:48] <= #Tp p_in[23:16];
if (byte_sel[1])
data[47:40] <= #Tp p_in[15:8];
if (byte_sel[0])
data[39:32] <= #Tp p_in[7:0];
end
else if (latch[2] && !tip)
begin
if (byte_sel[3])
data[95:88] <= #Tp p_in[31:24];
if (byte_sel[2])
data[87:80] <= #Tp p_in[23:16];
if (byte_sel[1])
data[79:72] <= #Tp p_in[15:8];
if (byte_sel[0])
data[71:64] <= #Tp p_in[7:0];
end
else if (latch[3] && !tip)
begin
if (byte_sel[3])
data[127:120] <= #Tp p_in[31:24];
if (byte_sel[2])
data[119:112] <= #Tp p_in[23:16];
if (byte_sel[1])
data[111:104] <= #Tp p_in[15:8];
if (byte_sel[0])
data[103:96] <= #Tp p_in[7:0];
end
`else
`ifdef SPI_MAX_CHAR_64
else if (latch[0] && !tip)
begin
if (byte_sel[3])
data[31:24] <= #Tp p_in[31:24];
if (byte_sel[2])
data[23:16] <= #Tp p_in[23:16];
if (byte_sel[1])
data[15:8] <= #Tp p_in[15:8];
if (byte_sel[0])
data[7:0] <= #Tp p_in[7:0];
end
else if (latch[1] && !tip)
begin
if (byte_sel[3])
data[63:56] <= #Tp p_in[31:24];
if (byte_sel[2])
data[55:48] <= #Tp p_in[23:16];
if (byte_sel[1])
data[47:40] <= #Tp p_in[15:8];
if (byte_sel[0])
data[39:32] <= #Tp p_in[7:0];
end
`else
else if (latch[0] && !tip)
begin
`ifdef SPI_MAX_CHAR_8
if (byte_sel[0])
data[`SPI_MAX_CHAR-1:0] <= #Tp p_in[`SPI_MAX_CHAR-1:0];
`endif
`ifdef SPI_MAX_CHAR_16
if (byte_sel[0])
data[7:0] <= #Tp p_in[7:0];
if (byte_sel[1])
data[`SPI_MAX_CHAR-1:8] <= #Tp p_in[`SPI_MAX_CHAR-1:8];
`endif
`ifdef SPI_MAX_CHAR_24
if (byte_sel[0])
data[7:0] <= #Tp p_in[7:0];
if (byte_sel[1])
data[15:8] <= #Tp p_in[15:8];
if (byte_sel[2])
data[`SPI_MAX_CHAR-1:16] <= #Tp p_in[`SPI_MAX_CHAR-1:16];
`endif
`ifdef SPI_MAX_CHAR_32
if (byte_sel[0])
data[7:0] <= #Tp p_in[7:0];
if (byte_sel[1])
data[15:8] <= #Tp p_in[15:8];
if (byte_sel[2])
data[23:16] <= #Tp p_in[23:16];
if (byte_sel[3])
data[`SPI_MAX_CHAR-1:24] <= #Tp p_in[`SPI_MAX_CHAR-1:24];
`endif
end
`endif
`endif
else
data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] <= #Tp rx_clk ? s_in : data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]];
end
endmodule
 
/trunk/doc/spi.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
trunk/doc/spi.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: trunk/doc/src/spi.doc =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: trunk/doc/src/spi.doc =================================================================== --- trunk/doc/src/spi.doc (nonexistent) +++ trunk/doc/src/spi.doc (revision 2)
trunk/doc/src/spi.doc Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: trunk/sim/rtl_sim/run/rtl.fl =================================================================== --- trunk/sim/rtl_sim/run/rtl.fl (nonexistent) +++ trunk/sim/rtl_sim/run/rtl.fl (revision 2) @@ -0,0 +1,3 @@ +spi_top.v +spi_clgen.v +spi_shift.v Index: trunk/sim/rtl_sim/run/sim.fl =================================================================== --- trunk/sim/rtl_sim/run/sim.fl (nonexistent) +++ trunk/sim/rtl_sim/run/sim.fl (revision 2) @@ -0,0 +1,3 @@ +tb_spi_top.v +wb_master_model.v +spi_slave_model.v Index: trunk/sim/rtl_sim/run/run_sim =================================================================== --- trunk/sim/rtl_sim/run/run_sim (nonexistent) +++ trunk/sim/rtl_sim/run/run_sim (revision 2) @@ -0,0 +1,108 @@ +#!/bin/csh -f + +set current_par = 0 +set output_waveform = 0 +while ( $current_par < $# ) + @ current_par = $current_par + 1 + case wave: + @ output_waveform = 1 + breaksw + default: + echo 'Unknown option "'$argv[$current_par]'"!' + exit + breaksw + endsw +end + +echo "TEST: spi" + +#echo "-CDSLIB ./cds.lib" > ncvlog.args +#echo "-HDLVAR ./hdl.var" >> ncvlog.args +echo "-MESSAGES" > ncvlog.args +echo "-INCDIR ../../../bench/verilog" >> ncvlog.args +echo "-INCDIR ../../../rtl/verilog" >> ncvlog.args +echo "-NOCOPYRIGHT" >> ncvlog.args +echo "-UPDATE" >> ncvlog.args +echo "-LOGFILE ncvlog.log" >> ncvlog.args + +foreach filename ( `cat ./rtl.fl` ) + echo "../../../rtl/verilog/"$filename >> ncvlog.args +end + +foreach filename ( `cat ./sim.fl` ) + echo "../../../bench/verilog/"$filename >> ncvlog.args +end + +ncvlog -f ncvlog.args +if ($status != 0) then + echo "STATUS: failed" + exit +endif + + +echo "-MESSAGES" > ncelab.args +echo "-NOCOPYRIGHT" >> ncelab.args +#echo "-CDSLIB ./cds.lib" >> ncelab.args +#echo "-HDLVAR ./hdl.var" >> ncelab.args +echo "-LOGFILE ncelab.log" >> ncelab.args +echo "-SNAPSHOT worklib.tb_spi_top:v" >> ncelab.args +echo "-NOTIMINGCHECKS" >> ncelab.args +echo "-ACCESS +RWC" >> ncelab.args +echo "tb_spi_top" >> ncelab.args + +ncelab -f ncelab.args +if ($status != 0) then + echo "STATUS: failed" + exit +endif + + +echo "-MESSAGES" > ncsim.args +echo "-NOCOPYRIGHT" >> ncsim.args +#echo "-CDSLIB ./cds.lib" >> ncsim.args +#echo "-HDLVAR ./hdl.var" >> ncsim.args +echo "-INPUT ncsim.tcl" >> ncsim.args +echo "-LOGFILE ncsim.log" >> ncsim.args +echo "worklib.tb_spi_top:v" >> ncsim.args + +if ( $output_waveform ) then + echo "database -open waves -shm -into ../out/wav" > ./ncsim.tcl + echo "probe -create -database waves -shm tb_spi_top -all -depth all" >> ./ncsim.tcl + echo "stop -create -time 25000000 -relative" >> ./ncsim.tcl + echo "run" >> ./ncsim.tcl +else + echo "stop -create -time 25000000 -relative" >> ./ncsim.tcl + echo "run" > ./ncsim.tcl +endif + +echo "exit" >> ncsim.tcl + +ncsim -LICQUEUE -f ./ncsim.args + +set exit_line_nb = `sed -n '/exit/=' < ./ncsim.log` + +set dead_line_nb = 0 + +if ( $exit_line_nb ) then + + @ dead_line_nb = $exit_line_nb - 1 + set exit_line=`sed -n $exit_line_nb's/exit/&/gp' < ./ncsim.log` + set dead_line=`sed -n $dead_line_nb's/report/&/gp' < ./ncsim.log` + + if ( "$dead_line" == "report (deaddead)" ) then + if ( "$exit_line" == "exit (00000000)" ) then + echo "STATUS: passed" #|tee -a ./run_sim.log 2>&1 + else + echo "STATUS: failed" #|tee -a ./run_sim.log 2>&1 + endif + else + echo "STATUS: failed" + endif + +endif + +exit + + + +
trunk/sim/rtl_sim/run/run_sim Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.