使用Quartus-II 9.1SP2 + ModelSim 6.5b-Aletra + Altera DE2-115 FPGA開發平台,設計Arithmetic Logic Unit (ALU)為例(FPGA開發平台)
module DE2_115 (SW, LEDR, LEDG , CLOCK_50 ,KEY ,HEX0 ,HEX1 ,HEX2,HEX3,HEX4 ,HEX5 ,HEX6,HEX7, GPIO );
input [17:0] SW; // toggle switches
input [7:0] KEY; // Push bottom
input CLOCK_50; //Clock 27MHz , 50Mhz
output [17:0] LEDR; // red LEDS
output [8:0] LEDG; // green LEDs
output [6:0] HEX0,HEX1,HEX2,HEX3; //7-segment display
output [6:0] HEX4,HEX5,HEX6,HEX7; //7-segment display
inout [35:0] GPIO;
assign HEX0=7'b111_1111;
assign HEX1=7'b111_1111;
assign HEX2=7'b111_1111;
assign HEX3=7'b111_1111;
assign HEX4=7'b111_1111;
assign HEX5=7'b111_1111;
assign HEX6=7'b111_1111;
assign HEX7=7'b111_1111;
//module alu(Y, C, V, N, Z, A, B, Op);
// output [7:0] Y; // Result.
// output C; // Carry.
// output N; // Negative.
// output V; // Overflow.
// output Z; // Zero.
// input [7:0] A; // Operand.
// input [7:0] B; // Operand.
// input [2:0] Op; // Operation.
alu U0( LEDR[7:0],LEDR[8],LEDR[9],LEDR[10],LEDR[11],SW[7:0],SW[15:8],
{SW[17:16],KEY[0]});
endmodule
module alu(Y, C, V, N, Z, A, B, Op);
output [7:0] Y; // Result.
output C; // Carry.
output N; // Negative.
output V; // Overflow.
output Z; // Zero.
input [7:0] A; // Operand.
input [7:0] B; // Operand.
input [2:0] Op; // Operation.
wire [7:0] AS, And, Or, Xor, Not;
wire s;
wire Vas;
wire Cas;
// The operations
carry_select_adder_subtractor addsub(AS, Cas, Vas, A, B, Op[0]);
// Op == 3'b000, 3'b001
andop aluand(And, A, B);
// Op == 3'b010
orop aluor(Or, A, B);
// Op == 3'b011
xorop aluxor(Xor, A, B);
// Op == 3'b100
notop alunot(Not, A);
// Op == 3'b101
multiplexer_8_1 muxy(Y, AS, AS, And, Or, Xor, Not, 8'b0, 8'b0, Op);
// Select the result.
nor(s, Op[1], Op[2]);
// s == 0 => a logical operation, otherwise and arithmetic operation.
and(C, Cas, s);
and(V, Vas, s);
and(N, Y[7], s);
// Most significant bit is the sign bit in 2's complement.
zero z(Z, Y);
// All operations can set the Zero status bit.
endmodule // alu
module andop(Y, A, B);
output [7:0] Y; // Result.
input [7:0] A; // Operand.
input [7:0] B; // Operand.
and(Y[0], A[0], B[0]);
and(Y[1], A[1], B[1]);
and(Y[2], A[2], B[2]);
and(Y[3], A[3], B[3]);
and(Y[4], A[4], B[4]);
and(Y[5], A[5], B[5]);
and(Y[6], A[6], B[6]);
and(Y[7], A[7], B[7]);
endmodule // andop
module orop(Y, A, B);
output [7:0] Y; // Result.
input [7:0] A; // Operand.
input [7:0] B; // Operand.
or(Y[0], A[0], B[0]);
or(Y[1], A[1], B[1]);
or(Y[2], A[2], B[2]);
or(Y[3], A[3], B[3]);
or(Y[4], A[4], B[4]);
or(Y[5], A[5], B[5]);
or(Y[6], A[6], B[6]);
or(Y[7], A[7], B[7]);
endmodule // orop
module xorop(Y, A, B);
output [7:0] Y; // Result.
input [7:0] A; // Operand.
input [7:0] B; // Operand.
xor(Y[0], A[0], B[0]);
xor(Y[1], A[1], B[1]);
xor(Y[2], A[2], B[2]);
xor(Y[3], A[3], B[3]);
xor(Y[4], A[4], B[4]);
xor(Y[5], A[5], B[5]);
xor(Y[6], A[6], B[6]);
xor(Y[7], A[7], B[7]);
endmodule // xorop
module notop(Y, A);
output [7:0] Y; // Result.
input [7:0] A; // Operand.
not(Y[0], A[0]);
not(Y[1], A[1]);
not(Y[2], A[2]);
not(Y[3], A[3]);
not(Y[4], A[4]);
not(Y[5], A[5]);
not(Y[6], A[6]);
not(Y[7], A[7]);
endmodule // notop
module zero(Z, A);
output Z; // Result.
input [7:0] A; // Operand.
wire [7:0] Y; // Temp result.
xnor(Y[0], A[0], 0);
xnor(Y[1], A[1], 0);
xnor(Y[2], A[2], 0);
xnor(Y[3], A[3], 0);
xnor(Y[4], A[4], 0);
xnor(Y[5], A[5], 0);
xnor(Y[6], A[6], 0);
xnor(Y[7], A[7], 0);
and(Z, Y[0], Y[1], Y[2], Y[3], Y[4],
Y[5], Y[6], Y[7]);
endmodule // zero
module carry_select_adder_subtractor(S, C, V, A, B, Op);
output [7:0] S; // The 16-bit sum/difference.
output C; // The 1-bit carry/borrow status.
output V; // The 1-bit overflow status.
input [7:0] A; // The 16-bit augend/minuend.
input [7:0] B; // The 16-bit addend/subtrahend.
input Op; // The operation: 0 => Add, 1=>Subtract.
wire C7; // The carry out bit of adder/subtractor, used to generate final carry/borrrow.
wire [7:0] Bx;
// Looking at the truth table for not we see that
// B xor 0 = B, and
// B xor 1 = not(B).
// So, if Op==1 means we are subtracting, then
// adding A and B xor Op alog with setting the first
// carry bit to Op, will give us a result of
// A+B when Op==0, and A+not(B)+1 when Op==1.
// Note that not(B)+1 is the 2's complement of B, so
// this gives us subtraction.
xor(Bx[0], B[0], Op);
xor(Bx[1], B[1], Op);
xor(Bx[2], B[2], Op);
xor(Bx[3], B[3], Op);
xor(Bx[4], B[4], Op);
xor(Bx[5], B[5], Op);
xor(Bx[6], B[6], Op);
xor(Bx[7], B[7], Op);
xor(C, C7, Op);
// Carry = C7 for addition, Carry = not(C7) for subtraction.
carry_select_adder csa(S, C7, V, A, Bx, Op);
endmodule // carry_select_adder_subtractor
module carry_select_adder(S, C, V, A, B, Cin);
output [7:0] S; // The 16-bit sum.
output C; // The 1-bit carry.
output V; // The 1-bit overflow status.
input [7:0] A; // The 16-bit augend.
input [7:0] B; // The 16-bit addend.
input Cin; // The initial carry in.
wire [3:0] S1_0; // Nibble 1 sum output with carry input 0.
wire [3:0] S1_1; // Nibble 1 sum output with carry input 1.
wire C1_0; // Nibble 1 carry output with carry input 0.
wire C1_1; // Nibble 1 carry output with carry input 1.
wire C0; // Nibble 0 carry output used to select multiplexer output.
wire C1; // Nibble 1 carry output used to select multiplexer output.
wire V0; // Nibble 0 overflow output.
wire V1_0; // Nibble 1 overflow output with carry input 0.
wire V1_1; // Nibble 1 overflow output with carry input 1.
ripple_carry_adder rc_nibble_0(S[3:0], C0, V0, A[3:0], B[3:0], Cin); // Calculate S nibble 0.
ripple_carry_adder rc_nibble_1_carry_0(S1_0, C1_0, V1_0, A[7:4], B[7:4], 0); // Calculate S nibble 1 with carry input 0.
ripple_carry_adder rc_nibble_1_carry_1(S1_1, C1_1, V1_1, A[7:4], B[7:4], 1); // Calculate S nibble 1 with carry input 1.
multiplexer_2_1 #(1) muxc1(C1, C1_0, C1_1, C0); // C0 selects the carry output for nibble 1.
multiplexer_2_1 #(4) muxs1(S[7:4], S1_0, S1_1, C0); // C0 selects the result for nibble 1.
endmodule // carry_select_adder
module ripple_carry_adder(S, C, V, A, B, Cin);
output [3:0] S; // The 4-bit sum.
output C; // The 1-bit carry.
output V; // The 1-bit overflow status.
input [3:0] A; // The 4-bit augend.
input [3:0] B; // The 4-bit addend.
input Cin; // The carry input.
wire C0; // The carry out bit of fa0, the carry in bit of fa1.
wire C1; // The carry out bit of fa1, the carry in bit of fa2.
wire C2; // The carry out bit of fa2, the carry in bit of fa3.
full_adder fa0(S[0], C0, A[0], B[0], Cin); // Least significant bit.
full_adder fa1(S[1], C1, A[1], B[1], C0);
full_adder fa2(S[2], C2, A[2], B[2], C1);
full_adder fa3(S[3], C, A[3], B[3], C2); // Most significant bit.
xor(V, C, C2); // Overflow
endmodule // ripple_carry_adder
module full_adder(S, Cout, A, B, Cin);
output S;
output Cout;
input A;
input B;
input Cin;
wire w1;
wire w2;
wire w3;
wire w4;
xor(w1, A, B);
xor(S, Cin, w1);
and(w2, A, B);
and(w3, A, Cin);
and(w4, B, Cin);
or(Cout, w2, w3, w4);
endmodule // full_adder
module multiplexer_2_1(X, A0, A1, S);
parameter WIDTH=8; // How many bits wide are the lines
output [WIDTH-1:0] X; // The output line
input [WIDTH-1:0] A1; // Input line with id 1'b1
input [WIDTH-1:0] A0; // Input line with id 1'b0
input S; // Selection bit
assign X = (S == 1'b0) ? A0 : A1;
endmodule // multiplexer_2_1
module multiplexer_8_1(X, A0, A1, A2, A3, A4, A5, A6, A7, S);
parameter WIDTH=8; // How many bits wide are the lines
output [WIDTH-1:0] X; // The output line
input [WIDTH-1:0] A7; // Input line with id 3'b111
input [WIDTH-1:0] A6; // Input line with id 3'b110
input [WIDTH-1:0] A5; // Input line with id 3'b101
input [WIDTH-1:0] A4; // Input line with id 3'b100
input [WIDTH-1:0] A3; // Input line with id 3'b011
input [WIDTH-1:0] A2; // Input line with id 3'b010
input [WIDTH-1:0] A1; // Input line with id 3'b001
input [WIDTH-1:0] A0; // Input line with id 3'b000
input [2:0] S;
assign X = (S[2] == 0
? (S[1] == 0
? (S[0] == 0
? A0 // {S2,S1,S0} = 3'b000
: A1) // {S2,S1,S0} = 3'b001
: (S[0] == 0
? A2 // {S2,S1,S0} = 3'b010
: A3)) // {S2,S1,S0} = 3'b011
: (S[1] == 0
? (S[0] == 0
? A4 // {S2,S1,S0} = 3'b100
: A5) // {S2,S1,S0} = 3'b101
: (S[0] == 0
? A6 // {S2,S1,S0} = 3'b110
: A7))); // {S2,S1,S0} = 3'b111
endmodule // multiplexer_8_1
沒有留言:
張貼留言