data/full_repos/permissive/447223480/05_mmio/cpu.v
data/verilator_xmls/4ef42fbe-9af4-40ec-88e9-c5fb4ada63cd.xml
module cpu(
	clock, reset,
	paddr, pread, pwrite, pread_req, pwrite_req, psize
);
	input clock;
	input reset;
	output [31:0] paddr;
	input [31:0] pread;
	output [31:0] pwrite;
	output pread_req, pwrite_req;
	output [2:0] psize;

	reg [31:0] pc;
	wire [31:0] next_pc;

	always @(posedge clock) begin
		if (reset) begin
			pc <= 32'd0;
		end else begin
			pc <= next_pc;
		end
	end

	wire [15:0] inst;
	wire [31:0] daddr, dread, dwrite;
	wire dread_req, dwrite_req;
	wire [2:0] dsize;
	wire dread_se;

	mem mem(
		.clock(clock), .iaddr(pc), .iread(inst),
		.daddr(daddr), .dread(dread), .dwrite(dwrite),
		.dread_req(dread_req), .dwrite_req(dwrite_req), .dsize(dsize), .dread_se(dread_se),
		.paddr(paddr), .pread(pread), .pwrite(pwrite),
		.pread_req(pread_req), .pwrite_req(pwrite_req), .psize(psize)
	);

	wire [4:0] Rm, Rs, Rd;
	wire [31:0] Rm_data, Rs_data, immediate;
	wire [31:0] new_value;
	wire is_immediate;
	wire [9:0] alu_op;
	wire is_jmp, jmp_if_zero, jmp_absolute;

	decoder decoder(
		.inst(inst),
		.Rm(Rm), .Rs(Rs), .Rd(Rd), .immediate(immediate),
		.is_immediate(is_immediate), .alu_op(alu_op),
		.dread_req(dread_req), .dwrite_req(dwrite_req), .dsize(dsize), .dread_se(dread_se),
		.is_jmp(is_jmp), .jmp_if_zero(jmp_if_zero), .jmp_absolute(jmp_absolute)
	);

	regs regs(
		.clock(clock), .reset(reset),
		.Rm(Rm), .Rs(Rs), .Rd(Rd),
		.Rm_data(Rm_data), .Rs_data(Rs_data), .Rd_data(new_value)
	);

	wire [31:0] alu_in2 = is_immediate ? immediate : Rs_data;
	wire [31:0] alu_answer;
	wire alu_is_zero;

	alu alu(
		.in1(Rm_data), .in2(alu_in2), .op(alu_op), .answer(alu_answer), .is_zero(alu_is_zero)
	);

	wire [31:0] jmp_base = jmp_absolute ? Rm_data : pc;
	wire [31:0] jmp_target_raw = jmp_base + immediate;
	wire [31:0] jmp_target = {jmp_target_raw[31:1], 1'b0};
	wire [31:0] pc_next_inst = pc + 32'd2;

	wire jmp_taken = is_jmp & (alu_is_zero ^ ~jmp_if_zero);
	assign next_pc = jmp_taken ? jmp_target : pc_next_inst;

	wire [31:0] ex_result = is_jmp ? pc_next_inst : alu_answer;

	assign daddr = ex_result;
	assign dwrite = Rs_data;

	assign new_value = dread_req ? dread : ex_result;

endmodule
module cpu(
	clock, reset,
	paddr, pread, pwrite, pread_req, pwrite_req, psize
);

	input clock;
	input reset;
	output [31:0] paddr;
	input [31:0] pread;
	output [31:0] pwrite;
	output pread_req, pwrite_req;
	output [2:0] psize;

	reg [31:0] pc;
	wire [31:0] next_pc;

	always @(posedge clock) begin
		if (reset) begin
			pc <= 32'd0;
		end else begin
			pc <= next_pc;
		end
	end

	wire [15:0] inst;
	wire [31:0] daddr, dread, dwrite;
	wire dread_req, dwrite_req;
	wire [2:0] dsize;
	wire dread_se;

	mem mem(
		.clock(clock), .iaddr(pc), .iread(inst),
		.daddr(daddr), .dread(dread), .dwrite(dwrite),
		.dread_req(dread_req), .dwrite_req(dwrite_req), .dsize(dsize), .dread_se(dread_se),
		.paddr(paddr), .pread(pread), .pwrite(pwrite),
		.pread_req(pread_req), .pwrite_req(pwrite_req), .psize(psize)
	);

	wire [4:0] Rm, Rs, Rd;
	wire [31:0] Rm_data, Rs_data, immediate;
	wire [31:0] new_value;
	wire is_immediate;
	wire [9:0] alu_op;
	wire is_jmp, jmp_if_zero, jmp_absolute;

	decoder decoder(
		.inst(inst),
		.Rm(Rm), .Rs(Rs), .Rd(Rd), .immediate(immediate),
		.is_immediate(is_immediate), .alu_op(alu_op),
		.dread_req(dread_req), .dwrite_req(dwrite_req), .dsize(dsize), .dread_se(dread_se),
		.is_jmp(is_jmp), .jmp_if_zero(jmp_if_zero), .jmp_absolute(jmp_absolute)
	);

	regs regs(
		.clock(clock), .reset(reset),
		.Rm(Rm), .Rs(Rs), .Rd(Rd),
		.Rm_data(Rm_data), .Rs_data(Rs_data), .Rd_data(new_value)
	);

	wire [31:0] alu_in2 = is_immediate ? immediate : Rs_data;
	wire [31:0] alu_answer;
	wire alu_is_zero;

	alu alu(
		.in1(Rm_data), .in2(alu_in2), .op(alu_op), .answer(alu_answer), .is_zero(alu_is_zero)
	);

	wire [31:0] jmp_base = jmp_absolute ? Rm_data : pc;
	wire [31:0] jmp_target_raw = jmp_base + immediate;
	wire [31:0] jmp_target = {jmp_target_raw[31:1], 1'b0};
	wire [31:0] pc_next_inst = pc + 32'd2;

	wire jmp_taken = is_jmp & (alu_is_zero ^ ~jmp_if_zero);
	assign next_pc = jmp_taken ? jmp_target : pc_next_inst;

	wire [31:0] ex_result = is_jmp ? pc_next_inst : alu_answer;

	assign daddr = ex_result;
	assign dwrite = Rs_data;

	assign new_value = dread_req ? dread : ex_result;

endmodule