`include "def.h" module poco( input clk, rst_n, input [`DATA_W-1:0] idatain, input [`DATA_W-1:0] ddatain, output [`DATA_W-1:0] iaddr, daddr, output [`DATA_W-1:0] ddataout, output we_n); reg [`DATA_W-1:0] pc; reg [`DATA_W-1:0] ir; reg [`STAT_W-1:0] stat; wire [`DATA_W-1:0] rf_a, rf_b ; reg [`DATA_W-1:0] rf_c; //wire for always wire [`DATA_W-1:0] alu_y; reg [`DATA_W-1:0] alu_b; //wire for always wire [`OPCODE_W-1:0] opcode; wire [`OPCODE_W-1:0] func; wire [`REG_W-1:0] rs, rd, cadr; reg [`SEL_W-1:0] com; //wire for always wire [`IMM_W-1:0] imm; wire pcsel; reg rwe; // wire for always wire st_op, bez_op, bnz_op, bmi_op, bpl_op ; wire jmp_op, jal_op, jr_op; assign ddataout = rf_a; assign iaddr = pc; assign daddr = rf_b; assign {opcode, rd, rs, func} = ir; assign imm = ir[`IMM_W-1:0]; assign st_op = stat[`EX] & (opcode == `OP_REG) & (func == `F_ST); assign jr_op = stat[`EX] & (opcode == `OP_REG) & (func == `F_JR); assign bez_op = stat[`EX] & (opcode == `OP_BEZ); assign bnz_op = stat[`EX] & (opcode == `OP_BNZ); assign bpl_op = stat[`EX] & (opcode == `OP_BPL); assign bmi_op = stat[`EX] & (opcode == `OP_BMI); assign jmp_op = stat[`EX] & (opcode == `OP_JMP); assign jal_op = stat[`EX] & (opcode == `OP_JAL); assign we_n = ~st_op; always @( * ) begin if(stat[`EX]) case(opcode) `OP_REG: if(func == `F_LD) begin rwe <= `ENABLE; rf_c <= ddatain; com <= func[`SEL_W-1:0]; alu_b <= rf_b; end else if(func[4:3] == 2'b00) begin rwe <= `ENABLE; rf_c <= alu_y; com <= func[`SEL_W-1:0]; alu_b <= rf_b; end else begin rwe <= `DISABLE; rf_c <= alu_y; com <= func[`SEL_W-1:0]; alu_b <= rf_b; end `OP_LDI: begin rwe <= `ENABLE; rf_c <= alu_y; com <= `ALU_THB; alu_b <= {{8{imm[7]}},imm} ; end `OP_LDIU: begin rwe <= `ENABLE; rf_c <= alu_y; com <= `ALU_THB; alu_b <= {8'b0,imm} ; end `OP_LDHI: begin rwe <= `ENABLE; rf_c <= alu_y; com <= `ALU_THB; alu_b <= {imm,8'b0} ; end `OP_ADDI: begin rwe <= `ENABLE; rf_c <= alu_y; com <= `ALU_ADD; alu_b <= {{8{imm[7]}},imm} ; end `OP_ADDIU: begin rwe <= `ENABLE; rf_c <= alu_y; com <= `ALU_ADD; alu_b <= {8'b0,imm} ; end `OP_JAL: begin rwe <= `ENABLE; rf_c <= pc; com <= func[`SEL_W-1:0]; alu_b <= rf_b ; end default: begin rwe <= `DISABLE; rf_c <= alu_y; com <= func[`SEL_W-1:0]; alu_b <= rf_b ; end endcase else begin rwe <= `DISABLE; rf_c <= alu_y; com <= func[`SEL_W-1:0]; alu_b <= rf_b ; end end assign cadr = jal_op ? 3'b111 : rd; alu alu_1(.a(rf_a), .b(alu_b), .s(com), .y(alu_y)); rfile rfile_1(.clk(clk), .a(rf_a), .aadr(rd), .b(rf_b), .badr(rs), .c(rf_c), .cadr(cadr), .we(rwe)); assign pcsel = (bez_op & rf_a == 16'b0 ) | (bnz_op & rf_a != 16'b0) | (bmi_op & rf_a[15] == 1 ) | (bpl_op & rf_a[15] == 0) ; always @(posedge clk or negedge rst_n) begin if(!rst_n) pc <= 0; else if(jmp_op | jal_op) pc <= pc +{{5{ir[10]}},ir[10:0]} ; else if(pcsel) pc <= pc +{{8{imm[7]}},imm} ; else if(jr_op) pc <= rf_a; else if(stat[`IF]) pc <= pc+1; end always @(posedge clk or negedge rst_n) begin if(!rst_n) ir <= 0; else if(stat[`IF]) ir <= idatain; end always @(posedge clk or negedge rst_n) begin if(!rst_n) stat <= `STAT_IF; else case (stat) `STAT_IF: stat <= `STAT_EX; `STAT_EX: stat <= `STAT_IF; endcase end endmodule