module decode #( parameter UROM = "" , parameter UIP_BITS = 15 , parameter UROM_BITS = 8 , parameter BUS_BITS = 16 , parameter OPCODE_BITS = 8 ) ( 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 [OPCODE_BITS-1:0] opcode; bit [BUS_BITS-1:0] a; bit [BUS_BITS-1:0] b; bit needmore; bit [UIP_BITS-1:0] new_uip; assign new_uip = {opcode, {(UIP_BITS-OPCODE_BITS){1'b0}}}; typedef enum { CLEAR , DECODE , OUTADDR , OUTADDR_SEL0 , OUTADDR_SEL1 , OUTDATA , OUTDATA_SEL0 , OUTDATA_SEL1 } CtrlBit; bit [UROM_BITS-1:0] ctrl; urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl); bit [1:0] asel; assign asel = {ctrl[OUTADDR_SEL1], ctrl[OUTADDR_SEL0]}; bit [1:0] dsel; assign dsel = {ctrl[OUTDATA_SEL1], ctrl[OUTDATA_SEL0]}; bit [BUS_BITS-1:0] aout; assign aout = (asel == 0) ? a : (asel == 1) ? b : (asel == 2) ? {{(BUS_BITS-UIP_BITS){1'b0}}, new_uip} : {(BUS_BITS){1'bX}}; assign abus = ctrl[OUTADDR] ? aout : {(BUS_BITS){1'bZ}}; bit [BUS_BITS-1:0] dout; assign dout = (dsel == 0) ? a : (dsel == 1) ? b : (dsel == 2) ? {{(BUS_BITS-1){1'b0}}, needmore} : {(BUS_BITS){1'bX}}; assign dbus = ctrl[OUTDATA] ? dout : {(BUS_BITS){1'bZ}}; always @(posedge clk) begin if (reset || ctrl[CLEAR]) begin opcode <= 0; a <= 0; b <= 0; needmore <= 1; end else if (ctrl[DECODE]) begin automatic bit m = dbus[7]; automatic bit i = dbus[6]; automatic bit [1:0] field = dbus[5:4]; automatic bit [3:0] shift = dbus[3:0]; needmore <= m; if (field == 0) begin opcode <= {i ? ~opcode[OPCODE_BITS-1-4:0] : opcode[OPCODE_BITS-1-4:0], shift}; end else if (field == 2) begin a <= {i ? ~a[BUS_BITS-1-4:0] : a[BUS_BITS-1-4:0], shift}; end else if (field == 3) begin b <= {i ? ~b[BUS_BITS-1-4:0] : b[BUS_BITS-1-4:0], shift}; end end end endmodule