14 `define CW_MEM_WR (16'b1 << `CWB_MEM_WR)
15 `define CW_MEM_EN (16'b1 << `CWB_MEM_EN)
16 `define CW_PC_WR (16'b1 << `CWB_PC_WR)
17 `define CW_IR_WR (16'b1 << `CWB_IR_WR)
18 `define CW_WB (16'b1 << `CWB_WB)
20 function [15:0] lshift(input [15:0] value, input [15:0] shamt);
21 if (shamt[15] == 1'b0)
22 lshift = value << shamt;
24 lshift = value >> -shamt;
34 wire signed [15:0] in1s = in1;
35 wire signed [15:0] in2s = in2;
39 3'b000: out = in1 + in2;
40 3'b001: out = in1 - in2;
41 3'b010: out = in1 & in2;
42 3'b011: out = in1 | in2;
43 3'b100: out = lshift(in1, in2);
44 3'b101: out = in1 ^ in2;
45 3'b110: out = { 15'b0, (in1 < in2) };
46 3'b111: out = { 15'b0, (in1s < in2s) };
53 output reg [15:0] mem_addr,
54 inout [15:0] mem_data,
62 wire [15:0] alu_in2, alu_out;
63 reg [15:0] regs [7:1];
64 reg [15:0] rd, pc, next_pc, instr;
65 reg [15:0] control_word;
69 wire [2:0] rd_sel = instr[15:12] != 4'b1110 ? instr[10:8] : 3'h7;
70 wire [2:0] rs_sel = ifmt == `FMT_I ? instr[10:8] : instr[6:4];
71 wire [2:0] rt_sel = instr[2:0];
72 wire [2:0] alu_op = ifmt == `FMT_R ? { instr[11], instr[7], instr[3] } : { instr[11], 2'b00 };
73 wire [15:0] rs = regs[rs_sel];
74 wire [15:0] rt = regs[rt_sel];
75 wire [15:0] alu_in1 = rs;
77 assign debug = control_word[7:0];
86 always@ (posedge clk or posedge rst) begin
89 else if (control_word[`CWB_PC_WR] )
93 always@ (posedge clk or posedge rst) begin
96 else if (control_word[`CWB_IR_WR])
100 always@ (negedge clk or posedge rst) begin
112 control_word <= `CW_MEM_EN | `CW_IR_WR | `CW_PC_WR;
121 control_word <= `CW_WB;
128 control_word <= `CW_WB | `CW_PC_WR;
134 control_word <= `CW_WB;
139 rd <= instr[11] ? imm : (imm << 8);
140 control_word <= `CW_WB;
146 control_word <= `CW_MEM_EN;
153 control_word <= `CW_MEM_WR;
159 if ((rs == rt) ^ instr[12]) begin
161 control_word <= `CW_PC_WR;
163 else control_word <= 0;
170 control_word <= `CW_WB | `CW_PC_WR;
176 control_word <= `CW_PC_WR;
186 control_word <= `CW_WB;
198 always@ (posedge clk) begin
199 if (control_word[`CWB_WB] && rd_sel != 0)
205 4'b000?: ifmt = `FMT_R;
206 4'b001?: ifmt = `FMT_I;
207 4'b01??: ifmt = `FMT_L;
208 4'b10??: ifmt = `FMT_S;
209 4'b110?: ifmt = `FMT_UD;
210 4'b111?: ifmt = `FMT_J;
216 `FMT_I: imm2 = { {8{instr[7]}}, instr[7:0] };
217 `FMT_L: imm2 = { {10{instr[11]}}, instr[11], instr[7:3] };
218 `FMT_S: imm2 = { {10{instr[11]}}, instr[11:7], instr[3] };
219 `FMT_J: imm2 = { {4{instr[11]}}, instr[11:0] };
223 4'b1000: imm = imm2 << 1;
224 4'b101?: imm = imm2 << 1;
225 4'b111?: imm = imm2 << 1;
230 assign alu_in2 = ifmt == `FMT_R ? rt : imm;
231 assign mem_wr = control_word[`CWB_MEM_WR];
232 assign mem_en = control_word[`CWB_MEM_EN];
233 assign mem_data = control_word[`CWB_MEM_WR] ? rs : 16'bz;