module alu #( parameter UROM = "" , parameter UIP_BITS = 15 , parameter UROM_BITS = 8 , parameter BUS_BITS = 16 ) ( input bit clk , input bit reset , input bit [UIP_BITS-1:0] uip , inout bit [BUS_BITS-1:0] abus , inout bit [BUS_BITS-1:0] dbus ); bit [BUS_BITS-1:0] x; typedef enum { OP , OP_SEL0 , OP_SEL1 , OP_SEL2 , OUTADDR , OUTDATA } CtrlBit; bit [UROM_BITS-1:0] ctrl; urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl); bit [2:0] sel; assign sel = {ctrl[OP_SEL2], ctrl[OP_SEL1], ctrl[OP_SEL0]}; bit [BUS_BITS-1:0] and_result; bit [BUS_BITS-1:0] or_result; bit [BUS_BITS-1:0] xor_result; bit [BUS_BITS-1:0] add_result; bit [BUS_BITS-1:0] sub_result; bit [BUS_BITS-1:0] cmp_result; bit [BUS_BITS-1:0] lshift_result; bit [BUS_BITS-1:0] rshift_result; assign and_result = abus & dbus; assign or_result = abus | dbus; assign xor_result = abus ^ dbus; assign add_result = abus + dbus; assign sub_result = abus - dbus; assign cmp_result = {{(BUS_BITS-6){1'b0}}, (abus != 0) & (dbus != 0), (abus != 0) | (dbus != 0), (abus != 0) ^ (dbus != 0), abus > dbus, abus == dbus, abus < dbus}; assign lshift_result = {dbus[BUS_BITS-2:0], abus[0]}; assign rshift_result = {abus[BUS_BITS-1], dbus[BUS_BITS-1:1]}; bit [BUS_BITS-1:0] newx; assign newx = (sel == 0) ? and_result : (sel == 1) ? or_result : (sel == 2) ? xor_result : (sel == 3) ? add_result : (sel == 4) ? sub_result : (sel == 5) ? cmp_result : (sel == 6) ? lshift_result : (sel == 7) ? rshift_result : {(BUS_BITS){1'bX}}; assign abus = ctrl[OUTADDR] ? x : {(BUS_BITS){1'bZ}}; assign dbus = ctrl[OUTDATA] ? x : {(BUS_BITS){1'bZ}}; always @(posedge clk) begin if (ctrl[OP]) begin x <= newx; end end endmodule