module alu (a,b,op,alu_go,result,flags); input [15:0] a, b; input [3:0] op; input alu_go; output [15:0] result; output [3:0] flags; reg [15:0] result,a_reg, b_reg, result_reg; reg [3:0] op_reg, flags, newflags; parameter ALUOP_NOP = 4'h0; parameter ALUOP_AND = 4'h1; parameter ALUOP_OR = 4'h2; parameter ALUOP_NOT = 4'h3; parameter ALUOP_XOR = 4'h4; parameter ALUOP_ADD = 4'h5; parameter ALUOP_SUB = 4'h6; parameter ALUOP_MULH = 4'h7; parameter ALUOP_MULL = 4'h8; parameter ALUOP_DIV = 4'h9; parameter ALUOP_MOD = 4'hA; parameter ALUOP_NEG = 4'hB; parameter ALUOP_COMP = 4'hC; parameter ALUOP_INC_A= 4'hD; parameter ALUOP_B = 4'hE; parameter ALUOP_DEC_A= 4'hF; parameter TALUOP = 50; initial begin op_reg = 0; newflags = 0;flags = 0;result_reg = 0; end always @(posedge alu_go) begin if (~(op == ALUOP_NOP)) begin op_reg = op;a_reg = a;b_reg = b;newflags = 0; #1 $display("%t %m Befehl %dd(%hh,%hh) wird ausgeführt.",$time, op, a, b); case (op) // flags reihenfolge: ocnz (overflow, carry, negativ, zero) ALUOP_AND: #TALUOP result_reg = a & b; // oberere flags bleiben null ALUOP_OR: #TALUOP result_reg = a | b; // " ALUOP_NOT: #TALUOP result_reg = ~a; // " ALUOP_XOR: #TALUOP result_reg = a ^ b; // " ALUOP_INC_A:#TALUOP result_reg = a+1; // " ALUOP_DEC_A:#TALUOP result_reg = a-1; // " ALUOP_B: #TALUOP result_reg = b; // " ALUOP_ADD: begin #TALUOP result_reg = a + b; newflags[2] = (a+b > 'hFFFF); // ab~result + ~a~by newflags[3] = a[15] && b[15] && ~result_reg[15] || ~a[15] && ~b[15] && result_reg[15]; end ALUOP_SUB: begin #TALUOP result_reg = a - b; newflags[2] = (a+b > 'hFFFF); // a~b~result + ~aby andersherum als im Motorola!! newflags[3] = a[15] && ~b[15] && ~result_reg[15] || ~a[15] && b[15] && result_reg[15]; end ALUOP_COMP: begin #TALUOP result_reg = a - b; newflags[2] = (a+b > 'hFFFF); // a~b~result + ~aby andersherum als im Motorola!! newflags[3] = a[15] && ~b[15] && ~result_reg[15] || ~a[15] && b[15] && result_reg[15]; end ALUOP_MULH: begin #TALUOP result_reg = ((a * b) / 'h10000); newflags[3] = ~((a * b) % 'h10000 == 0);// unteres wort <> 0 end ALUOP_MULL: begin #TALUOP result_reg = a * b; newflags[3] = ~((a * b) / 'h10000 == 0); // oberes wort <> 0 end ALUOP_DIV: begin #TALUOP result_reg = a / b; newflags[3] = ~((a % b) == 0); // rest <> 0 end ALUOP_MOD: begin #TALUOP result_reg = a % b; newflags[3] = ~((a / b) == 0); // quotient <> 0 end ALUOP_NEG: begin newflags[3] = (b == 'h8000); // 32768 gibt es nicht #TALUOP result_reg = - a; end default: #TALUOP result_reg = 1234; endcase newflags[1] = result_reg[15]; // Negativ-bit newflags[0] = (result_reg == 0); // Zero-bit flags = newflags; newflags = 0; $display("%t %m Ergebnis (%h, %h) ist %hh (%bb)",$time,a,b, result_reg, flags); if (op != ALUOP_COMP) result=result_reg; else result=a; end end endmodule