基本邏輯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
|
