基本邏輯10     Black Jack

 

 

這是一個較完整的序向電路

 

程式設計者可以練習Data Path/Control的設計形式(style)

 

 

-- bjack

 

VHDL : bjack.vhd

 

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_unsigned.all;

 

ENTITY bjack IS

PORT

(

      mclk,bta,btb      : IN STD_LOGIC;

      card  : IN STD_LOGIC_VECTOR(3 DOWNTO 0);

      btvcc,sto,buo     : OUT STD_LOGIC;

      sco   : OUT STD_LOGIC_VECTOR(4 DOWNTO 0)

);

END bjack;

ARCHITECTURE a1 OF bjack IS

TYPE BJACK_STATE IS (SIdle,SCardIn,SAddCard,SAdd10,STest17,STest22,SSub10,SOver);

SIGNAL sbj,nsbj : BJACK_STATE;

SIGNAL dcnt    : STD_LOGIC_VECTOR(11 DOWNTO 0);

SIGNAL score,data   : STD_LOGIC_VECTOR(4 DOWNTO 0);

SIGNAL sbta,sbtb     : STD_LOGIC_VECTOR(1 DOWNTO 0);

SIGNAL ace,nace,clear,add,add10,sub10,btas,btbs,

              cout,isace,gt16,lt22    : STD_LOGIC;

BEGIN

 

btvcc<='1';

 

PROCESS(mclk)

BEGIN

IF mclk'EVENT AND mclk='1' THEN

      dcnt<=dcnt+1;

END IF;

END PROCESS;

 

cout<='1' WHEN dcnt=16#fff# ELSE '0';

 

PROCESS(mclk)

BEGIN

IF mclk'EVENT AND mclk='1' THEN

      btas<=bta; btbs<=btb;

END IF;

END PROCESS;

 

PROCESS(mclk)

BEGIN

IF mclk'EVENT AND mclk='1' THEN

      CASE sbta IS

      WHEN "00" => IF cout='1' AND btas='1' THEN sbta<="01"; END IF;

      WHEN "01" => sbta<="10";

      WHEN "10" => IF cout='1' AND btas='0' THEN sbta<="00"; END IF;

      WHEN OTHERS => sbta<="00";

      END CASE;

END IF;

END PROCESS;

 

PROCESS(mclk)

BEGIN

IF mclk'EVENT AND mclk='1' THEN

      CASE sbtb IS

      WHEN "00" => IF cout='1' AND btbs='1' THEN sbtb<="01"; END IF;

      WHEN "01" => sbtb<="10";

      WHEN "10" => IF cout='1' AND btbs='0' THEN sbtb<="00"; END IF;

      WHEN OTHERS => sbtb<="00";

      END CASE;

END IF;

END PROCESS;

 

isace<='1' WHEN card=1 ELSE '0';

gt16<='1' WHEN score>16 ELSE '0';

lt22<='1' WHEN score<22 ELSE '0';

 

PROCESS(mclk)

BEGIN

IF mclk'EVENT AND mclk='1' THEN

      IF clear='1' THEN score<="00000";

      ELSIF add='1' THEN score<=score+1; END IF;

END IF;

END PROCESS;

 

PROCESS(add10,sub10,card)

BEGIN

IF add10='1' THEN data<="01010";

ELSIF sub10='1' THEN data<="10110";

ELSE data<="0"&card;

END IF;

END PROCESS;

 

PROCESS(mclk)

BEGIN

IF mclk'EVENT AND mclk='1' THEN

      sbj<=nsbj; ace<=nace;

END IF;

END PROCESS;

PROCESS(sbj,ace,sbta,sbtb,isace,gt16,lt22)

BEGIN

nsbj<=sbj; nace<=ace;

clear<='0'; add<='0'; add10<='0'; sub10<='0';

buo<='0'; sto<='0';

CASE sbj IS

WHEN SIdle => clear<='1'; nace<='0';

      IF sbta(0)='1' THEN nsbj<=SCardIn; END IF;

WHEN SCardIn =>

      IF sbtb(0)='1' THEN nsbj<=SAddCard; END IF;

WHEN SAddCard => add<='1';

      IF isace='1' AND ace='0' THEN nsbj<=SAdd10;

      ELSE nsbj<=STest17; END IF;

WHEN SAdd10 => nace<='1'; add<='1'; add10<='1';

      nsbj<=STest17;

WHEN STest17 =>

      IF gt16='0' THEN nsbj<=SCardIn;

      ELSE nsbj<=STest22; END IF;

WHEN STest22 =>

      IF lt22='1' THEN nsbj<=SOver;

      ELSE

              IF ace='1' THEN nsbj<=SSub10;

              ELSE nsbj<=SOver; END IF;

      END IF;

WHEN SSub10 => nace<='0'; add<='1'; sub10<='1';

      nsbj<=STest17;

WHEN SOver => buo<=NOT lt22; sto<=lt22;     

      IF sbta(0)='1' THEN nsbj<=SIdle; END IF;

END CASE;

END PROCESS;

 

sco<=score;

END a1;

 

 

 

 

Verilog : bjack.v

 

module bjack

(

      mclk,bta,btb,btvcc,card,

      sto,buo,sco

);

input mclk,bta,btb;

input[3:0] card;

output sto,buo,btvcc;

output[4:0] sco;

 

parameter SIdle=3'b000,SCardIn=3'b001,SAddCard=3'b010,SAdd10=3'b011,

      STest17=3'b100,STest22=3'b101,SSub10=3'b110,SOver=3'b111;

 

reg sto,buo,btas,btbs;

reg ace,nace,clear,add,add10,sub10;

reg[1:0] sbta,sbtb;

reg[2:0] sbj,nsbj;

reg[4:0] score,data;

reg[11:0] dcnt;

 

wire cout,isace,gt16,lt22;

 

assign btvcc=1'b1;

 

always @(posedge mclk)

      dcnt<=dcnt+1;

 

assign cout=(dcnt==12'hfff);

 

always @(posedge mclk)

      {btas,btbs}<={bta,btb};

 

always @(posedge mclk)

begin

case(sbta)

0 : if(cout&btas) sbta<=1;

1 : sbta<=2;

2 : if(cout&~btas) sbta<=0;

default : sbta<=0;

endcase

end

always @(posedge mclk)

begin

case(sbtb)

0 : if(cout&btbs) sbtb<=1;

1 : sbtb<=2;

2 : if(cout&~btbs) sbtb<=0;

default : sbtb<=0;

endcase

end

 

assign isace=(card==1),gt16=(score>16),lt22=(score<22);

 

always @(posedge mclk)

begin

if(clear) score<=0;

else if(add) score<=score+data;

end

 

always @(add10 or sub10 or card)

begin

if(add10) data=10;

else if(sub10) data=-10;

else data={1'b0,card};

end

 

always @(posedge mclk)

begin

sbj<=nsbj; ace<=nace;

end

 

always @(sbj or ace or sbta or sbtb or isace or gt16 or lt22)

begin

nsbj=sbj; nace=ace;

clear=1'b0; add=1'b0; add10=1'b0; sub10=1'b0;

buo=1'b0; sto=1'b0;

case(sbj)

SIdle : begin

              clear=1'b1; nace=0;

              if(sbta[0]) nsbj=SCardIn;

              end

SCardIn : begin

              if(sbtb[0]) nsbj=SAddCard;

              end

SAddCard : begin

              add=1'b1;

              if(isace&~ace) nsbj=SAdd10;

              else nsbj=STest17;

              end

SAdd10 : begin

              nace=1'b1; add=1'b1; add10=1'b1;

              nsbj=STest17;

              end

STest17 : begin

              if(~gt16) nsbj=SCardIn;

              else nsbj=STest22;

              end

STest22 : begin

              if(lt22) nsbj=SOver;

              else

                      begin

                      if(ace) nsbj=SSub10;

                      else nsbj=SOver;

                      end

              end

SSub10 : begin

              nace=1'b0; add=1'b1; sub10=1'b1;

              nsbj=STest17;

              end

SOver : begin

              buo=~lt22; sto=lt22;

              if(sbta[0]) nsbj=SIdle;

              end

endcase

end

 

assign sco=score;

 

endmodule

 

 

 

 

 

 

文章標籤
全站熱搜
創作者介紹
創作者 zeppe 的頭像
zeppe

ZEPPE

zeppe 發表在 痞客邦 留言(0) 人氣(51)