cpu模块主要是将各个模块组合正在一起
数据通路图:
`timescale 1ns / 1ps
module cpu(
input clk, //时钟沿信号
input rst, //复位信号
output [31:0] pcdata, //指令码地址pc
input [31:0] inst, //输入的指令码
input [31:0] rdata, //从ram读入的数据
output [31:0] addr, //写入ram的地址
output [31:0] wdata, //写入ram的数据
output im_r, //指令寄存器读信号
output dm_cs, //
output dm_r, //数据寄存器读信号
output dm_w, //数据寄存器写信号
output [5:0] op_out, //调试输出用...
output Z //调试输出用...
);
wire [31:0] npc_out;
wire [31:0] npc_in;
ADDU NPC( //NPC模块
.a(npc_in), //功能:每次将pc+4,指向下一条指令地址
.b(32'd4),
.c(npc_out)
);
wire [31:0] mux1_in1;
wire [31:0] mux1_in2;
wire [31:0] mux1_out;
wire mux1_m;
MUX MUX1( //数据选择器
.m(mux1_m), //功能:根据不同的信号选择不用的输入作为输出
.data_in1(mux1_in1),
.data_in2(mux1_in2),
.data_out(mux1_out)
);
wire [31:0] mux3_in1;
wire [31:0] mux3_in2;
wire [31:0] mux3_out;
wire mux3_m; //数据选择器
MUX MUX3(
.m(mux3_m),
.data_in1(mux3_in1),
.data_in2(mux3_in2),
.data_out(mux3_out)
);
wire [31:0] mux4_in1;
wire [31:0] mux4_in2;
wire [31:0] mux4_out;
wire mux4_m; //数据选择器
MUX MUX4(
.m(mux4_m),
.data_in1(mux4_in1),
.data_in2(mux4_in2),
.data_out(mux4_out)
);
wire [31:0] mux5_in1;
wire [31:0] mux5_in2;
wire [31:0] mux5_out;
wire mux5_m;
MUX MUX5( //数据选择器
.m(mux5_m),
.data_in1(mux5_in1),
.data_in2(mux5_in2),
.data_out(mux5_out)
);
wire [31:0] mux6_in1;
wire [31:0] mux6_in2;
wire [31:0] mux6_out;
wire mux6_m;
MUX MUX6( //数据选择器
.m(mux6_m),
.data_in1(mux6_in1),
.data_in2(mux6_in2),
.data_out(mux6_out)
);
wire [31:0] mux7_in1;
wire [31:0] mux7_in2;
wire [31:0] mux7_out;
wire mux7_m;
MUX MUX7( //数据选择器
.m(mux7_m),
.data_in1(mux7_in1),
.data_in2(mux7_in2),
.data_out(mux7_out)
);
wire [31:0] mux8_in1;
wire [31:0] mux8_in2;
wire [31:0] mux8_out;
wire mux8_m;
MUX MUX8( //数据选择器
.m(mux8_m),
.data_in1(mux8_in1),
.data_in2(mux8_in2),
.data_out(mux8_out)
);
wire [31:0] mux2_in1;
wire [31:0] mux2_in2;
wire [31:0] mux2_in3;
wire [31:0] mux2_out;
wire [1:0] mux2_m;
MUXS MUX2( //数据选择器
.m(mux2_m),
.data_in1(mux2_in1),
.data_in2(mux2_in2),
.data_in3(mux2_in3),
.data_out(mux2_out)
);
wire [4:0] ext5_in;
wire [31:0] ext5_out;
wire ext5_c;
Ext_imm5 ext5( //数据扩充器
.idata(ext5_in), //将数据扩充为32位
.odata(ext5_out),
.ca(ext5_c)
);
wire [15:0] ext16_in;
wire [31:0] ext16_out;
wire ext16_c;
Ext_imm16 ext16( //数据扩充器
.idata(ext16_in),
.odata(ext16_out),
.ca(ext16_c)
);
wire [15:0] ext18_in;
wire [31:0] ext18_out;
wire ext18_c;
Ext_imm18 ext18( //数据扩充器
.idata(ext18_in),
.odata(ext18_out),
.ca(ext18_c)
);
// wire pc_ena;
wire pc_clk;
wire pc_rst;
assign pc_rst=rst;
wire [31:0] pc_data_in;
wire [31:0] pc_data_out;
wire [3:0] pc_data31_28;
PC_Reg PC( //PC寄存器
.clk(pc_clk), //功能:存放下一条指令的地址
.rst(pc_rst),
.ena(1'b1),
.data_in(pc_data_in),
.data_out(pc_data_out),
.pc31_28(pc_data31_28)
);
// wire imem_wena;
// assign imem_wena=0;
// wire [31:0] imem_addr;
// wire [31:0] imem_data_in;
// assign imem_data_in=32'b0;
wire [31:0] imem_data_out;
wire [25:0] target=imem_data_out[25:0];
wire [4:0] sa=imem_data_out[10:6];
wire [4:0] Rsc=imem_data_out[25:21];
wire [4:0] Rtc=imem_data_out[20:16];
wire [4:0] Rdc=imem_data_out[15:11];
wire [5:0] op=imem_data_out[31:26];
wire [5:0] func=imem_data_out[5:0];
wire [15:0] imm16=imem_data_out[15:0];
/* IMEM imem(
.clk(clk),
.wena(imem_wena),
.addr(imem_addr),
.data_in(imem_data_in),
.data_out(imem_data_out)
);*/
wire rf_clk;
wire rf_rst;
assign rf_rst=rst;
wire rf_we;
wire [4:0]rf_rsc;
wire [4:0]rf_rtc;
wire [4:0]rf_rdc;
wire [31:0]rf_rd;
wire [31:0]rf_rs;
wire [31:0]rf_rt;
RegFiles cpu_ref( //通用寄存器模块
.clk(rf_clk),
.rst(rf_rst),
.we(rf_we),
.raddr1(rf_rsc),
.rdata1(rf_rs),
.raddr2(rf_rtc),
.rdata2(rf_rt),
.waddr(rf_rdc),
.wdata(rf_rd)
);
wire [31:0] alu_a;
wire [31:0] alu_b;
wire [31:0] alu_r;
wire [3:0] aluc;
wire z;
wire c;
wire n;
wire o;
alu ALU( //ALU模块
.a(alu_a),
.b(alu_b),
.r(alu_r),
.aluc(aluc),
.zero(z),
.carry(c),
.negative(n),
.overflow(o)
);
wire [31:0] add_a;
wire [31:0] add_b;
wire [31:0] add_c;
ADD add(
.a(add_a),
.b(add_b),
.c(add_c)
);
wire dmem_cs;
wire dmem_we;
wire dmem_re;
wire [31:0] dmem_addr;
wire [31:0] dmem_data_in;
wire [31:0] dmem_data_out;
// wire [31:0] dmem_data;
/* DMEM dmem(
.clk(clk),
.cs(dmem_cs),
.we(dmem_we),
.re(dmem_re),
.addr(dmem_addr),
.data_in(dmem_data_in),
.data_out(dmem_data_out)
); */
wire [31:0] j_jal={npc_out[31:28],imem_data_out[25:0],2'b0};
assign npc_in=pc_data_out;
assign mux1_in1=j_jal;
assign mux1_in2=mux5_out;
assign add_b=npc_out;
assign mux5_in1=npc_out;
assign mux5_in2=add_c;
assign add_a=ext18_out;
assign ext18_in=imm16;
assign ext16_in=imm16;
assign ext5_in=sa;
// assign imem_addr=pc_data_out;
assign mux7_in1=rf_rs;
assign mux7_in2=mux1_out;
assign pc_data_in=mux7_out;
assign mux6_in1=rf_rtc;
assign mux6_in2=Rdc;//assign mux6_in2=rf_rdc;//
assign mux8_in1=mux6_out;
assign mux8_in2=32'd31;
assign rf_rdc=mux8_out;
assign rf_rsc=Rsc;
assign rf_rtc=Rtc;
assign rf_rd=mux2_out;
assign mux3_in1=ext5_out;
assign mux3_in2=rf_rs;
assign mux4_in1=rf_rt;
assign mux4_in2=ext16_out;
assign alu_a=mux3_out;
assign alu_b=mux4_out;
assign dmem_addr=alu_r;
assign mux2_in1=dmem_data_out;
assign dmem_data_in=rf_rt;
assign mux2_in2=npc_out;
assign mux2_in3=alu_r;
/* wire [5:0] op;
wire [5:0] func;
wire z;*/
wire PC_CLK;
wire IM_R;
wire M3;
wire M4;
wire [3:0] ALUC;
wire M2_0;
wire M2_1;
wire M6;
wire RF_W;
wire RF_CLK;
wire M5;
wire M1;
wire DM_CS;
wire DM_R;
wire DM_W;
wire M7;
wire M8;
wire Ext5_C;
wire Ext16_C;
wire Ext18_C;
control cpucon( //控制器模块
.op(op),
.func(func),
.z(z),
.clk(clk),
.PC_CLK(PC_CLK),
.IM_R(IM_R),
.M3(M3),
.M4(M4),
.ALUC(ALUC),
.M2_0(M2_0),
.M2_1(M2_1),
.M6(M6),
.RF_W(RF_W),
.RF_CLK(RF_CLK),
.M5(M5),
.M1(M1),
.DM_CS(DM_CS),
.DM_R(DM_R),
.DM_W(DM_W),
.M7(M7),
.M8(M8),
.Ext5_C(Ext5_C),
.Ext16_C(Ext16_C),
.Ext18_C(Ext18_C)
);
assign pc_clk=PC_CLK;
// assign =IM_R;
assign mux3_m=M3;
assign mux4_m=M4;
assign aluc=ALUC;
assign mux2_m={M2_0,M2_1};
assign mux6_m=M6;
assign rf_we=RF_W;
assign rf_clk=RF_CLK;
assign mux5_m=M5;
assign mux1_m=M1;
assign dmem_cs=DM_CS;
assign dmem_we=DM_W;
assign dmem_re=DM_R;
assign mux7_m=M7;
assign mux8_m=M8;
assign ext5_c=Ext5_C;
assign ext16_c=Ext16_C;
assign ext18_c=Ext18_C;
assign imem_data_out=inst;
assign pcdata=pc_data_out;
assign addr=dmem_addr;
assign wdata=dmem_data_in;
assign dmem_data_out=rdata;
assign dm_cs=DM_CS;
assign dm_w=DM_W;
assign dm_r=DM_R;
assign op_out=op;
assign Z=z;
endmodule
控制器模块识别输入机器码,并输出控制信号,控制各个模块的运行
各指令(已包括54条指令)所需控制信号如下图所示
`timescale 1ns / 1ps
module control(
input [5:0] op,
input [5:0] func,
input z,
input clk,
output PC_CLK,
output IM_R,
output M3,
output M4,
output [3:0] ALUC,
output M2_0,
output M2_1,
output M6,
output RF_W,
output RF_CLK,
output M5,
output M1,
output DM_CS,
output DM_R,
output DM_W,
output M7,
output M8,
output Ext5_C,
output Ext16_C,
output Ext18_C
);
wire r_type=~|op;
wire i_add=r_type&func[5]&~func[4]&~func[3]&~func[2]&~func[1]&~func[0];
wire i_addu=r_type&func[5]&~func[4]&~func[3]&~func[2]&~func[1]&func[0];
wire i_sub=r_type&func[5]&~func[4]&~func[3]&~func[2]&func[1]&~func[0];
wire i_subu=r_type&func[5]&~func[4]&~func[3]&~func[2]&func[1]&func[0];
wire i_and=r_type&func[5]&~func[4]&~func[3]&func[2]&~func[1]&~func[0];
wire i_or=r_type&func[5]&~func[4]&~func[3]&func[2]&~func[1]&func[0];
wire i_xor=r_type&func[5]&~func[4]&~func[3]&func[2]&func[1]&~func[0];
wire i_nor=r_type&func[5]&~func[4]&~func[3]&func[2]&func[1]&func[0];
wire i_slt=r_type&func[5]&~func[4]&func[3]&~func[2]&func[1]&~func[0];
wire i_sltu=r_type&func[5]&~func[4]&func[3]&~func[2]&func[1]&func[0];
wire i_sll=r_type&~func[5]&~func[4]&~func[3]&~func[2]&~func[1]&~func[0];
wire i_srl=r_type&~func[5]&~func[4]&~func[3]&~func[2]&func[1]&~func[0];
wire i_sra=r_type&~func[5]&~func[4]&~func[3]&~func[2]&func[1]&func[0];
wire i_sllv=r_type&~func[5]&~func[4]&~func[3]&func[2]&~func[1]&~func[0];
wire i_srlv=r_type&~func[5]&~func[4]&~func[3]&func[2]&func[1]&~func[0];
wire i_srav=r_type&~func[5]&~func[4]&~func[3]&func[2]&func[1]&func[0];
wire i_jr=r_type&~func[5]&~func[4]&func[3]&~func[2]&~func[1]&~func[0];
wire i_addi=~op[5]&~op[4]&op[3]&~op[2]&~op[1]&~op[0];
wire i_addiu=~op[5]&~op[4]&op[3]&~op[2]&~op[1]&op[0];
wire i_andi=~op[5]&~op[4]&op[3]&op[2]&~op[1]&~op[0];
wire i_ori=~op[5]&~op[4]&op[3]&op[2]&~op[1]&op[0];
wire i_xori=~op[5]&~op[4]&op[3]&op[2]&op[1]&~op[0];
wire i_lui=~op[5]&~op[4]&op[3]&op[2]&op[1]&op[0];
wire i_lw=op[5]&~op[4]&~op[3]&~op[2]&op[1]&op[0];
wire i_sw=op[5]&~op[4]&op[3]&~op[2]&op[1]&op[0];
wire i_beq=~op[5]&~op[4]&~op[3]&op[2]&~op[1]&~op[0];
wire i_bne=~op[5]&~op[4]&~op[3]&op[2]&~op[1]&op[0];
wire i_slti=~op[5]&~op[4]&op[3]&~op[2]&op[1]&~op[0];
wire i_sltiu=~op[5]&~op[4]&op[3]&~op[2]&op[1]&op[0];
wire i_j=~op[5]&~op[4]&~op[3]&~op[2]&op[1]&~op[0];
wire i_jal=~op[5]&~op[4]&~op[3]&~op[2]&op[1]&op[0];
assign PC_CLK=clk;
assign IM_R=1;
assign M3=(i_sll+i_srl+i_sra)?0:1;
assign M4=i_addi+i_addiu+i_andi+i_ori+i_xori+i_lui+i_lw+i_sw+i_slti+i_sltiu+i_j+i_jal+i_jr;
assign M2_0=~(i_lw+i_jal);
assign M2_1=~i_lw;
assign M6=i_add+i_addu+i_sub+i_subu+i_and+i_or+i_xor+i_nor+i_slt+i_sltu+i_sll+i_srl+i_sra+i_sllv+i_srlv+i_srav;
assign RF_W=~(i_sw+i_beq+i_bne+i_j);
// assign RF_CLK=~(i_sw+i_beq+i_bne+i_j)&clk;
assign RF_CLK=clk;
assign M5=((i_beq&z)+(i_bne&(~z)));
// assign M5=i_beq&z;
assign M1=~(i_j+i_jal+i_jr);
assign DM_CS=i_lw+i_sw;
assign DM_R=i_lw;
assign DM_W=i_sw;
assign M7=~i_jr;
assign M8=i_jal;
assign Ext5_C=0;
assign Ext16_C=i_addi+i_addiu+i_slti+i_sltiu;
assign Ext18_C=1;
reg [3:0] aluc;
always@(*)begin
if(i_add) aluc=4'b0010;
else if(i_addu) aluc=4'b0000;
else if(i_sub) aluc=4'b0011;
else if(i_subu) aluc=4'b0001;
else if(i_and) aluc=4'b0100;
else if(i_or) aluc=4'b0101;
else if(i_xor) aluc=4'b0110;
else if(i_nor) aluc=4'b0111;
else if(i_slt) aluc=4'b1011;
else if(i_sltu) aluc=4'b1010;
else if(i_sll) aluc=4'b1110;
else if(i_srl) aluc=4'b1101;
else if(i_sra) aluc=4'b1100;
else if(i_sllv) aluc=4'b1110;
else if(i_srlv) aluc=4'b1101;
else if(i_srav) aluc=4'b1100;
else if(i_addi) aluc=4'b0010;
else if(i_addiu) aluc=4'b0000;
else if(i_andi) aluc=4'b0100;
else if(i_ori) aluc=4'b0101;
else if(i_xori) aluc=4'b0110;
else if(i_lui) aluc=4'b1000;
else if(i_beq) aluc=4'b0011;
else if(i_bne) aluc=4'b0011;
else if(i_slti) aluc=4'b1011;
else if(i_sltiu) aluc=4'b1010;
else aluc=4'b0000;
end
assign ALUC=aluc;
endmodule
ALU模块主要实现基本的运算操作:加法、减法、移位等
`timescale 1ns / 1ps
module alu(
input [31:0] a,
input [31:0] b,
input [3:0] aluc,
output reg [31:0] r,
output reg zero,
output reg carry,
output reg negative,
output reg overflow
);
reg [32:0] tempa;
reg [32:0] tempb;
reg [32:0] temp;
reg c;
integer i;
initial begin
zero=0;
carry=0;
negative=0;
overflow=0;
end
always @(*)
begin
if(aluc[3]==0&&aluc[2]==0&&aluc[1]==0&&aluc[0]==0)
begin
{carry,r}=a+b;
if(r[31]==1) negative=1;
else negative=0;
if(r==0) zero=1;
else zero=0;
end
else if(aluc[3]==0&&aluc[2]==0&&aluc[1]==1&&aluc[0]==0)
begin
r=a+b;
if(a[31]==b[31]) begin
if(r[31]==a[31])
overflow=0;
else
overflow=1;
end
if(r[31]==1) negative=1;
else negative=0;
if(r==0) zero=1;
else zero=0;
end
else if(aluc[3]==0&&aluc[2]==0&&aluc[1]==0&&aluc[0]==1)
begin
{carry,r}=a-b;
if(r[31]==1) negative=1;
else negative=0;
if(r==0) zero=1;
else zero=0;
end
else if(aluc[3]==0&&aluc[2]==0&&aluc[1]==1&&aluc[0]==1)
begin
r=a-b;
if(a[31]!=b[31]) begin
if(r[31]==a[31])
overflow=0;
else
overflow=1;
end
else overflow=0;
if(r[31]==1) negative=1;
else negative=0;
if(r==0) zero=1;
else zero=0;
end
else if(aluc[3]==0&&aluc[2]==1&&aluc[1]==0&&aluc[0]==0)
begin
r=a&b;
if(r[31]==1) negative=1;
else negative=0;
if(r==0) zero=1;
else zero=0;
end
else if(aluc[3]==0&&aluc[2]==1&&aluc[1]==0&&aluc[0]==1)
begin
r=a|b;
if(r[31]==1) negative=1;
else negative=0;
if(r==0) zero=1;
else zero=0;
end
else if(aluc[3]==0&&aluc[2]==1&&aluc[1]==1&&aluc[0]==0)
begin
r=a^b;
if(r[31]==1) negative=1;
else negative=0;
if(r==0) zero=1;
else zero=0;
end
else if(aluc[3]==0&&aluc[2]==1&&aluc[1]==1&&aluc[0]==1)
begin
r=~(a|b);
if(r[31]==1) negative=1;
else negative=0;
if(r==0) zero=1;
else zero=0;
end
else if(aluc[3]==1&&aluc[2]==0&&aluc[1]==0)
begin
r={b[15:0],16'b0};
if(r[31]==1) negative=1;
else negative=0;
if(r==0) zero=1;
else zero=0;
end
else if(aluc[3]==1&&aluc[2]==0&&aluc[1]==1&&aluc[0]==1)
begin
if(a[31]==0&&b[31]==0) begin
if(a>>a;
r=b;
case(a)
0:r={r[31],r[31:0]};
1:r={r[31],r[31:1]};
2:r={{2{r[31]}},r[31:2]};
3:r={{3{r[31]}},r[31:3]};
4:r={{4{r[31]}},r[31:4]};
5:r={{5{r[31]}},r[31:5]};
6:r={{6{r[31]}},r[31:6]};
7:r={{7{r[31]}},r[31:7]};
8:r={{8{r[31]}},r[31:8]};
9:r={{9{r[31]}},r[31:9]};
10:r={{10{r[31]}},r[31:10]};
11:r={{11{r[31]}},r[31:11]};
12:r={{12{r[31]}},r[31:12]};
13:r={{13{r[31]}},r[31:13]};
14:r={{14{r[31]}},r[31:14]};
15:r={{15{r[31]}},r[31:15]};
16:r={{16{r[31]}},r[31:16]};
17:r={{17{r[31]}},r[31:17]};
18:r={{18{r[31]}},r[31:18]};
19:r={{19{r[31]}},r[31:19]};
20:r={{20{r[31]}},r[31:20]};
21:r={{21{r[31]}},r[31:21]};
22:r={{22{r[31]}},r[31:22]};
23:r={{23{r[31]}},r[31:23]};
24:r={{24{r[31]}},r[31:24]};
25:r={{25{r[31]}},r[31:25]};
26:r={{26{r[31]}},r[31:26]};
27:r={{27{r[31]}},r[31:27]};
28:r={{28{r[31]}},r[31:28]};
29:r={{29{r[31]}},r[31:29]};
30:r={{30{r[31]}},r[31:30]};
31:r={{31{r[31]}},r[31:31]};
endcase
carry=b[a-1];
if(r[31]==1) negative=1;
else negative=0;
if(r==0) zero=1;
else zero=0;
end
else if(aluc[3]==1&&aluc[2]==1&&aluc[1]==1)
begin
r=b<>a;
carry=b[a-1];
if(r[31]==1) negative=1;
else negative=0;
if(r==0) zero=1;
else zero=0;
end
end
endmodule
32位Mips架构CPU中包含32个通用寄存器
`timescale 1ns / 1ps
module RegFiles(
input clk,
input rst,
input we,
input [4:0] raddr1,
input [4:0] raddr2,
input [4:0] waddr,
input [31:0] wdata,
output [31:0] rdata1,
output [31:0] rdata2
);
reg [31:0] array_reg [0:31];
integer i;
always@(posedge clk or posedge rst) begin
if(rst) begin
for(i=0;i<32;i=i+1)
array_reg[i]<=32'b0;
end
else begin
if(we&&waddr!=5'b0)
array_reg[waddr]<=wdata;
end
end
assign rdata1=(raddr1==5'b0)?32'b0:array_reg[raddr1];
assign rdata2=(raddr2==5'b0)?32'b0:array_reg[raddr2];
endmodule
为了简化,这个CPU把指令存储器和数据存储器分开了
`timescale 1ns / 1ps
module IMEM(
// input clk,
// input wena,
input [10:0] addr,
// input [31:0] data_in,
output [31:0] data_out
);
reg [31:0] state [0:1024];
// wire [31:0] real_addr=(addr-32'h00400000)/4;
initial begin
$readmemh("E:/vivado_projects/CSCPU/31CPUtest/_1_addi.hex.txt",state);
end
/* always @(posedge clk) begin
if(wena) begin
if(addr!=0) state[addr]<=data_in;
end
end*/
assign data_out=state[addr];
endmodule
module DMEM(
input clk,
input cs,
input we,
input re,
input [31:0] addr,
input [31:0] data_in,
output [31:0] data_out
);
reg [31:0] state [0:1024];
wire [31:0] really_addr;
assign really_addr=(addr-32'h10010000)/4;
always @(negedge clk) begin
if(we) begin
state[really_addr]<=data_in;
end
end
assign data_out=re?state[really_addr]:32'bz;
endmodule
pc寄存器保存取指的地址
`timescale 1ns / 1ps
module PC_Reg(
input clk,
input rst,
input ena,
input [31:0] data_in,
output [31:0] data_out,
output [31:28] pc31_28
);
reg [31:0] data;
always @(posedge clk or posedge rst) begin
if(rst) data<=32'h00400000;
else begin
if(ena) data<=data_in;
end
end
assign data_out=data;
assign pc31_28=data[31:28];
endmodule
`timescale 1ns / 1ps
module MUX(
input m,
input [31:0] data_in1,
input [31:0] data_in2,
output [31:0] data_out
);
assign data_out=(m==0)?data_in1:data_in2;
endmodule
module MUXS(
input [1:0] m,
input [31:0] data_in1,
input [31:0] data_in2,
input [31:0] data_in3,
output [31:0] data_out
);
reg [31:0] out;
always@(*)begin
case(m)
2'b00:out<=data_in1;
2'b01:out<=data_in2;
2'b11:out<=data_in3;
default: out<=32'b0;
endcase
end
assign data_out=out;
endmodule
顶层模块将CPU与存储器、外部设备连接
`timescale 1ns / 1ps
module Ext_imm5(
input [4:0] idata,
output [31:0] odata,
input ca
);
assign odata=(ca==0)?{27'b0,idata}:{{27{idata[4]}},idata};
endmodule
module Ext_imm16(
input [15:0] idata,
output [31:0] odata,
input ca
);
assign odata=(ca==0)?{16'b0,idata}:{{16{idata[15]}},idata};
endmodule
module Ext_imm18(
input [15:0] idata,
output [31:0] odata,
input ca
);
assign odata=(ca==0)?{14'b0,idata,2'b0}:{{14{idata[15]}},idata,2'b0};
endmodule