module opw(inc_pc, ld_mdr, ld_ir, ld_reg,mem_cs, mem_wr, mem_sflag,set_sel_a, sel_reg_a_src, sel_op_a, sel_op_b, sel_mem_addr, sel_pc,clock, new_sel_a, load_pc, alu_go,opc, alu_flags, mode); `include ".\\timing.v" `include ".\\defs.v" output [5:0] opc; output [3:0] alu_flags, mode; reg [5:0] opc; reg [3:0] mode; reg [15:0] current_pc, a_out_driver; input inc_pc, load_pc, ld_mdr, ld_ir, ld_reg; input mem_cs, mem_wr, mem_sflag; input sel_reg_a_src, sel_op_a, sel_op_b, sel_pc, alu_go; input clock, set_sel_a; input [1:0] sel_mem_addr; input [2:0] new_sel_a; wire [15:0] w_current_pc; wire [15:0] w_mdr_out; pc_unit pc ( .new_address(w_mdr_out), .current_pc(w_current_pc), .clock(clock), .load(load_pc), .incpc(inc_pc) ); reg [15:0] mem_data; wire [15:0] w_abus; wire [15:0] w_databus; sram sram ( .CS(mem_cs), .WR(mem_wr), .ABUS(w_abus), .DATABUS(w_databus), .SFLAG(mem_sflag) ); always @(w_databus) begin $display("%t %m Databus (abus:%hh) changed: data = %hh, ld_mdr= %bb ", $time,w_abus, w_databus, ld_mdr); end always @(w_mdr_out) begin $display("%t %m w_mdr_out changed: w_mdr_out= %hh", $time, w_mdr_out); end register mdr( .clock(clock), .di(w_databus), .do(w_mdr_out), .load(ld_mdr) ); wire [15:0] w_ir_out; register ir( .clock(clock), .di(w_databus), .do(w_ir_out), .load(ld_ir) ); wire [15:0] w_a_in, w_alu_out; mux_16bit_2to1 mux_a_in ( .sel(sel_reg_a_src), .out(w_a_in), .in0(w_alu_out), .in1(w_mdr_out) ); wire [2:0] w_sel_a; mux_3bit_2to1 mux_sel_a( .sel(set_sel_a), .out(w_sel_a), .in0(w_ir_out[5:3]), .in1(new_sel_a) ); always @(w_ir_out) begin opc = w_ir_out[15:10]; mode = w_ir_out[9:6]; $display("%t %m OPC: %h, w_ir_out: %h, mode: %d", $time, opc, w_ir_out[15:10], mode); end wire [15:0] w_a_out, w_b_out; registersatzb registersatz( .a_in(w_a_in), .sel_a(w_sel_a), .sel_b(w_ir_out[2:0]), .a_out(w_a_out), .b_out(w_b_out), .load(ld_reg), .clock(clock) ); wire [15:0] w_op_a; mux_16bit_2to1 mux_a_in ( .sel(sel_op_a), .out(w_op_a), .in0(w_mdr_out), .in1(w_a_out) ); wire [15:0] w_op_b; mux_16bit_2to1 mux_b_in ( .sel(sel_op_b), .out(w_op_b), .in0(w_mdr_out), .in1(w_b_out) ); wire [3:0] w_alu_op; alu alu( .a(w_op_a), .b(w_op_b), .op(w_alu_op), .alu_go(alu_go), .result(w_alu_out), .flags(alu_flags) ); opc_to_alu_op op_converter( .opc(w_ir_out[15:10]), .alu_op(w_alu_op) ); mux_16bit_4to1 mux_mem_in ( .sel(sel_mem_addr), .out(w_abus), .in0(w_a_out), .in1(w_b_out), .in2(w_current_pc), .in3(w_mdr_out) ); always @(mem_wr or w_ir_out[15:10]) begin if ((w_ir_out[15:10] == jsr) && (mem_wr == 1)) begin assign a_out_driver = w_current_pc; $display("%t %m Connecting PC with Databus", $time); end else begin case(mem_wr) 0: #20 assign a_out_driver = 16'bzzzzzzzzzzzzzzzz; // Etwas hingebogen 1: assign a_out_driver = w_a_out; endcase end $display("%t %m a_out_driver changed to: %hh", $time, a_out_driver); end assign w_databus = a_out_driver; endmodule