quarta-feira, 15 de janeiro de 2014

ULA

Talvez algumas horas... não lembro.. faz tando tempo...
Guinter, se vc ainda tiver vivo, eu acho q vc que me ajudou a testar cada upcode...





SUBDESIGN UNIDADE_BUSCA
(
Imm8[7..0], NPc_Sel, RESET, CLK : INPUT;
Adp[7..0] : OUTPUT;
)
VARIABLE
PC[7..0] : DFFE; -- 1 REGISTROS DE 8 BITS
SOMADOR_1[7..0], SOMADOR_IMM8[7..0] : NODE;

BEGIN
PC[].CLK = NOT CLK;
PC[].CLRN = NOT RESET; -- reset ativo em 1
Adp[7..0] = PC[].Q;

SOMADOR_1[] = PC[].Q +1;
SOMADOR_IMM8[] = SOMADOR_1[] + Imm8[];

IF NPc_Sel == 0 THEN
PC[].D = SOMADOR_1[];
ELSE
PC[].D = SOMADOR_IMM8[];
END IF;
END;


SUBDESIGN UNIDADE_REG
(
Rw[3..0], Ra[3..0], Rb[3..0] : INPUT;
RegWr, RESET, CLK : INPUT;
BUS_W[7..0] : INPUT;
R0_Ptr, Reg_Clr, Reg_Inc, Reg_Dec, R0_Ptr_Ena : INPUT;
BUS_A[7..0], BUS_B[7..0] : OUTPUT;
)
VARIABLE
REGISTROS[15..0][7..0] : DFFE; -- 16 REGISTROS DE 8 BITS CADA UM
Ra_Ptr[3..0], Rw_Ptr[3..0] : NODE;

BEGIN
REGISTROS[][].CLK = NOT CLK;
REGISTROS[][].CLRN = NOT RESET; -- RESET ATIVO EM 1
REGISTROS[][].D = BUS_W[];


-- ATUALIZAÇÃO DO BANCO DE REGISTROS QUANDO RegWr = 1

IF RegWr THEN -- APENAS O REGISTRO #Rw É ATUALIZADO QUANDO RegWr = 1
IF (R0_Ptr & R0_Ptr_Ena) THEN
Rw_Ptr[3..0] = REGISTROS[0][3..0].Q;
FOR J IN 0 TO 15 GENERATE
CASE Rw_Ptr[] IS
WHEN J => REGISTROS[J][].ENA = VCC;
END CASE;
END GENERATE;
ELSE
FOR I IN 0 TO 15 GENERATE -- #Rw É ATUALIZADO
CASE Rw[] IS
WHEN I => REGISTROS[I][].ENA = VCC;
IF Reg_Clr THEN -- Limpa o registrador
REGISTROS[I][].CLRN = VCC;
ELSIF Reg_Inc THEN -- Incrementa o registrador
REGISTROS[I][].D = REGISTROS[I][].Q + 1;
ELSIF Reg_Dec THEN -- Decrementa o registrador
REGISTROS[I][].D = REGISTROS[I][].Q - 1;
END IF;
END CASE;
END GENERATE;
END IF;
END IF;

-- MULTIPLEXADOR DO BUS_A
IF (R0_Ptr & !R0_Ptr_Ena) THEN -- Ponteiro R0 -- MOV Rd, @R0 ativo com 1
Ra_Ptr[3..0] = REGISTROS[0][3..0].Q;
FOR J IN 0 TO 15 GENERATE
CASE Ra_Ptr[] IS
WHEN J => BUS_A[] = REGISTROS[J][].Q;
END CASE;
END GENERATE;
ELSE
FOR J IN 0 TO 15 GENERATE
CASE Ra[] IS
WHEN J => BUS_A[] = REGISTROS[J][].Q;
END CASE;
END GENERATE;
END IF;

-- MULTIPLEXADOR DO BUS_B

FOR K IN 0 TO 15 GENERATE
CASE Rb[] IS
WHEN K => BUS_B[] = REGISTROS[K][].Q;
END CASE;
END GENERATE;
END;


SUBDESIGN UNIDADE_CONTROLE
(
    OP_CODE[4..0], O_ZERO, O_CARRY : INPUT;
MI[16..0]                                 : OUTPUT;
    --nPC_Sel, RETI, RegWr, RO_Ptl, Reg_Clr, Reg_inc, Reg_dec, ALUctr[2..0],
    --Men_Wr, Reg_Dst, Reg_Src, O_Wr, Alu_Src, Memtoreg      : OUTPUT;
)
BEGIN
CASE OP_CODE[] IS
WHEN B"00000" => -- ADD
MI[] = B"00100000000011000";
WHEN B"00001" => -- SUB
MI[] = B"00100000001011000";
WHEN B"00010" => -- OR
MI[] = B"00100000010011000";
WHEN B"00011" => -- AND
MI[] = B"00100000011011000";
WHEN B"00100" => -- LOAD
MI[] = B"00100000000001011";
WHEN B"00101" => -- STORE
MI[] = B"00000000000100010";
WHEN B"00110" => -- MOV
MI[] = B"00100000111001010";
WHEN B"00111" => -- BRANCH_EQ
MI[15..0] = B"0000000001000000";
MI[16] = O_ZERO;
WHEN B"01000" => -- BRANCH_MENOR
MI[15..0] = B"0000000001000000";
MI[16] = O_CARRY;
WHEN B"01001" => -- JUMP
MI[] = B"10000000111000000";
WHEN B"01010" => -- INC
MI[] = B"00000010111001000";
WHEN B"01011" => -- DEC
MI[] = B"00000001111001000";
WHEN B"01100" => -- CLR
MI[] = B"00000100111001000";
WHEN B"01101" => -- MOV Rd, @R0
MI[] = B"00111000111001010";
WHEN B"01110" => -- MOV @R0, Rs
MI[] = B"00110000111001010";
WHEN B"01111" => -- IOR_RD
MI[] = B"00100000000010000";
WHEN B"10000" => -- IOR_WR
MI[] = B"00100000000010000";
WHEN B"10001" => -- RETI
MI[] = B"01000000000000000";
END CASE;
END;


SUBDESIGN ULA
(
ALUctr[2..0], Bus_A[7..0], Bus_MUX[7..0] : INPUT ;
Bus_OUT[7..0] , O_ZERO , O_CARRY : OUTPUT;
)
BEGIN
DEFAULTS
O_ZERO = GND;
O_CARRY = GND;
Bus_OUT[7..0] = GND;
END DEFAULTS;

CASE ALUctr[] IS
WHEN B"000" => -- ADD, LOAD ou STORE
Bus_OUT [7..0] = Bus_A[7..0] + Bus_MUX[7..0];
WHEN B"001" => -- SUB, BRANCH MENOR ou BRANCH_EQ
Bus_OUT [7..0] = Bus_A[7..0] - Bus_MUX[7..0];
IF ((Bus_A[7..0] - Bus_MUX[7..0]) == 0 ) THEN --Ativa Zero se resultado da subtração for igual a 0 (BRACH_EQ)
O_ZERO = VCC;
ELSE IF (Bus_A[7..0] > Bus_MUX[7..0]) THEN --Ativa Carry se BUS_A for maior que BUS_MUX (BRANCH_MENOR)
O_CARRY = VCC;
END IF;
END IF;
WHEN B"010" => -- OR
Bus_OUT[7..0] = Bus_A[7..0] # Bus_MUX[7..0];
WHEN B"011" => -- AND
Bus_OUT[7..0] = Bus_A[7..0] & Bus_MUX[7..0];
WHEN B"111" => -- MOV /TRASNPARENTE A
Bus_OUT[7..0] = Bus_A[7..0];
END CASE;
END;


SUBDESIGN R0
(
O_Wr, Clk, DATA[7..0] : INPUT;
O[7..0] : OUTPUT;
)
VARIABLE
REGISTRADOR[7..0] : DFFE;

BEGIN
REGISTRADOR[].CLK = NOT Clk;
REGISTRADOR[].D = DATA[];

IF O_Wr ==1 THEN
O[] = REGISTRADOR[].Q;
END IF;
END;



SUBDESIGN MUX_8b_2x1
(
Entrada0[7..0], Entrada1[7..0], Seletor : INPUT;
Saida[7..0] : OUTPUT;
)
BEGIN
CASE Seletor IS
WHEN B"0" => Saida[] = Entrada0[];
WHEN B"1" => Saida[] = Entrada1[];
END CASE;
END;


SUBDESIGN MUX_4b_2x1
(
Entrada0[3..0], Entrada1[3..0], Seletor : INPUT;
Saida[3..0] : OUTPUT;
)
BEGIN
CASE Seletor IS
WHEN B"0" => Saida[] = Entrada0[];
WHEN B"1" => Saida[] = Entrada1[];
END CASE;
END;


Guinter.. o Fabiano passou este links:

http://www.elektronikforumet.com/wiki/images/4/4e/Diglog.png
http://www.xess.com/blog/learn-fpga-programming-with-myhdl/
http://linuxgizmos.com/fpga-programmable-instrumentation-device-runs-linux/
http://www.xess.com/blog/learn-fpga-programming-with-myhdl/

Refazer?
Postar um comentário