URL
https://opencores.org/ocsvn/altor32/altor32/trunk
Subversion Repositories altor32
Compare Revisions
- This comparison shows the changes necessary to convert path
/altor32
- from Rev 36 to Rev 37
- ↔ Reverse comparison
Rev 36 → Rev 37
/trunk/rtl/cpu_lite/altor32_regfile_sim.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
48,11 → 48,11
input clk_i /*verilator public*/, |
input rst_i /*verilator public*/, |
input wr_i /*verilator public*/, |
input [4:0] rs_i /*verilator public*/, |
input [4:0] rt_i /*verilator public*/, |
input [4:0] ra_i /*verilator public*/, |
input [4:0] rb_i /*verilator public*/, |
input [4:0] rd_i /*verilator public*/, |
output reg [31:0] reg_rs_o /*verilator public*/, |
output reg [31:0] reg_rt_o /*verilator public*/, |
output reg [31:0] reg_ra_o /*verilator public*/, |
output reg [31:0] reg_rb_o /*verilator public*/, |
input [31:0] reg_rd_i /*verilator public*/ |
); |
|
107,37 → 107,37
begin |
if (rst_i) |
begin |
reg_r1_sp <= 32'h00000000; |
reg_r2_fp <= 32'h00000000; |
reg_r3 <= 32'h00000000; |
reg_r4 <= 32'h00000000; |
reg_r5 <= 32'h00000000; |
reg_r6 <= 32'h00000000; |
reg_r7 <= 32'h00000000; |
reg_r8 <= 32'h00000000; |
reg_r9_lr <= 32'h00000000; |
reg_r10 <= 32'h00000000; |
reg_r11 <= 32'h00000000; |
reg_r12 <= 32'h00000000; |
reg_r13 <= 32'h00000000; |
reg_r14 <= 32'h00000000; |
reg_r15 <= 32'h00000000; |
reg_r16 <= 32'h00000000; |
reg_r17 <= 32'h00000000; |
reg_r18 <= 32'h00000000; |
reg_r19 <= 32'h00000000; |
reg_r20 <= 32'h00000000; |
reg_r21 <= 32'h00000000; |
reg_r22 <= 32'h00000000; |
reg_r23 <= 32'h00000000; |
reg_r24 <= 32'h00000000; |
reg_r25 <= 32'h00000000; |
reg_r26 <= 32'h00000000; |
reg_r27 <= 32'h00000000; |
reg_r28 <= 32'h00000000; |
reg_r29 <= 32'h00000000; |
reg_r30 <= 32'h00000000; |
reg_r31 <= 32'h00000000; |
reg_r1_sp <= 32'h00000000; |
reg_r2_fp <= 32'h00000000; |
reg_r3 <= 32'h00000000; |
reg_r4 <= 32'h00000000; |
reg_r5 <= 32'h00000000; |
reg_r6 <= 32'h00000000; |
reg_r7 <= 32'h00000000; |
reg_r8 <= 32'h00000000; |
reg_r9_lr <= 32'h00000000; |
reg_r10 <= 32'h00000000; |
reg_r11 <= 32'h00000000; |
reg_r12 <= 32'h00000000; |
reg_r13 <= 32'h00000000; |
reg_r14 <= 32'h00000000; |
reg_r15 <= 32'h00000000; |
reg_r16 <= 32'h00000000; |
reg_r17 <= 32'h00000000; |
reg_r18 <= 32'h00000000; |
reg_r19 <= 32'h00000000; |
reg_r20 <= 32'h00000000; |
reg_r21 <= 32'h00000000; |
reg_r22 <= 32'h00000000; |
reg_r23 <= 32'h00000000; |
reg_r24 <= 32'h00000000; |
reg_r25 <= 32'h00000000; |
reg_r26 <= 32'h00000000; |
reg_r27 <= 32'h00000000; |
reg_r28 <= 32'h00000000; |
reg_r29 <= 32'h00000000; |
reg_r30 <= 32'h00000000; |
reg_r31 <= 32'h00000000; |
end |
else |
begin |
217,142 → 217,142
// Asynchronous Register read (Rs & Rd) |
always @ * |
begin |
case (rs_i) |
case (ra_i) |
5'b00000 : |
reg_rs_o = 32'h00000000; |
reg_ra_o = 32'h00000000; |
5'b00001 : |
reg_rs_o = reg_r1_sp; |
reg_ra_o = reg_r1_sp; |
5'b00010 : |
reg_rs_o = reg_r2_fp; |
reg_ra_o = reg_r2_fp; |
5'b00011 : |
reg_rs_o = reg_r3; |
reg_ra_o = reg_r3; |
5'b00100 : |
reg_rs_o = reg_r4; |
reg_ra_o = reg_r4; |
5'b00101 : |
reg_rs_o = reg_r5; |
reg_ra_o = reg_r5; |
5'b00110 : |
reg_rs_o = reg_r6; |
reg_ra_o = reg_r6; |
5'b00111 : |
reg_rs_o = reg_r7; |
reg_ra_o = reg_r7; |
5'b01000 : |
reg_rs_o = reg_r8; |
reg_ra_o = reg_r8; |
5'b01001 : |
reg_rs_o = reg_r9_lr; |
reg_ra_o = reg_r9_lr; |
5'b01010 : |
reg_rs_o = reg_r10; |
reg_ra_o = reg_r10; |
5'b01011 : |
reg_rs_o = reg_r11; |
reg_ra_o = reg_r11; |
5'b01100 : |
reg_rs_o = reg_r12; |
reg_ra_o = reg_r12; |
5'b01101 : |
reg_rs_o = reg_r13; |
reg_ra_o = reg_r13; |
5'b01110 : |
reg_rs_o = reg_r14; |
reg_ra_o = reg_r14; |
5'b01111 : |
reg_rs_o = reg_r15; |
reg_ra_o = reg_r15; |
5'b10000 : |
reg_rs_o = reg_r16; |
reg_ra_o = reg_r16; |
5'b10001 : |
reg_rs_o = reg_r17; |
reg_ra_o = reg_r17; |
5'b10010 : |
reg_rs_o = reg_r18; |
reg_ra_o = reg_r18; |
5'b10011 : |
reg_rs_o = reg_r19; |
reg_ra_o = reg_r19; |
5'b10100 : |
reg_rs_o = reg_r20; |
reg_ra_o = reg_r20; |
5'b10101 : |
reg_rs_o = reg_r21; |
reg_ra_o = reg_r21; |
5'b10110 : |
reg_rs_o = reg_r22; |
reg_ra_o = reg_r22; |
5'b10111 : |
reg_rs_o = reg_r23; |
reg_ra_o = reg_r23; |
5'b11000 : |
reg_rs_o = reg_r24; |
reg_ra_o = reg_r24; |
5'b11001 : |
reg_rs_o = reg_r25; |
reg_ra_o = reg_r25; |
5'b11010 : |
reg_rs_o = reg_r26; |
reg_ra_o = reg_r26; |
5'b11011 : |
reg_rs_o = reg_r27; |
reg_ra_o = reg_r27; |
5'b11100 : |
reg_rs_o = reg_r28; |
reg_ra_o = reg_r28; |
5'b11101 : |
reg_rs_o = reg_r29; |
reg_ra_o = reg_r29; |
5'b11110 : |
reg_rs_o = reg_r30; |
reg_ra_o = reg_r30; |
5'b11111 : |
reg_rs_o = reg_r31; |
reg_ra_o = reg_r31; |
default : |
reg_rs_o = 32'h00000000; |
reg_ra_o = 32'h00000000; |
endcase |
|
case (rt_i) |
case (rb_i) |
5'b00000 : |
reg_rt_o = 32'h00000000; |
reg_rb_o = 32'h00000000; |
5'b00001 : |
reg_rt_o = reg_r1_sp; |
reg_rb_o = reg_r1_sp; |
5'b00010 : |
reg_rt_o = reg_r2_fp; |
reg_rb_o = reg_r2_fp; |
5'b00011 : |
reg_rt_o = reg_r3; |
reg_rb_o = reg_r3; |
5'b00100 : |
reg_rt_o = reg_r4; |
reg_rb_o = reg_r4; |
5'b00101 : |
reg_rt_o = reg_r5; |
reg_rb_o = reg_r5; |
5'b00110 : |
reg_rt_o = reg_r6; |
reg_rb_o = reg_r6; |
5'b00111 : |
reg_rt_o = reg_r7; |
reg_rb_o = reg_r7; |
5'b01000 : |
reg_rt_o = reg_r8; |
reg_rb_o = reg_r8; |
5'b01001 : |
reg_rt_o = reg_r9_lr; |
reg_rb_o = reg_r9_lr; |
5'b01010 : |
reg_rt_o = reg_r10; |
reg_rb_o = reg_r10; |
5'b01011 : |
reg_rt_o = reg_r11; |
reg_rb_o = reg_r11; |
5'b01100 : |
reg_rt_o = reg_r12; |
reg_rb_o = reg_r12; |
5'b01101 : |
reg_rt_o = reg_r13; |
reg_rb_o = reg_r13; |
5'b01110 : |
reg_rt_o = reg_r14; |
reg_rb_o = reg_r14; |
5'b01111 : |
reg_rt_o = reg_r15; |
reg_rb_o = reg_r15; |
5'b10000 : |
reg_rt_o = reg_r16; |
reg_rb_o = reg_r16; |
5'b10001 : |
reg_rt_o = reg_r17; |
reg_rb_o = reg_r17; |
5'b10010 : |
reg_rt_o = reg_r18; |
reg_rb_o = reg_r18; |
5'b10011 : |
reg_rt_o = reg_r19; |
reg_rb_o = reg_r19; |
5'b10100 : |
reg_rt_o = reg_r20; |
reg_rb_o = reg_r20; |
5'b10101 : |
reg_rt_o = reg_r21; |
reg_rb_o = reg_r21; |
5'b10110 : |
reg_rt_o = reg_r22; |
reg_rb_o = reg_r22; |
5'b10111 : |
reg_rt_o = reg_r23; |
reg_rb_o = reg_r23; |
5'b11000 : |
reg_rt_o = reg_r24; |
reg_rb_o = reg_r24; |
5'b11001 : |
reg_rt_o = reg_r25; |
reg_rb_o = reg_r25; |
5'b11010 : |
reg_rt_o = reg_r26; |
reg_rb_o = reg_r26; |
5'b11011 : |
reg_rt_o = reg_r27; |
reg_rb_o = reg_r27; |
5'b11100 : |
reg_rt_o = reg_r28; |
reg_rb_o = reg_r28; |
5'b11101 : |
reg_rt_o = reg_r29; |
reg_rb_o = reg_r29; |
5'b11110 : |
reg_rt_o = reg_r30; |
reg_rb_o = reg_r30; |
5'b11111 : |
reg_rt_o = reg_r31; |
reg_rb_o = reg_r31; |
default : |
reg_rt_o = 32'h00000000; |
reg_rb_o = 32'h00000000; |
endcase |
end |
end |
361,78 → 361,78
// Asynchronous Register read (Rs & Rd) |
always @ * |
begin |
case (rs_i) |
case (ra_i) |
5'b00000 : |
reg_rs_o = 32'h00000000; |
reg_ra_o = 32'h00000000; |
5'b00001 : |
reg_rs_o = reg_r1_sp; |
reg_ra_o = reg_r1_sp; |
5'b00010 : |
reg_rs_o = reg_r2_fp; |
reg_ra_o = reg_r2_fp; |
5'b00011 : |
reg_rs_o = reg_r3; |
reg_ra_o = reg_r3; |
5'b00100 : |
reg_rs_o = reg_r4; |
reg_ra_o = reg_r4; |
5'b00101 : |
reg_rs_o = reg_r5; |
reg_ra_o = reg_r5; |
5'b00110 : |
reg_rs_o = reg_r6; |
reg_ra_o = reg_r6; |
5'b00111 : |
reg_rs_o = reg_r7; |
reg_ra_o = reg_r7; |
5'b01000 : |
reg_rs_o = reg_r8; |
reg_ra_o = reg_r8; |
5'b01001 : |
reg_rs_o = reg_r9_lr; |
reg_ra_o = reg_r9_lr; |
5'b01010 : |
reg_rs_o = reg_r10; |
reg_ra_o = reg_r10; |
5'b01011 : |
reg_rs_o = reg_r11; |
reg_ra_o = reg_r11; |
5'b01100 : |
reg_rs_o = reg_r12; |
reg_ra_o = reg_r12; |
5'b01101 : |
reg_rs_o = reg_r13; |
reg_ra_o = reg_r13; |
5'b01110 : |
reg_rs_o = reg_r14; |
reg_ra_o = reg_r14; |
5'b01111 : |
reg_rs_o = reg_r15; |
reg_ra_o = reg_r15; |
default : |
reg_rs_o = 32'h00000000; |
reg_ra_o = 32'h00000000; |
endcase |
|
case (rt_i) |
case (rb_i) |
5'b00000 : |
reg_rt_o = 32'h00000000; |
reg_rb_o = 32'h00000000; |
5'b00001 : |
reg_rt_o = reg_r1_sp; |
reg_rb_o = reg_r1_sp; |
5'b00010 : |
reg_rt_o = reg_r2_fp; |
reg_rb_o = reg_r2_fp; |
5'b00011 : |
reg_rt_o = reg_r3; |
reg_rb_o = reg_r3; |
5'b00100 : |
reg_rt_o = reg_r4; |
reg_rb_o = reg_r4; |
5'b00101 : |
reg_rt_o = reg_r5; |
reg_rb_o = reg_r5; |
5'b00110 : |
reg_rt_o = reg_r6; |
reg_rb_o = reg_r6; |
5'b00111 : |
reg_rt_o = reg_r7; |
reg_rb_o = reg_r7; |
5'b01000 : |
reg_rt_o = reg_r8; |
reg_rb_o = reg_r8; |
5'b01001 : |
reg_rt_o = reg_r9_lr; |
reg_rb_o = reg_r9_lr; |
5'b01010 : |
reg_rt_o = reg_r10; |
reg_rb_o = reg_r10; |
5'b01011 : |
reg_rt_o = reg_r11; |
reg_rb_o = reg_r11; |
5'b01100 : |
reg_rt_o = reg_r12; |
reg_rb_o = reg_r12; |
5'b01101 : |
reg_rt_o = reg_r13; |
reg_rb_o = reg_r13; |
5'b01110 : |
reg_rt_o = reg_r14; |
reg_rb_o = reg_r14; |
5'b01111 : |
reg_rt_o = reg_r15; |
reg_rb_o = reg_r15; |
default : |
reg_rt_o = 32'h00000000; |
reg_rb_o = 32'h00000000; |
endcase |
end |
end |
/trunk/rtl/cpu_lite/altor32_regfile_xil.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
45,15 → 45,15
//----------------------------------------------------------------- |
module altor32_regfile_xil |
( |
input clk_i /*verilator public*/, |
input rst_i /*verilator public*/, |
input wr_i /*verilator public*/, |
input [4:0] rs_i /*verilator public*/, |
input [4:0] rt_i /*verilator public*/, |
input [4:0] rd_i /*verilator public*/, |
output reg [31:0] reg_rs_o /*verilator public*/, |
output reg [31:0] reg_rt_o /*verilator public*/, |
input [31:0] reg_rd_i /*verilator public*/ |
input clk_i /*verilator public*/, |
input rst_i /*verilator public*/, |
input wr_i /*verilator public*/, |
input [4:0] ra_i /*verilator public*/, |
input [4:0] rb_i /*verilator public*/, |
input [4:0] rd_i /*verilator public*/, |
output reg [31:0] reg_ra_o /*verilator public*/, |
output reg [31:0] reg_rb_o /*verilator public*/, |
input [31:0] reg_rd_i /*verilator public*/ |
); |
|
//----------------------------------------------------------------- |
62,45 → 62,19
parameter SUPPORT_32REGS = "ENABLED"; |
|
//----------------------------------------------------------------- |
// Registers |
// Registers / Wires |
//----------------------------------------------------------------- |
reg [4:0] addr_write; |
wire [31:0] data_out1; |
wire [31:0] data_out2; |
reg write_enable; |
wire [31:0] data_out1a; |
wire [31:0] data_out1b; |
wire [31:0] data_out2a; |
wire [31:0] data_out2b; |
wire wea; |
wire web; |
wire [31:0] reg_ra_w; |
wire [31:0] reg_rb_w; |
wire [31:0] ra_0_15_w; |
wire [31:0] ra_16_31_w; |
wire [31:0] rb_0_15_w; |
wire [31:0] rb_16_31_w; |
wire write_enable_w; |
wire write_banka_w; |
wire write_bankb_w; |
|
//----------------------------------------------------------------- |
// Async Read Process |
//----------------------------------------------------------------- |
always @ (clk_i or rs_i or rt_i or rd_i or reg_rd_i or data_out1 or data_out2 or rst_i or wr_i) |
begin |
// Read Rs |
if (rs_i == 5'b00000) |
reg_rs_o <= 32'h00000000; |
else |
reg_rs_o <= data_out1; |
|
// Read Rt |
if (rt_i == 5'b00000) |
reg_rt_o <= 32'h00000000; |
else |
reg_rt_o <= data_out2; |
|
// Write enabled? |
addr_write <= rd_i[4:0]; |
if ((rd_i != 5'b00000) & (wr_i == 1'b1)) |
write_enable <= 1'b1; |
else |
write_enable <= 1'b0; |
end |
|
//----------------------------------------------------------------- |
// Register File (using RAM16X1D ) |
//----------------------------------------------------------------- |
|
110,8 → 84,8
genvar i; |
for (i=0;i<32;i=i+1) |
begin : reg_loop1 |
RAM16X1D reg_bit1a(.WCLK(clk_i), .WE(wea), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rs_i[0]), .DPRA1(rs_i[1]), .DPRA2(rs_i[2]), .DPRA3(rs_i[3]), .DPO(data_out1a[i]), .SPO(/* open */)); |
RAM16X1D reg_bit1b(.WCLK(clk_i), .WE(web), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rs_i[0]), .DPRA1(rs_i[1]), .DPRA2(rs_i[2]), .DPRA3(rs_i[3]), .DPO(data_out1b[i]), .SPO(/* open */)); |
RAM16X1D reg_bit1a(.WCLK(clk_i), .WE(write_banka_w), .A0(rd_i[0]), .A1(rd_i[1]), .A2(rd_i[2]), .A3(rd_i[3]), .D(reg_rd_i[i]), .DPRA0(ra_i[0]), .DPRA1(ra_i[1]), .DPRA2(ra_i[2]), .DPRA3(ra_i[3]), .DPO(ra_0_15_w[i]), .SPO(/* open */)); |
RAM16X1D reg_bit2a(.WCLK(clk_i), .WE(write_banka_w), .A0(rd_i[0]), .A1(rd_i[1]), .A2(rd_i[2]), .A3(rd_i[3]), .D(reg_rd_i[i]), .DPRA0(rb_i[0]), .DPRA1(rb_i[1]), .DPRA2(rb_i[2]), .DPRA3(rb_i[3]), .DPO(rb_0_15_w[i]), .SPO(/* open */)); |
end |
end |
endgenerate |
123,14 → 97,14
genvar i; |
for (i=0;i<32;i=i+1) |
begin : reg_loop2 |
RAM16X1D reg_bit2a(.WCLK(clk_i), .WE(wea), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rt_i[0]), .DPRA1(rt_i[1]), .DPRA2(rt_i[2]), .DPRA3(rt_i[3]), .DPO(data_out2a[i]), .SPO(/* open */)); |
RAM16X1D reg_bit2b(.WCLK(clk_i), .WE(web), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rt_i[0]), .DPRA1(rt_i[1]), .DPRA2(rt_i[2]), .DPRA3(rt_i[3]), .DPO(data_out2b[i]), .SPO(/* open */)); |
RAM16X1D reg_bit1b(.WCLK(clk_i), .WE(write_bankb_w), .A0(rd_i[0]), .A1(rd_i[1]), .A2(rd_i[2]), .A3(rd_i[3]), .D(reg_rd_i[i]), .DPRA0(ra_i[0]), .DPRA1(ra_i[1]), .DPRA2(ra_i[2]), .DPRA3(ra_i[3]), .DPO(ra_16_31_w[i]), .SPO(/* open */)); |
RAM16X1D reg_bit2b(.WCLK(clk_i), .WE(write_bankb_w), .A0(rd_i[0]), .A1(rd_i[1]), .A2(rd_i[2]), .A3(rd_i[3]), .D(reg_rd_i[i]), .DPRA0(rb_i[0]), .DPRA1(rb_i[1]), .DPRA2(rb_i[2]), .DPRA3(rb_i[3]), .DPO(rb_16_31_w[i]), .SPO(/* open */)); |
end |
end |
else |
begin |
assign data_out2a = 32'h00000000; |
assign data_out2b = 32'h00000000; |
assign ra_16_31_w = 32'h00000000; |
assign rb_16_31_w = 32'h00000000; |
end |
endgenerate |
|
137,9 → 111,26
//----------------------------------------------------------------- |
// Combinatorial Assignments |
//----------------------------------------------------------------- |
assign data_out1 = (rs_i[4] == 1'b0) ? data_out1a : data_out1b; |
assign data_out2 = (rt_i[4] == 1'b0) ? data_out2a : data_out2b; |
assign wea = (write_enable & ~ (addr_write[4])); |
assign web = (write_enable & addr_write[4]); |
assign reg_ra_w = (ra_i[4] == 1'b0) ? ra_0_15_w : ra_16_31_w; |
assign reg_rb_w = (rb_i[4] == 1'b0) ? rb_0_15_w : rb_16_31_w; |
|
assign write_enable_w = (rd_i != 5'b00000) & wr_i; |
|
assign write_banka_w = (write_enable_w & (~rd_i[4])); |
assign write_bankb_w = (write_enable_w & rd_i[4]); |
|
// Register read ports |
always @ * |
begin |
if (ra_i == 5'b00000) |
reg_ra_o = 32'h00000000; |
else |
reg_ra_o = reg_ra_w; |
|
if (rb_i == 5'b00000) |
reg_rb_o = 32'h00000000; |
else |
reg_rb_o = reg_rb_w; |
end |
|
endmodule |
/trunk/rtl/cpu_lite/altor32_lite.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
93,32 → 93,32
//----------------------------------------------------------------- |
|
// PC |
reg [31:0] r_pc; |
reg [31:0] pc_q; |
|
// Exception saved program counter |
reg [31:0] r_epc; |
reg [31:0] epc_q; |
|
// Supervisor register |
reg [31:0] r_sr; |
reg [31:0] sr_q; |
|
// Exception saved supervisor register |
reg [31:0] r_esr; |
reg [31:0] esr_q; |
|
// Destination register number (post execute stage) |
reg [4:0] r_e_rd; |
reg [4:0] ex_rd_q; |
|
// ALU input A |
reg [31:0] r_e_alu_a; |
reg [31:0] ex_alu_a_q; |
|
// ALU input B |
reg [31:0] r_e_alu_b; |
reg [31:0] ex_alu_b_q; |
|
// ALU output |
wire [31:0] r_e_result; |
wire [31:0] ex_result_w; |
|
// ALU Carry |
wire alu_carry_out; |
wire alu_carry_update; |
wire alu_carry_out_w; |
wire alu_carry_update_w; |
|
// ALU Comparisons |
wire compare_equal_w; |
129,28 → 129,28
wire alu_flag_update; |
|
// ALU operation selection |
reg [3:0] r_e_alu_func; |
reg [3:0] ex_alu_func_q; |
|
// Delayed NMI |
reg r_nmi; |
reg nmi_q; |
|
// SIM PUTC |
`ifdef SIM_EXT_PUTC |
reg [7:0] r_putc; |
reg [7:0] putc_q; |
`endif |
|
wire [4:0] w_ra; |
wire [4:0] w_rb; |
wire [4:0] w_rd; |
wire [4:0] ra_w; |
wire [4:0] rb_w; |
wire [4:0] rd_w; |
|
wire [31:0] w_reg_ra; |
wire [31:0] w_reg_rb; |
wire [31:0] reg_ra_w; |
wire [31:0] reg_rb_w; |
|
reg [31:0] r_opcode; |
reg [31:0] opcode_q; |
|
reg [31:0] r_load_result; |
reg [31:0] load_result_r; |
|
reg [1:0] mem_offset; |
reg [1:0] mem_offset_q; |
|
// Current state |
parameter STATE_IDLE = 0; |
160,7 → 160,7
parameter STATE_MEM = 4; |
parameter STATE_WRITE_BACK = 5; |
|
reg [3:0] state; |
reg [3:0] state_q; |
|
//----------------------------------------------------------------- |
// Instantiation |
170,19 → 170,19
altor32_alu alu |
( |
// ALU operation select |
.op_i(r_e_alu_func), |
.op_i(ex_alu_func_q), |
|
// Operands |
.a_i(r_e_alu_a), |
.b_i(r_e_alu_b), |
.c_i(r_sr[`OR32_SR_CY]), |
.a_i(ex_alu_a_q), |
.b_i(ex_alu_b_q), |
.c_i(sr_q[`OR32_SR_CY]), |
|
// Result |
.p_o(r_e_result), |
.p_o(ex_result_w), |
|
// Carry |
.c_o(alu_carry_out), |
.c_update_o(alu_carry_update), |
.c_o(alu_carry_out_w), |
.c_update_o(alu_carry_update_w), |
|
// Comparisons |
.equal_o(compare_equal_w), |
194,12 → 194,14
); |
|
// Writeback result |
wire [31:0] w_write_res = (state == STATE_MEM) ? r_load_result : r_e_result; |
wire [31:0] w_write_res = (state_q == STATE_MEM) ? load_result_r : ex_result_w; |
|
// Writeback enable |
wire w_write_en = (state == STATE_MEM & mem_ack_i) | (state == STATE_WRITE_BACK); |
wire w_write_en = (state_q == STATE_MEM & mem_ack_i) | (state_q == STATE_WRITE_BACK); |
|
// Register file |
//----------------------------------------------------------------- |
// [Xilinx] Register file |
//----------------------------------------------------------------- |
generate |
if (REGISTER_FILE_TYPE == "XILINX") |
begin : REGFILE_XIL |
215,14 → 217,17
.wr_i(w_write_en), |
|
// Tri-port |
.rs_i(w_ra), |
.rt_i(w_rb), |
.rd_i(r_e_rd), |
.reg_rs_o(w_reg_ra), |
.reg_rt_o(w_reg_rb), |
.ra_i(ra_w), |
.rb_i(rb_w), |
.rd_i(ex_rd_q), |
.reg_ra_o(reg_ra_w), |
.reg_rb_o(reg_rb_w), |
.reg_rd_i(w_write_res) |
); |
end |
//----------------------------------------------------------------- |
// [Altera] Register file |
//----------------------------------------------------------------- |
else if (REGISTER_FILE_TYPE == "ALTERA") |
begin : REGFILE_ALT |
altor32_regfile_alt |
237,14 → 242,17
.wr_i(w_write_en), |
|
// Tri-port |
.rs_i(w_ra), |
.rt_i(w_rb), |
.rd_i(r_e_rd), |
.reg_rs_o(w_reg_ra), |
.reg_rt_o(w_reg_rb), |
.ra_i(ra_w), |
.rb_i(rb_w), |
.rd_i(ex_rd_q), |
.reg_ra_o(reg_ra_w), |
.reg_rb_o(reg_rb_w), |
.reg_rd_i(w_write_res) |
); |
end |
//----------------------------------------------------------------- |
// [Simulation] Register file |
//----------------------------------------------------------------- |
else |
begin : REGFILE_SIM |
altor32_regfile_sim |
259,11 → 267,11
.wr_i(w_write_en), |
|
// Tri-port |
.rs_i(w_ra), |
.rt_i(w_rb), |
.rd_i(r_e_rd), |
.reg_rs_o(w_reg_ra), |
.reg_rt_o(w_reg_rb), |
.ra_i(ra_w), |
.rb_i(rb_w), |
.rd_i(ex_rd_q), |
.reg_ra_o(reg_ra_w), |
.reg_rb_o(reg_rb_w), |
.reg_rd_i(w_write_res) |
); |
end |
290,36 → 298,36
always @ * |
begin |
// Instruction |
inst_r = {2'b00,r_opcode[31:26]}; |
inst_r = {2'b00,opcode_q[31:26]}; |
|
// Sub instructions |
alu_op_r = {r_opcode[9:6],r_opcode[3:0]}; |
sfxx_op_r = {5'b00,r_opcode[31:21]} & `INST_OR32_SFMASK; |
shift_op_r = r_opcode[7:6]; |
alu_op_r = {opcode_q[9:6],opcode_q[3:0]}; |
sfxx_op_r = {5'b00,opcode_q[31:21]} & `INST_OR32_SFMASK; |
shift_op_r = opcode_q[7:6]; |
|
// Branch target |
target_int26_r = sign_extend_imm26(r_opcode[25:0]); |
target_int26_r = sign_extend_imm26(opcode_q[25:0]); |
|
// Store immediate |
store_int32_r = sign_extend_imm16({r_opcode[25:21],r_opcode[10:0]}); |
store_int32_r = sign_extend_imm16({opcode_q[25:21],opcode_q[10:0]}); |
|
// Signed & unsigned imm -> 32-bits |
uint16_r = r_opcode[15:0]; |
int32_r = sign_extend_imm16(r_opcode[15:0]); |
uint32_r = extend_imm16(r_opcode[15:0]); |
uint16_r = opcode_q[15:0]; |
int32_r = sign_extend_imm16(opcode_q[15:0]); |
uint32_r = extend_imm16(opcode_q[15:0]); |
|
// Register values [ra/rb] |
reg_ra_r = w_reg_ra; |
reg_rb_r = w_reg_rb; |
reg_ra_r = reg_ra_w; |
reg_rb_r = reg_rb_w; |
|
// Shift ammount (from register[rb]) |
shift_rb_r = {26'b00,w_reg_rb[5:0]}; |
shift_rb_r = {26'b00,reg_rb_w[5:0]}; |
|
// Shift ammount (from immediate) |
shift_imm_r = {26'b00,r_opcode[5:0]}; |
shift_imm_r = {26'b00,opcode_q[5:0]}; |
|
// MTSPR/MFSPR operand |
mxspr_uint16_r = (w_reg_ra[15:0] | {5'b00000,r_opcode[10:0]}); |
mxspr_uint16_r = (reg_ra_w[15:0] | {5'b00000,opcode_q[10:0]}); |
end |
|
//----------------------------------------------------------------- |
383,8 → 391,8
wire inst_sfltu_w = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFLTU); // l.sfltu |
wire inst_sfne_w = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFNE); // l.sfne |
|
wire inst_sys_w = (inst_r == `INST_OR32_MISC) & (r_opcode[31:24] == `INST_OR32_SYS); // l.sys |
wire inst_trap_w = (inst_r == `INST_OR32_MISC) & (r_opcode[31:24] == `INST_OR32_TRAP); // l.trap |
wire inst_sys_w = (inst_r == `INST_OR32_MISC) & (opcode_q[31:24] == `INST_OR32_SYS); // l.sys |
wire inst_trap_w = (inst_r == `INST_OR32_MISC) & (opcode_q[31:24] == `INST_OR32_TRAP); // l.trap |
|
//----------------------------------------------------------------- |
// Load/Store operation? |
408,9 → 416,9
reg [3:0] next_state_r; |
always @ * |
begin |
next_state_r = state; |
next_state_r = state_q; |
|
case (state) |
case (state_q) |
//----------------------------------------- |
// IDLE - |
//----------------------------------------- |
471,9 → 479,9
always @ (posedge rst_i or posedge clk_i ) |
begin |
if (rst_i == 1'b1) |
state <= STATE_IDLE; |
state_q <= STATE_IDLE; |
else |
state <= next_state_r; |
state_q <= next_state_r; |
end |
|
//----------------------------------------------------------------- |
490,8 → 498,8
mem_stb_o <= 1'b0; |
mem_cyc_o <= 1'b0; |
|
r_opcode <= 32'h00000000; |
mem_offset <= 2'b0; |
opcode_q <= 32'h00000000; |
mem_offset_q <= 2'b0; |
end |
else |
begin |
499,7 → 507,7
if (~mem_stall_i) |
mem_stb_o <= 1'b0; |
|
case (state) |
case (state_q) |
|
//----------------------------------------- |
// FETCH - Issue instruction fetch |
507,7 → 515,7
STATE_FETCH : |
begin |
// Start fetch from memory |
mem_addr_o <= r_pc; |
mem_addr_o <= pc_q; |
mem_stb_o <= 1'b1; |
mem_we_o <= 1'b0; |
mem_cyc_o <= 1'b1; |
520,7 → 528,7
// Data ready from memory? |
if (mem_ack_i) |
begin |
r_opcode <= mem_dat_i; |
opcode_q <= mem_dat_i; |
mem_cyc_o <= 1'b0; |
end |
end |
530,9 → 538,9
STATE_EXEC : |
begin |
`ifdef CONF_CORE_TRACE |
$display("%08x: Execute 0x%08x", r_pc, r_opcode); |
$display(" rA[%d] = 0x%08x", w_ra, reg_ra_r); |
$display(" rB[%d] = 0x%08x", w_rb, reg_rb_r); |
$display("%08x: Execute 0x%08x", pc_q, opcode_q); |
$display(" rA[%d] = 0x%08x", ra_w, reg_ra_r); |
$display(" rB[%d] = 0x%08x", rb_w, reg_rb_r); |
`endif |
|
case (1'b1) |
540,7 → 548,7
load_inst_r: |
begin |
mem_addr_o <= {mem_addr_r[31:2], 2'b0}; |
mem_offset <= mem_addr_r[1:0]; |
mem_offset_q <= mem_addr_r[1:0]; |
mem_dat_o <= 32'h00000000; |
mem_sel_o <= 4'b1111; |
mem_we_o <= 1'b0; |
548,7 → 556,7
mem_cyc_o <= 1'b1; |
|
`ifdef CONF_CORE_DEBUG |
$display(" Load from 0x%08x to R%d", mem_addr_r, w_rd); |
$display(" Load from 0x%08x to R%d", mem_addr_r, rd_w); |
`endif |
end |
|
555,7 → 563,7
inst_sb_w: // l.sb |
begin |
mem_addr_o <= {mem_addr_r[31:2], 2'b0}; |
mem_offset <= mem_addr_r[1:0]; |
mem_offset_q <= mem_addr_r[1:0]; |
case (mem_addr_r[1:0]) |
2'b00 : |
begin |
597,7 → 605,7
inst_sh_w: // l.sh |
begin |
mem_addr_o <= {mem_addr_r[31:2], 2'b0}; |
mem_offset <= mem_addr_r[1:0]; |
mem_offset_q <= mem_addr_r[1:0]; |
case (mem_addr_r[1:0]) |
2'b00 : |
begin |
623,7 → 631,7
inst_sw_w: // l.sw |
begin |
mem_addr_o <= {mem_addr_r[31:2], 2'b0}; |
mem_offset <= mem_addr_r[1:0]; |
mem_offset_q <= mem_addr_r[1:0]; |
mem_dat_o <= reg_rb_r; |
mem_sel_o <= 4'b1111; |
mem_we_o <= 1'b1; |
631,7 → 639,7
mem_cyc_o <= 1'b1; |
|
`ifdef CONF_CORE_DEBUG |
$display(" Store R%d to 0x%08x = 0x%08x", w_rb, {mem_addr_r[31:2],2'b00}, reg_rb_r); |
$display(" Store R%d to 0x%08x = 0x%08x", rb_w, {mem_addr_r[31:2],2'b00}, reg_rb_r); |
`endif |
end |
default: |
659,15 → 667,15
|
// If simulation, RA = 03 if NOP instruction |
`ifdef SIMULATION |
wire [7:0] v_fetch_inst = {2'b00, r_opcode[31:26]}; |
wire [7:0] v_fetch_inst = {2'b00, opcode_q[31:26]}; |
wire v_is_nop = (v_fetch_inst == `INST_OR32_NOP); |
assign w_ra = v_is_nop ? 5'd3 : r_opcode[20:16]; |
assign ra_w = v_is_nop ? 5'd3 : opcode_q[20:16]; |
`else |
assign w_ra = r_opcode[20:16]; |
assign ra_w = opcode_q[20:16]; |
`endif |
|
assign w_rb = r_opcode[15:11]; |
assign w_rd = r_opcode[25:21]; |
assign rb_w = opcode_q[15:11]; |
assign rd_w = opcode_q[25:21]; |
|
//----------------------------------------------------------------- |
// Next PC |
677,7 → 685,7
always @ * |
begin |
// Next expected PC (current PC + 4) |
next_pc_r = (r_pc + 4); |
next_pc_r = (pc_q + 4); |
end |
|
//----------------------------------------------------------------- |
687,15 → 695,15
reg compare_result_r; |
always @ * |
begin |
next_sr_r = r_sr; |
next_sr_r = sr_q; |
|
// Update SR.F |
if (alu_flag_update) |
next_sr_r[`OR32_SR_F] = compare_result_r; |
next_sr_r[`OR32_SR_F] = compare_result_r; |
|
// Latch carry if updated |
if (alu_carry_update) |
next_sr_r[`OR32_SR_CY] = alu_carry_out; |
if (alu_carry_update_w) |
next_sr_r[`OR32_SR_CY] = alu_carry_out_w; |
|
case (1'b1) |
inst_mtspr_w: |
714,13 → 722,13
end |
inst_rfe_w: |
begin |
next_sr_r[`OR32_SR_F] = r_esr[`OR32_SR_F]; |
next_sr_r[`OR32_SR_CY] = r_esr[`OR32_SR_CY]; |
next_sr_r[`OR32_SR_IEE] = r_esr[`OR32_SR_IEE]; |
next_sr_r[`OR32_SR_F] = esr_q[`OR32_SR_F]; |
next_sr_r[`OR32_SR_CY] = esr_q[`OR32_SR_CY]; |
next_sr_r[`OR32_SR_IEE] = esr_q[`OR32_SR_IEE]; |
end |
inst_sfxx_w, |
inst_sfxxi_w: |
next_sr_r[`OR32_SR_F] = compare_result_r; |
next_sr_r[`OR32_SR_F] = compare_result_r; |
default: |
; |
endcase |
734,8 → 742,8
|
always @ * |
begin |
next_epc_r = r_epc; |
next_esr_r = r_esr; |
next_epc_r = epc_q; |
next_esr_r = esr_q; |
|
case (1'b1) |
inst_mtspr_w: // l.mtspr |
896,7 → 904,7
// EPCR - EPC Exception saved PC |
`SPR_REG_EPCR: |
begin |
alu_input_a_r = r_epc; |
alu_input_a_r = epc_q; |
write_rd_r = 1'b1; |
end |
|
904,9 → 912,9
`SPR_REG_ESR: |
begin |
alu_input_a_r = 32'b0; |
alu_input_a_r[`OR32_SR_F] = r_esr[`OR32_SR_F]; |
alu_input_a_r[`OR32_SR_CY] = r_esr[`OR32_SR_CY]; |
alu_input_a_r[`OR32_SR_IEE] = r_esr[`OR32_SR_IEE]; |
alu_input_a_r[`OR32_SR_F] = esr_q[`OR32_SR_F]; |
alu_input_a_r[`OR32_SR_CY] = esr_q[`OR32_SR_CY]; |
alu_input_a_r[`OR32_SR_IEE] = esr_q[`OR32_SR_IEE]; |
write_rd_r = 1'b1; |
end |
default: |
1043,14 → 1051,14
branch_except_r = 1'b0; |
|
// Default branch target is relative to current PC |
branch_target_r = (r_pc + {target_int26_r[29:0],2'b00}); |
branch_target_r = (pc_q + {target_int26_r[29:0],2'b00}); |
|
case (1'b1) |
inst_bf_w: // l.bf |
branch_r = r_sr[`OR32_SR_F]; |
branch_r = sr_q[`OR32_SR_F]; |
|
inst_bnf_w: // l.bnf |
branch_r = ~r_sr[`OR32_SR_F]; |
branch_r = ~sr_q[`OR32_SR_F]; |
|
inst_j_w: // l.j |
branch_r = 1'b1; |
1079,7 → 1087,7
inst_rfe_w: // l.rfe |
begin |
branch_r = 1'b1; |
branch_target_r = r_epc; |
branch_target_r = epc_q; |
end |
|
inst_sys_w: // l.sys |
1170,26 → 1178,26
begin |
if (rst_i == 1'b1) |
begin |
r_e_alu_func <= `ALU_NONE; |
r_e_alu_a <= 32'h00000000; |
r_e_alu_b <= 32'h00000000; |
r_e_rd <= 5'b00000; |
ex_alu_func_q <= `ALU_NONE; |
ex_alu_a_q <= 32'h00000000; |
ex_alu_b_q <= 32'h00000000; |
ex_rd_q <= 5'b00000; |
end |
else |
begin |
// Update ALU input flops |
r_e_alu_func <= alu_func_r; |
r_e_alu_a <= alu_input_a_r; |
r_e_alu_b <= alu_input_b_r; |
ex_alu_func_q <= alu_func_r; |
ex_alu_a_q <= alu_input_a_r; |
ex_alu_b_q <= alu_input_b_r; |
|
// Branch and link (Rd = LR/R9) |
if (branch_link_r) |
r_e_rd <= 5'd9; |
ex_rd_q <= 5'd9; |
// Instruction with register writeback |
else if (write_rd_r) |
r_e_rd <= w_rd; |
ex_rd_q <= rd_w; |
else |
r_e_rd <= 5'b0; |
ex_rd_q <= 5'b0; |
end |
end |
|
1200,59 → 1208,59
begin |
if (rst_i == 1'b1) |
begin |
r_pc <= BOOT_VECTOR + `VECTOR_RESET; |
pc_q <= BOOT_VECTOR + `VECTOR_RESET; |
|
// Status registers |
r_epc <= 32'h00000000; |
r_sr <= 32'h00000000; |
r_esr <= 32'h00000000; |
epc_q <= 32'h00000000; |
sr_q <= 32'h00000000; |
esr_q <= 32'h00000000; |
|
fault_o <= 1'b0; |
|
r_nmi <= 1'b0; |
nmi_q <= 1'b0; |
end |
else |
begin |
// Record NMI in-case it can't be processed this cycle |
if (nmi_i) |
r_nmi <= 1'b1; |
nmi_q <= 1'b1; |
|
// Core disabled? |
if (~enable_i) |
begin |
// Reset |
r_pc <= BOOT_VECTOR + `VECTOR_RESET; |
pc_q <= BOOT_VECTOR + `VECTOR_RESET; |
|
// Status registers |
r_epc <= 32'h00000000; |
r_sr <= 32'h00000000; |
r_esr <= 32'h00000000; |
epc_q <= 32'h00000000; |
sr_q <= 32'h00000000; |
esr_q <= 32'h00000000; |
|
fault_o <= 1'b0; |
|
r_nmi <= 1'b0; |
nmi_q <= 1'b0; |
end |
// Write-back? |
else if (w_write_en) |
begin |
// Update SR |
r_sr <= next_sr_r; |
sr_q <= next_sr_r; |
|
// Exception: Instruction opcode not valid / supported, invalid PC |
if (invalid_inst_r || (r_pc[1:0] != 2'b00)) |
if (invalid_inst_r || (pc_q[1:0] != 2'b00)) |
begin |
// Save PC of next instruction |
r_epc <= next_pc_r; |
r_esr <= next_sr_r; |
epc_q <= next_pc_r; |
esr_q <= next_sr_r; |
|
// Disable further interrupts |
r_sr <= 32'b0; |
sr_q <= 32'b0; |
|
// Set PC to exception vector |
if (invalid_inst_r) |
r_pc <= ISR_VECTOR + `VECTOR_ILLEGAL_INST; |
pc_q <= ISR_VECTOR + `VECTOR_ILLEGAL_INST; |
else |
r_pc <= ISR_VECTOR + `VECTOR_BUS_ERROR; |
pc_q <= ISR_VECTOR + `VECTOR_BUS_ERROR; |
|
fault_o <= 1'b1; |
end |
1260,14 → 1268,14
else if (branch_except_r) |
begin |
// Save PC of next instruction |
r_epc <= next_pc_r; |
r_esr <= next_sr_r; |
epc_q <= next_pc_r; |
esr_q <= next_sr_r; |
|
// Disable further interrupts |
r_sr <= 32'b0; |
sr_q <= 32'b0; |
|
// Set PC to exception vector |
r_pc <= branch_target_r; |
pc_q <= branch_target_r; |
|
`ifdef CONF_CORE_DEBUG |
$display(" Exception 0x%08x", branch_target_r); |
1274,24 → 1282,24
`endif |
end |
// Non-maskable interrupt |
else if (nmi_i | r_nmi) |
else if (nmi_i | nmi_q) |
begin |
r_nmi <= 1'b0; |
nmi_q <= 1'b0; |
|
// Save PC of next instruction |
if (branch_r) |
r_epc <= branch_target_r; |
epc_q <= branch_target_r; |
// Next expected PC (current PC + 4) |
else |
r_epc <= next_pc_r; |
epc_q <= next_pc_r; |
|
r_esr <= next_sr_r; |
esr_q <= next_sr_r; |
|
// Disable further interrupts |
r_sr <= 32'b0; |
sr_q <= 32'b0; |
|
// Set PC to exception vector |
r_pc <= ISR_VECTOR + `VECTOR_NMI; |
pc_q <= ISR_VECTOR + `VECTOR_NMI; |
|
`ifdef CONF_CORE_DEBUG |
$display(" NMI 0x%08x", ISR_VECTOR + `VECTOR_NMI); |
1302,18 → 1310,18
begin |
// Save PC of next instruction & SR |
if (branch_r) |
r_epc <= branch_target_r; |
epc_q <= branch_target_r; |
// Next expected PC (current PC + 4) |
else |
r_epc <= next_pc_r; |
epc_q <= next_pc_r; |
|
r_esr <= next_sr_r; |
esr_q <= next_sr_r; |
|
// Disable further interrupts |
r_sr <= 32'b0; |
sr_q <= 32'b0; |
|
// Set PC to external interrupt vector |
r_pc <= ISR_VECTOR + `VECTOR_EXTINT; |
pc_q <= ISR_VECTOR + `VECTOR_EXTINT; |
|
`ifdef CONF_CORE_DEBUG |
$display(" External Interrupt 0x%08x", ISR_VECTOR + `VECTOR_EXTINT); |
1323,7 → 1331,7
else if (branch_r) |
begin |
// Perform branch |
r_pc <= branch_target_r; |
pc_q <= branch_target_r; |
|
`ifdef CONF_CORE_DEBUG |
$display(" Branch to 0x%08x", branch_target_r); |
1334,9 → 1342,9
begin |
// Update EPC / ESR which may have been updated |
// by an MTSPR write |
r_pc <= next_pc_r; |
r_epc <= next_epc_r; |
r_esr <= next_esr_r; |
pc_q <= next_pc_r; |
epc_q <= next_epc_r; |
esr_q <= next_esr_r; |
end |
end |
end |
1347,7 → 1355,7
//------------------------------------------------------------------- |
always @ * |
begin |
r_load_result = 32'h00000000; |
load_result_r = 32'h00000000; |
|
case (1'b1) |
|
1354,36 → 1362,36
inst_lbs_w, // l.lbs |
inst_lbz_w: // l.lbz |
begin |
case (mem_offset) |
2'b00 : r_load_result[7:0] = mem_dat_i[31:24]; |
2'b01 : r_load_result[7:0] = mem_dat_i[23:16]; |
2'b10 : r_load_result[7:0] = mem_dat_i[15:8]; |
2'b11 : r_load_result[7:0] = mem_dat_i[7:0]; |
case (mem_offset_q) |
2'b00 : load_result_r[7:0] = mem_dat_i[31:24]; |
2'b01 : load_result_r[7:0] = mem_dat_i[23:16]; |
2'b10 : load_result_r[7:0] = mem_dat_i[15:8]; |
2'b11 : load_result_r[7:0] = mem_dat_i[7:0]; |
default : ; |
endcase |
|
// Sign extend LB |
if (inst_lbs_w && r_load_result[7]) |
r_load_result[31:8] = 24'hFFFFFF; |
if (inst_lbs_w && load_result_r[7]) |
load_result_r[31:8] = 24'hFFFFFF; |
end |
|
inst_lhs_w, // l.lhs |
inst_lhz_w: // l.lhz |
begin |
case (mem_offset) |
2'b00 : r_load_result[15:0] = mem_dat_i[31:16]; |
2'b10 : r_load_result[15:0] = mem_dat_i[15:0]; |
case (mem_offset_q) |
2'b00 : load_result_r[15:0] = mem_dat_i[31:16]; |
2'b10 : load_result_r[15:0] = mem_dat_i[15:0]; |
default : ; |
endcase |
|
// Sign extend LH |
if (inst_lhs_w && r_load_result[15]) |
r_load_result[31:16] = 16'hFFFF; |
if (inst_lhs_w && load_result_r[15]) |
load_result_r[31:16] = 16'hFFFF; |
end |
|
// l.lwz l.lws |
default : |
r_load_result = mem_dat_i; |
load_result_r = mem_dat_i; |
endcase |
end |
|
1418,15 → 1426,15
if (rst_i == 1'b1) |
begin |
`ifdef SIM_EXT_PUTC |
r_putc <= 8'b0; |
putc_q <= 8'b0; |
`endif |
end |
else |
begin |
`ifdef SIM_EXT_PUTC |
r_putc <= 8'b0; |
putc_q <= 8'b0; |
`endif |
if (inst_nop_w && state == STATE_EXEC) |
if (inst_nop_w && state_q == STATE_EXEC) |
begin |
case (uint16_r) |
// NOP_PUTC |
1433,7 → 1441,7
16'h0004: |
begin |
`ifdef SIM_EXT_PUTC |
r_putc <= reg_ra_r[7:0]; |
putc_q <= reg_ra_r[7:0]; |
`else |
$write("%c", reg_ra_r[7:0]); |
`endif |
1454,16 → 1462,16
`ifdef verilator |
function [31:0] get_opcode_ex; |
// verilator public |
get_opcode_ex = (state == STATE_EXEC) ? r_opcode : `OPCODE_INST_BUBBLE; |
get_opcode_ex = (state_q == STATE_EXEC) ? opcode_q : `OPCODE_INST_BUBBLE; |
endfunction |
function [31:0] get_pc_ex; |
// verilator public |
get_pc_ex = r_pc; |
get_pc_ex = pc_q; |
endfunction |
function [7:0] get_putc; |
// verilator public |
`ifdef SIM_EXT_PUTC |
get_putc = r_putc; |
get_putc = putc_q; |
`else |
get_putc = 8'b0; |
`endif |
1470,23 → 1478,23
endfunction |
function [0:0] get_reg_valid; |
// verilator public |
get_reg_valid = (state == STATE_EXEC) ? 1'b1 : 1'b0; |
get_reg_valid = (state_q == STATE_EXEC) ? 1'b1 : 1'b0; |
endfunction |
function [4:0] get_reg_ra; |
// verilator public |
get_reg_ra = w_ra; |
get_reg_ra = ra_w; |
endfunction |
function [31:0] get_reg_ra_value; |
// verilator public |
get_reg_ra_value = w_reg_ra; |
get_reg_ra_value = reg_ra_w; |
endfunction |
function [4:0] get_reg_rb; |
// verilator public |
get_reg_rb = w_rb; |
get_reg_rb = rb_w; |
endfunction |
function [31:0] get_reg_rb_value; |
// verilator public |
get_reg_rb_value = w_reg_rb; |
get_reg_rb_value = reg_rb_w; |
endfunction |
`endif |
|
/trunk/rtl/cpu_lite/altor32_regfile_alt.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
45,15 → 45,15
//----------------------------------------------------------------- |
module altor32_regfile_alt |
( |
input clk_i /*verilator public*/, |
input rst_i /*verilator public*/, |
input wr_i /*verilator public*/, |
input [4:0] rs_i /*verilator public*/, |
input [4:0] rt_i /*verilator public*/, |
input [4:0] rd_i /*verilator public*/, |
output reg [31:0] reg_rs_o /*verilator public*/, |
output reg [31:0] reg_rt_o /*verilator public*/, |
input [31:0] reg_rd_i /*verilator public*/ |
input clk_i /*verilator public*/, |
input rst_i /*verilator public*/, |
input wr_i /*verilator public*/, |
input [4:0] ra_i /*verilator public*/, |
input [4:0] rb_i /*verilator public*/, |
input [4:0] rd_i /*verilator public*/, |
output reg [31:0] reg_ra_o /*verilator public*/, |
output reg [31:0] reg_rb_o /*verilator public*/, |
input [31:0] reg_rd_i /*verilator public*/ |
); |
|
//----------------------------------------------------------------- |
64,42 → 64,18
//----------------------------------------------------------------- |
// Registers |
//----------------------------------------------------------------- |
wire clk_delayed; |
wire [31:0] data_out1; |
wire [31:0] data_out2; |
reg write_enable; |
wire clk_delayed_w; |
wire [31:0] reg_ra_w; |
wire [31:0] reg_rb_w; |
wire write_enable_w; |
|
reg [4:0] addr_reg; |
reg [31:0] data_reg; |
reg [4:0] addr_q; |
reg [31:0] data_q; |
|
wire [31:0] q1; |
wire [31:0] q2; |
wire [31:0] ra_w; |
wire [31:0] rb_w; |
|
//----------------------------------------------------------------- |
// Async Read Process |
//----------------------------------------------------------------- |
always @ (clk_i or rs_i or rt_i or rd_i or reg_rd_i or data_out1 or data_out2 or rst_i or wr_i) |
begin |
// Read Rs |
if (rs_i == 5'b00000) |
reg_rs_o <= 32'h00000000; |
else |
reg_rs_o <= data_out1; |
|
// Read Rt |
if (rt_i == 5'b00000) |
reg_rt_o <= 32'h00000000; |
else |
reg_rt_o <= data_out2; |
|
// Write enabled? |
if ((rd_i != 5'b00000) & (wr_i == 1'b1)) |
write_enable <= 1'b1; |
else |
write_enable <= 1'b0; |
end |
|
//----------------------------------------------------------------- |
// Sync addr & data |
//----------------------------------------------------------------- |
always @ (posedge clk_i or posedge rst_i) |
106,14 → 82,14
begin |
if (rst_i) |
begin |
addr_reg <= 5'b00000; |
data_reg <= 32'h00000000; |
addr_q <= 5'b00000; |
data_q <= 32'h00000000; |
|
end |
else |
begin |
addr_reg <= rd_i; |
data_reg <= reg_rd_i; |
addr_q <= rd_i; |
data_q <= reg_rd_i; |
end |
end |
|
139,16 → 115,16
) |
lpm1 |
( |
.rdclock(clk_delayed), |
.rdclock(clk_delayed_w), |
.rdclken(1'b1), |
.rdaddress(rs_i), |
.rdaddress(ra_i), |
.rden(1'b1), |
.data(reg_rd_i), |
.wraddress(rd_i), |
.wren(write_enable), |
.wren(write_enable_w), |
.wrclock(clk_i), |
.wrclken(1'b1), |
.q(q1) |
.q(ra_w) |
); |
|
|
166,16 → 142,16
) |
lpm2 |
( |
.rdclock(clk_delayed), |
.rdclock(clk_delayed_w), |
.rdclken(1'b1), |
.rdaddress(rt_i), |
.rdaddress(rb_i), |
.rden(1'b1), |
.data(reg_rd_i), |
.wraddress(rd_i), |
.wren(write_enable), |
.wren(write_enable_w), |
.wrclock(clk_i), |
.wrclken(1'b1), |
.q(q2) |
.q(rb_w) |
); |
|
//----------------------------------------------------------------- |
183,10 → 159,26
//----------------------------------------------------------------- |
|
// Delayed clock |
assign clk_delayed = !clk_i; |
assign clk_delayed_w = !clk_i; |
|
// Register read ports |
always @ * |
begin |
if (ra_i == 5'b00000) |
reg_ra_o = 32'h00000000; |
else |
reg_ra_o = reg_ra_w; |
|
if (rb_i == 5'b00000) |
reg_rb_o = 32'h00000000; |
else |
reg_rb_o = reg_rb_w; |
end |
|
assign write_enable_w = (rd_i != 5'b00000) & wr_i; |
|
// Reads are bypassed during write-back |
assign data_out1 = (rs_i != addr_reg) ? q1 : data_reg; |
assign data_out2 = (rt_i != addr_reg) ? q2 : data_reg; |
assign reg_ra_w = (ra_i != addr_q) ? ra_w : data_q; |
assign reg_rb_w = (rb_i != addr_q) ? rb_w : data_q; |
|
endmodule |
/trunk/rtl/cpu_lite/altor32_funcs.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
/trunk/rtl/cpu_lite/altor32.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
/trunk/rtl/cpu_lite/altor32_alu.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
36,12 → 36,6
//----------------------------------------------------------------- |
|
//----------------------------------------------------------------- |
// Includes |
//----------------------------------------------------------------- |
`include "altor32_defs.v" |
`include "altor32_funcs.v" |
|
//----------------------------------------------------------------- |
// Module - ALU |
//----------------------------------------------------------------- |
module altor32_alu |
71,20 → 65,26
); |
|
//----------------------------------------------------------------- |
// Includes |
//----------------------------------------------------------------- |
`include "altor32_defs.v" |
`include "altor32_funcs.v" |
|
//----------------------------------------------------------------- |
// Registers |
//----------------------------------------------------------------- |
reg [31:0] result; |
reg [31:0] result_r; |
|
reg [31:16] shift_right_fill; |
reg [31:0] shift_right_1; |
reg [31:0] shift_right_2; |
reg [31:0] shift_right_4; |
reg [31:0] shift_right_8; |
reg [31:16] shift_right_fill_r; |
reg [31:0] shift_right_1_r; |
reg [31:0] shift_right_2_r; |
reg [31:0] shift_right_4_r; |
reg [31:0] shift_right_8_r; |
|
reg [31:0] shift_left_1; |
reg [31:0] shift_left_2; |
reg [31:0] shift_left_4; |
reg [31:0] shift_left_8; |
reg [31:0] shift_left_1_r; |
reg [31:0] shift_left_2_r; |
reg [31:0] shift_left_4_r; |
reg [31:0] shift_left_8_r; |
|
//----------------------------------------------------------------- |
// ALU |
98,29 → 98,29
`ALU_SHIFTL : |
begin |
if (b_i[0] == 1'b1) |
shift_left_1 = {a_i[30:0],1'b0}; |
shift_left_1_r = {a_i[30:0],1'b0}; |
else |
shift_left_1 = a_i; |
shift_left_1_r = a_i; |
|
if (b_i[1] == 1'b1) |
shift_left_2 = {shift_left_1[29:0],2'b00}; |
shift_left_2_r = {shift_left_1_r[29:0],2'b00}; |
else |
shift_left_2 = shift_left_1; |
shift_left_2_r = shift_left_1_r; |
|
if (b_i[2] == 1'b1) |
shift_left_4 = {shift_left_2[27:0],4'b0000}; |
shift_left_4_r = {shift_left_2_r[27:0],4'b0000}; |
else |
shift_left_4 = shift_left_2; |
shift_left_4_r = shift_left_2_r; |
|
if (b_i[3] == 1'b1) |
shift_left_8 = {shift_left_4[23:0],8'b00000000}; |
shift_left_8_r = {shift_left_4_r[23:0],8'b00000000}; |
else |
shift_left_8 = shift_left_4; |
shift_left_8_r = shift_left_4_r; |
|
if (b_i[4] == 1'b1) |
result = {shift_left_8[15:0],16'b0000000000000000}; |
result_r = {shift_left_8_r[15:0],16'b0000000000000000}; |
else |
result = shift_left_8; |
result_r = shift_left_8_r; |
|
c_o = 1'b0; |
c_update_o = 1'b0; |
132,34 → 132,34
begin |
// Arithmetic shift? Fill with 1's if MSB set |
if (a_i[31] == 1'b1 && op_i == `ALU_SHIRTR_ARITH) |
shift_right_fill = 16'b1111111111111111; |
shift_right_fill_r = 16'b1111111111111111; |
else |
shift_right_fill = 16'b0000000000000000; |
shift_right_fill_r = 16'b0000000000000000; |
|
if (b_i[0] == 1'b1) |
shift_right_1 = {shift_right_fill[31], a_i[31:1]}; |
shift_right_1_r = {shift_right_fill_r[31], a_i[31:1]}; |
else |
shift_right_1 = a_i; |
shift_right_1_r = a_i; |
|
if (b_i[1] == 1'b1) |
shift_right_2 = {shift_right_fill[31:30], shift_right_1[31:2]}; |
shift_right_2_r = {shift_right_fill_r[31:30], shift_right_1_r[31:2]}; |
else |
shift_right_2 = shift_right_1; |
shift_right_2_r = shift_right_1_r; |
|
if (b_i[2] == 1'b1) |
shift_right_4 = {shift_right_fill[31:28], shift_right_2[31:4]}; |
shift_right_4_r = {shift_right_fill_r[31:28], shift_right_2_r[31:4]}; |
else |
shift_right_4 = shift_right_2; |
shift_right_4_r = shift_right_2_r; |
|
if (b_i[3] == 1'b1) |
shift_right_8 = {shift_right_fill[31:24], shift_right_4[31:8]}; |
shift_right_8_r = {shift_right_fill_r[31:24], shift_right_4_r[31:8]}; |
else |
shift_right_8 = shift_right_4; |
shift_right_8_r = shift_right_4_r; |
|
if (b_i[4] == 1'b1) |
result = {shift_right_fill[31:16], shift_right_8[31:16]}; |
result_r = {shift_right_fill_r[31:16], shift_right_8_r[31:16]}; |
else |
result = shift_right_8; |
result_r = shift_right_8_r; |
|
c_o = 1'b0; |
c_update_o = 1'b0; |
169,17 → 169,17
//---------------------------------------------- |
`ALU_ADD : |
begin |
{c_o, result} = (a_i + b_i); |
c_update_o = 1'b1; |
{c_o, result_r} = (a_i + b_i); |
c_update_o = 1'b1; |
end |
`ALU_ADDC : |
begin |
{c_o, result} = (a_i + b_i) + {31'h00000000, c_i}; |
c_update_o = 1'b1; |
{c_o, result_r} = (a_i + b_i) + {31'h00000000, c_i}; |
c_update_o = 1'b1; |
end |
`ALU_SUB : |
begin |
result = (a_i - b_i); |
result_r = (a_i - b_i); |
c_o = 1'b0; |
c_update_o = 1'b0; |
end |
188,25 → 188,25
//---------------------------------------------- |
`ALU_AND : |
begin |
result = (a_i & b_i); |
result_r = (a_i & b_i); |
c_o = 1'b0; |
c_update_o = 1'b0; |
end |
`ALU_OR : |
begin |
result = (a_i | b_i); |
result_r = (a_i | b_i); |
c_o = 1'b0; |
c_update_o = 1'b0; |
end |
`ALU_XOR : |
begin |
result = (a_i ^ b_i); |
result_r = (a_i ^ b_i); |
c_o = 1'b0; |
c_update_o = 1'b0; |
end |
default : |
begin |
result = a_i; |
result_r = a_i; |
c_o = 1'b0; |
c_update_o = 1'b0; |
end |
213,7 → 213,7
endcase |
end |
|
assign p_o = result; |
assign p_o = result_r; |
|
//----------------------------------------------------------------- |
// Comparisons |
/trunk/rtl/cpu_lite/altor32_defs.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
/trunk/rtl/cpu/altor32_dcache.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
/trunk/rtl/cpu/altor32_noicache.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
58,11 → 58,11
input invalidate_i /*verilator public*/, |
|
// Memory interface |
output reg [31:0] wbm_addr_o /*verilator public*/, |
output [31:0] wbm_addr_o /*verilator public*/, |
input [31:0] wbm_dat_i /*verilator public*/, |
output [2:0] wbm_cti_o /*verilator public*/, |
output reg wbm_cyc_o /*verilator public*/, |
output reg wbm_stb_o /*verilator public*/, |
output wbm_cyc_o /*verilator public*/, |
output wbm_stb_o /*verilator public*/, |
input wbm_stall_i/*verilator public*/, |
input wbm_ack_i/*verilator public*/ |
); |
72,16 → 72,44
//----------------------------------------------------------------- |
|
// Current state |
parameter STATE_CHECK = 0; |
parameter STATE_FETCH = 1; |
reg state; |
parameter STATE_CHECK = 0; |
parameter STATE_FETCH = 1; |
reg state_q; |
|
reg ignore_resp; |
reg drop_resp_q; |
|
assign valid_o = wbm_ack_i & ~ignore_resp & ~rd_i; |
assign instruction_o = wbm_dat_i; |
wire mem_fetch_w = (state_q == STATE_CHECK); |
wire mem_valid_w; |
wire mem_final_w; |
|
//----------------------------------------------------------------- |
// Fetch unit |
//----------------------------------------------------------------- |
altor32_wb_fetch |
u_wb |
( |
.clk_i(clk_i), |
.rst_i(rst_i), |
|
.fetch_i(mem_fetch_w), |
.burst_i(1'b0), |
.address_i(pc_i), |
|
.resp_addr_o(/* not used */), |
.data_o(instruction_o), |
.valid_o(mem_valid_w), |
.final_o(mem_final_w), |
|
.wbm_addr_o(wbm_addr_o), |
.wbm_dat_i(wbm_dat_i), |
.wbm_cti_o(wbm_cti_o), |
.wbm_cyc_o(wbm_cyc_o), |
.wbm_stb_o(wbm_stb_o), |
.wbm_stall_i(wbm_stall_i), |
.wbm_ack_i(wbm_ack_i) |
); |
|
//----------------------------------------------------------------- |
// Control logic |
//----------------------------------------------------------------- |
always @ (posedge rst_i or posedge clk_i ) |
88,47 → 116,33
begin |
if (rst_i == 1'b1) |
begin |
wbm_addr_o <= 32'h00000000; |
wbm_stb_o <= 1'b0; |
wbm_cyc_o <= 1'b0; |
ignore_resp <= 1'b0; |
state <= STATE_CHECK; |
drop_resp_q <= 1'b0; |
state_q <= STATE_CHECK; |
end |
else |
begin |
|
if (~wbm_stall_i) |
wbm_stb_o <= 1'b0; |
|
case (state) |
case (state_q) |
|
//----------------------------------------- |
// CHECK - check cache for hit or miss |
// CHECK - Accept read request |
//----------------------------------------- |
STATE_CHECK : |
begin |
// Start fetch from memory |
wbm_addr_o <= pc_i; |
wbm_stb_o <= 1'b1; |
wbm_cyc_o <= 1'b1; |
ignore_resp <= 1'b0; |
state <= STATE_FETCH; |
drop_resp_q <= 1'b0; |
state_q <= STATE_FETCH; |
end |
//----------------------------------------- |
// FETCH - Fetch row from memory |
// FETCH - Wait for read response |
//----------------------------------------- |
STATE_FETCH : |
begin |
// Read whilst waiting for previous response? |
if (rd_i) |
ignore_resp <= 1'b1; |
drop_resp_q <= 1'b1; |
|
// Data ready from memory? |
if (wbm_ack_i) |
begin |
wbm_cyc_o <= 1'b0; |
state <= STATE_CHECK; |
end |
if (mem_final_w) |
state_q <= STATE_CHECK; |
end |
|
default: |
137,6 → 151,8
end |
end |
|
assign wbm_cti_o = 3'b111; |
assign valid_o = mem_valid_w & ~drop_resp_q & ~rd_i; |
assign instruction_o = wbm_dat_i; |
|
endmodule |
|
/trunk/rtl/cpu/altor32_writeback.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
78,15 → 78,15
//----------------------------------------------------------------- |
|
// Register address |
reg [4:0] r_w_rd; |
reg [4:0] rd_q; |
|
// Register writeback value |
reg [31:0] r_result; |
reg [31:0] result_q; |
|
reg [7:0] r_opcode; |
reg [7:0] opcode_q; |
|
// Register writeback enable |
reg r_w_write_rd; |
reg write_rd_q; |
|
//------------------------------------------------------------------- |
// Writeback |
95,23 → 95,23
begin |
if (rst_i == 1'b1) |
begin |
r_w_write_rd <= 1'b1; |
r_result <= 32'h00000000; |
r_w_rd <= 5'b00000; |
r_opcode <= 8'b0; |
write_rd_q <= 1'b1; |
result_q <= 32'h00000000; |
rd_q <= 5'b00000; |
opcode_q <= 8'b0; |
end |
else |
begin |
r_w_write_rd <= 1'b0; |
begin |
rd_q <= rd_i; |
result_q <= alu_result_i; |
|
r_w_rd <= rd_i; |
r_result <= alu_result_i; |
|
r_opcode <= {2'b00,opcode_i[31:26]}; |
opcode_q <= {2'b00,opcode_i[31:26]}; |
|
// Register writeback required? |
if (rd_i != 5'b00000) |
r_w_write_rd <= 1'b1; |
write_rd_q <= 1'b1; |
else |
write_rd_q <= 1'b0; |
end |
end |
|
118,14 → 118,14
//------------------------------------------------------------------- |
// Load result resolve |
//------------------------------------------------------------------- |
wire load_insn; |
wire [31:0] load_result; |
wire load_inst_w; |
wire [31:0] load_result_w; |
|
altor32_lfu |
u_lfu |
( |
// Opcode |
.opcode_i(r_opcode), |
.opcode_i(opcode_q), |
|
// Memory load result |
.mem_result_i(mem_result_i), |
132,15 → 132,15
.mem_offset_i(mem_offset_i), |
|
// Result |
.load_result_o(load_result), |
.load_insn_o(load_insn) |
.load_result_o(load_result_w), |
.load_insn_o(load_inst_w) |
); |
|
//------------------------------------------------------------------- |
// Assignments |
//------------------------------------------------------------------- |
assign write_enable_o = load_insn ? (r_w_write_rd & mem_ready_i) : r_w_write_rd; |
assign write_data_o = load_insn ? load_result : (mult_i ? mult_result_i : r_result); |
assign write_addr_o = r_w_rd; |
assign write_enable_o = load_inst_w ? (write_rd_q & mem_ready_i) : write_rd_q; |
assign write_data_o = load_inst_w ? load_result_w : (mult_i ? mult_result_i : result_q); |
assign write_addr_o = rd_q; |
|
endmodule |
/trunk/rtl/cpu/altor32_icache.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
56,11 → 56,11
input invalidate_i /*verilator public*/, |
|
// Memory interface |
output reg [31:0] wbm_addr_o /*verilator public*/, |
output [31:0] wbm_addr_o /*verilator public*/, |
input [31:0] wbm_dat_i /*verilator public*/, |
output reg [2:0] wbm_cti_o /*verilator public*/, |
output reg wbm_cyc_o /*verilator public*/, |
output reg wbm_stb_o /*verilator public*/, |
output [2:0] wbm_cti_o /*verilator public*/, |
output wbm_cyc_o /*verilator public*/, |
output wbm_stb_o /*verilator public*/, |
input wbm_stall_i/*verilator public*/, |
input wbm_ack_i/*verilator public*/ |
); |
99,35 → 99,29
//----------------------------------------------------------------- |
|
// Tag read / write data |
wire [CACHE_TAG_WIDTH-1:0] tag_data_out; |
reg [CACHE_TAG_WIDTH-1:0] tag_data_in; |
reg tag_wr; |
wire [CACHE_TAG_WIDTH-1:0] tag_out_w; |
reg [CACHE_TAG_WIDTH-1:0] tag_in_r; |
reg tag_wr_r; |
|
// Tag address |
wire [CACHE_LINE_ADDR_WIDTH-1:0] tag_entry; |
wire [CACHE_LINE_ADDR_WIDTH-1:0] tag_address_w; |
|
// Data memory read / write |
wire [CACHE_DWIDTH-1:0] cache_address_rd; |
wire [CACHE_DWIDTH-1:0] cache_address_wr; |
reg [31:0] cache_data_in; |
wire cache_wr; |
wire [CACHE_DWIDTH-1:0] address_rd_w; |
wire [CACHE_DWIDTH-1:0] address_wr_w; |
wire cache_wr_w; |
|
// Word currently being fetched within a line |
reg [CACHE_LINE_SIZE_WIDTH-3:0] mem_fetch_word; |
reg [CACHE_LINE_SIZE_WIDTH-3:0] mem_resp_idx; |
|
// Current / Miss PC |
reg [31:0] last_pc; |
reg [31:0] miss_pc; |
reg [31:0] last_pc_q; |
reg [31:0] miss_pc_q; |
|
// Flush state |
reg flush_req; |
reg [CACHE_LINE_ADDR_WIDTH-1:0] flush_addr; |
reg flush_wr; |
reg flush_q; |
reg [CACHE_LINE_ADDR_WIDTH-1:0] flush_addr_q; |
reg flush_wr_q; |
|
// Other state |
reg initial_fetch; |
reg read_while_busy; |
reg read_while_busy_q; |
|
// Current state |
parameter STATE_CHECK = 0; |
134,49 → 128,51
parameter STATE_FETCH = 1; |
parameter STATE_WAIT = 2; |
parameter STATE_FLUSH = 3; |
reg [3:0] state; |
reg [1:0] state_q; |
|
// Tag address from input PC or flopped version of it |
assign tag_entry = (state != STATE_CHECK) ? |
miss_pc[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH] : |
assign tag_address_w = (state_q != STATE_CHECK) ? |
miss_pc_q[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH] : |
pc_i[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH]; |
|
// Cache read address |
assign cache_address_rd = pc_i[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:2]; |
assign address_rd_w = pc_i[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:2]; |
|
// Cache miss output if requested PC is not in the tag memory |
wire miss = (!tag_data_out[CACHE_TAG_VALID_BIT] || |
(last_pc[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW] != tag_data_out[14:0])) ? 1'b1: 1'b0; |
wire miss_w = ~tag_out_w[CACHE_TAG_VALID_BIT] | |
(last_pc_q[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW] != tag_out_w[14:0]); |
|
// Stall the CPU if cache state machine is not idle! |
wire busy = (state == STATE_CHECK & ~read_while_busy) ? 1'b0 : 1'b1; |
wire busy_w = (state_q != STATE_CHECK) | read_while_busy_q; |
|
// Cache output valid |
assign valid_o = !miss && !busy; |
assign valid_o = busy_w ? 1'b0 : ~miss_w; |
|
// Final word to fetch from memory |
wire mem_fetch_final_word = (mem_fetch_word == {CACHE_LINE_WORDS_IDX_MAX{1'b1}}); |
|
// Flushing: Last line to flush |
wire flush_final_line = (flush_addr == {CACHE_LINE_ADDR_WIDTH{1'b0}}); |
wire flush_last_w = (flush_addr_q == {CACHE_LINE_ADDR_WIDTH{1'b0}}); |
|
// Is this a cache miss? |
wire cache_miss = (miss && // Tag lookup failed |
!initial_fetch && // NOT initial fetch after reset |
!rd_i && // NOT new read request cycle |
!read_while_busy && // NOT pending read whilst busy |
!flush_req && // NOT flush request |
!invalidate_i); |
wire cache_miss_w = miss_w & // Tag lookup failed |
!rd_i & // NOT new read request cycle |
!read_while_busy_q & // NOT pending read whilst busy |
!flush_q & // NOT flush request |
!invalidate_i; |
|
wire mem_fetch_w = (state_q == STATE_CHECK) & cache_miss_w; |
wire [31:0] mem_data_w; |
wire [31:0] mem_resp_addr_w; |
wire mem_valid_w; |
wire mem_final_w; |
|
//----------------------------------------------------------------- |
// Next State Logic |
//----------------------------------------------------------------- |
reg [3:0] next_state_r; |
reg [1:0] next_state_r; |
always @ * |
begin |
next_state_r = state; |
next_state_r = state_q; |
|
case (state) |
case (state_q) |
|
//----------------------------------------- |
// CHECK - check cache for hit or miss |
184,10 → 180,10
STATE_CHECK : |
begin |
// Cache flush request pending? |
if (flush_req || invalidate_i) |
if (flush_q || invalidate_i) |
next_state_r = STATE_FLUSH; |
// Cache miss (& new read request not pending) |
else if (cache_miss) |
else if (cache_miss_w) |
next_state_r = STATE_FETCH; |
// Cache hit (or new read request) |
else |
199,7 → 195,7
STATE_FETCH : |
begin |
// Line fetch complete? |
if (mem_resp_idx == {CACHE_LINE_SIZE_WIDTH-2{1'b1}} && wbm_ack_i) |
if (mem_final_w) |
next_state_r = STATE_WAIT; |
end |
//----------------------------------------- |
207,8 → 203,8
//----------------------------------------- |
STATE_FLUSH : |
begin |
if (flush_final_line) |
next_state_r = STATE_FETCH; |
if (flush_last_w) |
next_state_r = STATE_CHECK; |
else |
next_state_r = STATE_FLUSH; |
end |
226,71 → 222,36
always @ (posedge rst_i or posedge clk_i ) |
begin |
if (rst_i == 1'b1) |
state <= STATE_CHECK; |
state_q <= STATE_FLUSH; |
else |
state <= next_state_r; |
state_q <= next_state_r; |
end |
|
|
//----------------------------------------------------------------- |
// Check for cache misses |
// Flop request details |
//----------------------------------------------------------------- |
always @ (posedge rst_i or posedge clk_i ) |
begin |
if (rst_i == 1'b1) |
begin |
miss_pc <= BOOT_VECTOR + `VECTOR_RESET; |
last_pc <= 32'h00000000; |
initial_fetch <= 1'b1; |
read_while_busy <= 1'b0; |
miss_pc_q <= BOOT_VECTOR + `VECTOR_RESET; |
last_pc_q <= 32'h00000000; |
end |
else |
begin |
initial_fetch <= 1'b0; |
last_pc <= pc_i; |
last_pc_q <= pc_i; |
|
// New request whilst cache busy? |
if (rd_i) |
read_while_busy <= 1'b1; |
case (state_q) |
|
case (state) |
|
//----------------------------------------- |
// CHECK - check cache for hit or miss |
//----------------------------------------- |
STATE_CHECK : |
begin |
// Cache miss (& new read request not pending) |
if (cache_miss) |
begin |
read_while_busy <= 1'b0; |
|
`ifdef CONF_CORE_DEBUG |
$display("Fetch: Cache miss at 0x%x (last=%x, current=%x)", miss_pc, last_pc, pc_i); |
`endif |
end |
// Cache hit (or new read request) |
else |
begin |
`ifdef CONF_CORE_DEBUG |
$display("Fetch: Cache hit at PC=%x (current=%x)", last_pc, pc_i); |
if (read_while_busy) |
$display("Fetch: Read request whilst busy PC=%x (current=%x)", last_pc, pc_i); |
`endif |
// Store fetch PC |
miss_pc <= pc_i; |
read_while_busy <= 1'b0; |
end |
end |
//----------------------------------------- |
// FLUSH - Invalidate tag memory |
//----------------------------------------- |
STATE_FLUSH : |
begin |
// Last line, clear pending reads whilst busy |
if (flush_final_line) |
read_while_busy <= 1'b0; |
end |
// Cache hit (or new read request), store fetch PC |
if (!cache_miss_w) |
miss_pc_q <= pc_i; |
end |
default: |
; |
endcase |
298,295 → 259,159
end |
|
//----------------------------------------------------------------- |
// Cache Tag Write |
// Detect new read request whilst busy |
//----------------------------------------------------------------- |
always @ (posedge rst_i or posedge clk_i ) |
begin |
if (rst_i == 1'b1) |
begin |
tag_data_in <= {CACHE_TAG_WIDTH{1'b0}}; |
tag_wr <= 1'b0; |
begin |
read_while_busy_q <= 1'b0; |
end |
else |
begin |
tag_wr <= 1'b0; |
|
case (state) |
|
case (state_q) |
//----------------------------------------- |
// CHECK - check cache for hit or miss |
// CHECK - Check cache for hit or miss |
//----------------------------------------- |
STATE_CHECK : |
begin |
// Cache miss (& new read request not pending) |
if (cache_miss) |
begin |
// Update tag memory with this line's details |
tag_data_in <= {1'b1, miss_pc[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW]}; |
tag_wr <= 1'b1; |
end |
end |
read_while_busy_q <= 1'b0; |
end |
//----------------------------------------- |
// FLUSH - Invalidate tag memory |
// OTHER - Fetching, flushing, waiting |
//----------------------------------------- |
STATE_FLUSH : |
default: |
begin |
if (flush_final_line) |
begin |
// Update tag memory with this line's details |
tag_data_in <= {1'b1, pc_i[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW]}; |
tag_wr <= 1'b1; |
end |
end |
default: |
; |
endcase |
// New request whilst cache busy? |
if (rd_i) |
read_while_busy_q <= 1'b1; |
end |
endcase |
end |
end |
|
//----------------------------------------------------------------- |
// Flush Logic |
// Cache Tag Write |
//----------------------------------------------------------------- |
always @ (posedge rst_i or posedge clk_i ) |
always @ * |
begin |
if (rst_i == 1'b1) |
begin |
flush_addr <= {CACHE_LINE_ADDR_WIDTH{1'b0}}; |
flush_wr <= 1'b0; |
flush_req <= 1'b0; |
end |
else |
begin |
flush_wr <= 1'b0; |
|
// Latch invalidate request even if can't be actioned now... |
if (invalidate_i) |
flush_req <= 1'b1; |
tag_in_r = {CACHE_TAG_WIDTH{1'b0}}; |
tag_wr_r = 1'b0; |
|
case (state) |
case (state_q) |
|
//----------------------------------------- |
// CHECK - check cache for hit or miss |
//----------------------------------------- |
STATE_CHECK : |
//----------------------------------------- |
// CHECK - check cache for hit or miss |
//----------------------------------------- |
STATE_CHECK : |
begin |
// Cache miss (& new read request not pending) |
if (cache_miss_w) |
begin |
// Cache flush request pending? |
if (flush_req || invalidate_i) |
begin |
flush_req <= 1'b0; |
flush_addr <= {CACHE_LINE_ADDR_WIDTH{1'b1}}; |
flush_wr <= 1'b1; |
|
`ifdef CONF_CORE_DEBUG |
$display("Fetch: Cache flush request"); |
`endif |
end |
// Update tag memory with this line's details |
tag_in_r = {1'b1, miss_pc_q[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW]}; |
tag_wr_r = 1'b1; |
end |
//----------------------------------------- |
// FLUSH - Invalidate tag memory |
//----------------------------------------- |
STATE_FLUSH : |
begin |
if (~flush_final_line) |
begin |
flush_addr <= flush_addr - 1; |
flush_wr <= 1'b1; |
end |
end |
default: |
; |
endcase |
end |
end |
default: |
; |
endcase |
end |
|
//----------------------------------------------------------------- |
// External Mem Access |
// Flush Logic |
//----------------------------------------------------------------- |
reg flush_r; |
reg [CACHE_LINE_ADDR_WIDTH-1:0] flush_addr_r; |
reg flush_wr_r; |
|
// Next fetch address |
wire [CACHE_LINE_SIZE_WIDTH-3:0] mem_next_word = mem_fetch_word + 1; |
|
// Last word to fetch |
wire mem_resp_idx_word = (mem_fetch_word == ({CACHE_LINE_WORDS_IDX_MAX{1'b1}}-1)); |
|
always @ (posedge rst_i or posedge clk_i ) |
always @ * |
begin |
if (rst_i == 1'b1) |
begin |
wbm_addr_o <= 32'h00000000; |
wbm_cti_o <= 3'b0; |
wbm_stb_o <= 1'b0; |
flush_wr_r = 1'b0; |
flush_addr_r = flush_addr_q; |
flush_r = flush_q; |
|
case (state_q) |
|
mem_fetch_word <= {CACHE_LINE_SIZE_WIDTH-2{1'b0}}; |
end |
else |
begin |
if (~wbm_stall_i) |
wbm_stb_o <= 1'b0; |
|
case (state) |
|
//----------------------------------------- |
// CHECK - check cache for hit or miss |
//----------------------------------------- |
STATE_CHECK : |
//----------------------------------------- |
// CHECK - Check cache for hit or miss |
//----------------------------------------- |
STATE_CHECK : |
begin |
// Cache flush request pending? |
if (flush_q || invalidate_i) |
begin |
// Cache miss (& new read request not pending) |
if (cache_miss) |
begin |
// Start fetch from memory |
wbm_addr_o <= {miss_pc[31:CACHE_LINE_SIZE_WIDTH], {CACHE_LINE_SIZE_WIDTH{1'b0}}}; |
|
// Incrementing linear burst |
wbm_cti_o <= 3'b010; |
|
// Start of cycle |
wbm_stb_o <= 1'b1; |
|
mem_fetch_word <= {CACHE_LINE_SIZE_WIDTH-2{1'b0}}; |
end |
flush_r = 1'b0; |
flush_addr_r = {CACHE_LINE_ADDR_WIDTH{1'b1}}; |
flush_wr_r = 1'b1; |
end |
//----------------------------------------- |
// FETCH - Fetch row from memory |
//----------------------------------------- |
STATE_FETCH : |
begin |
// Command accepted |
if (~wbm_stall_i) |
begin |
// Fetch next word for line |
if (!mem_fetch_final_word) |
begin |
wbm_addr_o <= {wbm_addr_o[31:CACHE_LINE_SIZE_WIDTH], mem_next_word, 2'b00}; |
|
// Final word to read? |
if (mem_resp_idx_word) |
wbm_cti_o <= 3'b111; |
|
mem_fetch_word <= mem_next_word; |
|
// Still fetching... |
wbm_stb_o <= 1'b1; |
end |
end |
end |
//----------------------------------------- |
// FLUSH - Invalidate tag memory |
//----------------------------------------- |
STATE_FLUSH : |
begin |
// Fetch current PC line again |
if (flush_final_line) |
begin |
if (read_while_busy) |
wbm_addr_o <= {miss_pc[31:CACHE_LINE_SIZE_WIDTH], {CACHE_LINE_SIZE_WIDTH{1'b0}}}; |
else |
wbm_addr_o <= {pc_i[31:CACHE_LINE_SIZE_WIDTH], {CACHE_LINE_SIZE_WIDTH{1'b0}}}; |
|
// Incrementing linear burst |
wbm_cti_o <= 3'b010; |
|
// Start of cycle |
wbm_stb_o <= 1'b1; |
|
// Start of line |
mem_fetch_word <= {CACHE_LINE_SIZE_WIDTH-2{1'b0}}; |
end |
end |
default: |
; |
endcase |
end |
end |
//----------------------------------------- |
// FLUSH - Invalidate tag memory |
//----------------------------------------- |
STATE_FLUSH : |
begin |
flush_addr_r = flush_addr_q - 1; |
flush_wr_r = 1'b1; |
end |
//----------------------------------------- |
// OTHER - Fetching / wait cycles |
//----------------------------------------- |
default: |
begin |
// Latch invalidate request even if can't be actioned now... |
if (invalidate_i) |
flush_r = 1'b1; |
end |
endcase |
end |
|
//----------------------------------------------------------------- |
// CYC_O |
//----------------------------------------------------------------- |
always @ (posedge rst_i or posedge clk_i ) |
begin |
if (rst_i == 1'b1) |
wbm_cyc_o <= 1'b0; |
begin |
flush_addr_q <= {CACHE_LINE_ADDR_WIDTH{1'b1}}; |
flush_wr_q <= 1'b0; |
flush_q <= 1'b0; |
end |
else |
begin |
case (state) |
|
//----------------------------------------- |
// CHECK - check cache for hit or miss |
//----------------------------------------- |
STATE_CHECK : |
begin |
// Cache miss (& new read request not pending) |
if (cache_miss) |
wbm_cyc_o <= 1'b1; |
end |
//----------------------------------------- |
// FLUSH - Invalidate tag memory |
//----------------------------------------- |
STATE_FLUSH : |
begin |
// Fetch current PC line again |
if (flush_final_line) |
wbm_cyc_o <= 1'b1; |
end |
//----------------------------------------- |
// FETCH - Fetch row from memory |
//----------------------------------------- |
STATE_FETCH : |
begin |
// Last response? |
if (wbm_ack_i && (mem_resp_idx == {CACHE_LINE_SIZE_WIDTH-2{1'b1}})) |
wbm_cyc_o <= 1'b0; |
end |
default: |
; |
endcase |
flush_addr_q <= flush_addr_r; |
flush_wr_q <= flush_wr_r; |
flush_q <= flush_r; |
end |
end |
|
//----------------------------------------------------------------- |
// Memory response counter |
// External Mem Access |
//----------------------------------------------------------------- |
always @ (posedge rst_i or posedge clk_i ) |
begin |
if (rst_i == 1'b1) |
mem_resp_idx <= {CACHE_LINE_SIZE_WIDTH-2{1'b0}}; |
else |
begin |
case (state) |
altor32_wb_fetch |
u_wb |
( |
.clk_i(clk_i), |
.rst_i(rst_i), |
|
//----------------------------------------- |
// CHECK - check cache for hit or miss |
//----------------------------------------- |
STATE_CHECK : |
begin |
// Cache miss (& new read request not pending) |
if (cache_miss) |
mem_resp_idx <= {CACHE_LINE_SIZE_WIDTH-2{1'b0}}; |
end |
//----------------------------------------- |
// FLUSH - Invalidate tag memory |
//----------------------------------------- |
STATE_FLUSH : |
begin |
// Fetch current PC line again |
if (flush_final_line) |
mem_resp_idx <= {CACHE_LINE_SIZE_WIDTH-2{1'b0}}; |
end |
//----------------------------------------- |
// FETCH - Fetch row from memory |
//----------------------------------------- |
STATE_FETCH : |
begin |
// Response |
if (wbm_ack_i) |
mem_resp_idx <= mem_resp_idx + 1; |
end |
default: |
; |
endcase |
end |
end |
// Request |
.fetch_i(mem_fetch_w), |
.burst_i(1'b1), |
.address_i(miss_pc_q), |
|
// Response |
.resp_addr_o(mem_resp_addr_w), |
.data_o(mem_data_w), |
.valid_o(mem_valid_w), |
.final_o(mem_final_w), |
|
// Wishbone interface |
.wbm_addr_o(wbm_addr_o), |
.wbm_dat_i(wbm_dat_i), |
.wbm_cti_o(wbm_cti_o), |
.wbm_cyc_o(wbm_cyc_o), |
.wbm_stb_o(wbm_stb_o), |
.wbm_stall_i(wbm_stall_i), |
.wbm_ack_i(wbm_ack_i) |
); |
|
//----------------------------------------------------------------- |
// Tag memory |
//----------------------------------------------------------------- |
599,17 → 424,17
( |
// Tag read/write port |
.aclk_i(clk_i), |
.adat_o(tag_data_out), |
.adat_i(tag_data_in), |
.aadr_i(tag_entry), |
.awr_i(tag_wr), |
.adat_o(tag_out_w), |
.adat_i(tag_in_r), |
.aadr_i(tag_address_w), |
.awr_i(tag_wr_r), |
|
// Tag invalidate port |
.bclk_i(clk_i), |
.badr_i(flush_addr), |
.badr_i(flush_addr_q), |
.bdat_o(/*open*/), |
.bdat_i({CACHE_TAG_WIDTH{1'b0}}), |
.bwr_i(flush_wr) |
.bwr_i(flush_wr_q) |
); |
|
//----------------------------------------------------------------- |
624,7 → 449,7
( |
// Data read port |
.aclk_i(clk_i), |
.aadr_i(cache_address_rd), |
.aadr_i(address_rd_w), |
.adat_o(instruction_o), |
.adat_i(32'h00), |
.awr_i(1'b0), |
631,16 → 456,16
|
// Data write port |
.bclk_i(clk_i), |
.badr_i(cache_address_wr), |
.badr_i(address_wr_w), |
.bdat_o(/*open*/), |
.bdat_i(wbm_dat_i), |
.bwr_i(cache_wr) |
.bdat_i(mem_data_w), |
.bwr_i(cache_wr_w) |
); |
|
// Write to cache on wishbone response |
assign cache_address_wr = {miss_pc[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH], mem_resp_idx}; |
assign address_wr_w = {miss_pc_q[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH], mem_resp_addr_w[CACHE_LINE_SIZE_WIDTH-1:2]}; |
|
assign cache_wr = (state == STATE_FETCH) & wbm_ack_i; |
assign cache_wr_w = (state_q == STATE_FETCH) & mem_valid_w; |
|
endmodule |
|
/trunk/rtl/cpu/altor32_regfile_alt.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
45,15 → 45,15
//----------------------------------------------------------------- |
module altor32_regfile_alt |
( |
input clk_i /*verilator public*/, |
input rst_i /*verilator public*/, |
input wr_i /*verilator public*/, |
input [4:0] rs_i /*verilator public*/, |
input [4:0] rt_i /*verilator public*/, |
input [4:0] rd_i /*verilator public*/, |
output reg [31:0] reg_rs_o /*verilator public*/, |
output reg [31:0] reg_rt_o /*verilator public*/, |
input [31:0] reg_rd_i /*verilator public*/ |
input clk_i /*verilator public*/, |
input rst_i /*verilator public*/, |
input wr_i /*verilator public*/, |
input [4:0] ra_i /*verilator public*/, |
input [4:0] rb_i /*verilator public*/, |
input [4:0] rd_i /*verilator public*/, |
output reg [31:0] reg_ra_o /*verilator public*/, |
output reg [31:0] reg_rb_o /*verilator public*/, |
input [31:0] reg_rd_i /*verilator public*/ |
); |
|
//----------------------------------------------------------------- |
64,42 → 64,18
//----------------------------------------------------------------- |
// Registers |
//----------------------------------------------------------------- |
wire clk_delayed; |
wire [31:0] data_out1; |
wire [31:0] data_out2; |
reg write_enable; |
wire clk_delayed_w; |
wire [31:0] reg_ra_w; |
wire [31:0] reg_rb_w; |
wire write_enable_w; |
|
reg [4:0] addr_reg; |
reg [31:0] data_reg; |
reg [4:0] addr_q; |
reg [31:0] data_q; |
|
wire [31:0] q1; |
wire [31:0] q2; |
wire [31:0] ra_w; |
wire [31:0] rb_w; |
|
//----------------------------------------------------------------- |
// Async Read Process |
//----------------------------------------------------------------- |
always @ (clk_i or rs_i or rt_i or rd_i or reg_rd_i or data_out1 or data_out2 or rst_i or wr_i) |
begin |
// Read Rs |
if (rs_i == 5'b00000) |
reg_rs_o <= 32'h00000000; |
else |
reg_rs_o <= data_out1; |
|
// Read Rt |
if (rt_i == 5'b00000) |
reg_rt_o <= 32'h00000000; |
else |
reg_rt_o <= data_out2; |
|
// Write enabled? |
if ((rd_i != 5'b00000) & (wr_i == 1'b1)) |
write_enable <= 1'b1; |
else |
write_enable <= 1'b0; |
end |
|
//----------------------------------------------------------------- |
// Sync addr & data |
//----------------------------------------------------------------- |
always @ (posedge clk_i or posedge rst_i) |
106,14 → 82,14
begin |
if (rst_i) |
begin |
addr_reg <= 5'b00000; |
data_reg <= 32'h00000000; |
addr_q <= 5'b00000; |
data_q <= 32'h00000000; |
|
end |
else |
begin |
addr_reg <= rd_i; |
data_reg <= reg_rd_i; |
addr_q <= rd_i; |
data_q <= reg_rd_i; |
end |
end |
|
139,16 → 115,16
) |
lpm1 |
( |
.rdclock(clk_delayed), |
.rdclock(clk_delayed_w), |
.rdclken(1'b1), |
.rdaddress(rs_i), |
.rdaddress(ra_i), |
.rden(1'b1), |
.data(reg_rd_i), |
.wraddress(rd_i), |
.wren(write_enable), |
.wren(write_enable_w), |
.wrclock(clk_i), |
.wrclken(1'b1), |
.q(q1) |
.q(ra_w) |
); |
|
|
166,16 → 142,16
) |
lpm2 |
( |
.rdclock(clk_delayed), |
.rdclock(clk_delayed_w), |
.rdclken(1'b1), |
.rdaddress(rt_i), |
.rdaddress(rb_i), |
.rden(1'b1), |
.data(reg_rd_i), |
.wraddress(rd_i), |
.wren(write_enable), |
.wren(write_enable_w), |
.wrclock(clk_i), |
.wrclken(1'b1), |
.q(q2) |
.q(rb_w) |
); |
|
//----------------------------------------------------------------- |
183,10 → 159,26
//----------------------------------------------------------------- |
|
// Delayed clock |
assign clk_delayed = !clk_i; |
assign clk_delayed_w = !clk_i; |
|
// Register read ports |
always @ * |
begin |
if (ra_i == 5'b00000) |
reg_ra_o = 32'h00000000; |
else |
reg_ra_o = reg_ra_w; |
|
if (rb_i == 5'b00000) |
reg_rb_o = 32'h00000000; |
else |
reg_rb_o = reg_rb_w; |
end |
|
assign write_enable_w = (rd_i != 5'b00000) & wr_i; |
|
// Reads are bypassed during write-back |
assign data_out1 = (rs_i != addr_reg) ? q1 : data_reg; |
assign data_out2 = (rt_i != addr_reg) ? q2 : data_reg; |
assign reg_ra_w = (ra_i != addr_q) ? ra_w : data_q; |
assign reg_rb_w = (rb_i != addr_q) ? rb_w : data_q; |
|
endmodule |
/trunk/rtl/cpu/altor32_dfu.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
/trunk/rtl/cpu/altor32_funcs.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
/trunk/rtl/cpu/altor32.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
91,70 → 91,71
// Registers / Wires |
//----------------------------------------------------------------- |
|
// Instruction fetch |
wire fetch_rd_w; |
wire [31:0] fetch_pc_w; |
wire [31:0] fetch_opcode_w; |
wire fetch_valid_w; |
|
// Decode opcode / PC / state |
wire [31:0] dec_opcode_w; |
wire [31:0] dec_opcode_pc_w; |
wire dec_opcode_valid_w; |
|
// Register number (rA) |
wire [4:0] w_ra; |
wire [4:0] dec_ra_w; |
|
// Register number (rB) |
wire [4:0] w_rb; |
wire [4:0] dec_rb_w; |
|
// Destination register number (pre execute stage) |
wire [4:0] w_rd; |
wire [4:0] dec_rd_w; |
|
// Destination register number (post execute stage) |
wire [4:0] w_e_rd; |
|
// Register value (rA) |
wire [31:0] w_reg_ra; |
wire [31:0] dec_ra_val_w; |
|
// Register value (rB) |
wire [31:0] w_reg_rb; |
wire [31:0] dec_rb_val_w; |
|
// Current opcode |
wire [31:0] w_d_opcode; |
wire [31:0] w_d_pc; |
wire w_d_valid; |
// Destination register number (post execute stage) |
wire [4:0] ex_rd_w; |
|
wire [31:0] w_e_opcode; |
// Current executing instruction |
wire [31:0] ex_opcode_w; |
|
// Result from execute |
wire [31:0] ex_result_w; |
wire ex_mult_w; |
wire [31:0] ex_mult_res_w; |
|
// Branch request |
wire ex_branch_w; |
wire [31:0] ex_branch_pc_w; |
wire ex_stall_w; |
|
// Register writeback value |
wire [4:0] w_wb_rd; |
wire [31:0] w_wb_reg_rd; |
wire [4:0] wb_rd_w; |
wire [31:0] wb_rd_val_w; |
|
// Register writeback enable |
wire w_wb_write_rd; |
wire wb_rd_write_w; |
|
// Result from execute |
wire [31:0] w_e_result; |
wire w_e_mult; |
wire [31:0] w_e_mult_result; |
wire [31:0] dcache_addr_w; |
wire [31:0] dcache_data_out_w; |
wire [31:0] dcache_data_in_w; |
wire [3:0] dcache_sel_w; |
wire dcache_we_w; |
wire dcache_stb_w; |
wire dcache_cyc_w; |
wire dcache_ack_w; |
wire dcache_stall_w; |
|
// Branch request |
wire w_e_branch; |
wire [31:0] w_e_branch_pc; |
wire w_e_stall; |
wire icache_flush_w; |
wire dcache_flush_w; |
|
wire icache_rd; |
wire [31:0] icache_pc; |
wire [31:0] icache_inst; |
wire icache_valid; |
wire icache_invalidate; |
|
wire [31:0] dcache_addr; |
wire [31:0] dcache_data_o; |
wire [31:0] dcache_data_i; |
wire [3:0] dcache_sel; |
wire dcache_we; |
wire dcache_stb; |
wire dcache_cyc; |
wire dcache_ack; |
wire dcache_stall; |
wire dcache_flush; |
|
//----------------------------------------------------------------- |
// Instantiation |
// Instruction Cache |
//----------------------------------------------------------------- |
|
// Instruction Cache |
generate |
if (ENABLE_ICACHE == "ENABLED") |
begin : ICACHE |
169,11 → 170,11
.rst_i(rst_i), |
|
// Processor interface |
.rd_i(icache_rd), |
.pc_i(icache_pc), |
.instruction_o(icache_inst), |
.valid_o(icache_valid), |
.invalidate_i(icache_invalidate), |
.rd_i(fetch_rd_w), |
.pc_i(fetch_pc_w), |
.instruction_o(fetch_opcode_w), |
.valid_o(fetch_valid_w), |
.invalidate_i(icache_flush_w), |
|
// Instruction memory |
.wbm_addr_o(imem_addr_o), |
185,9 → 186,11
.wbm_ack_i(imem_ack_i) |
); |
end |
//----------------------------------------------------------------- |
// No instruction cache |
//----------------------------------------------------------------- |
else |
begin : NO_ICACHE |
// No instruction cache |
altor32_noicache |
u_icache |
( |
195,11 → 198,11
.rst_i(rst_i), |
|
// Processor interface |
.rd_i(icache_rd), |
.pc_i(icache_pc), |
.instruction_o(icache_inst), |
.valid_o(icache_valid), |
.invalidate_i(icache_invalidate), |
.rd_i(fetch_rd_w), |
.pc_i(fetch_pc_w), |
.instruction_o(fetch_opcode_w), |
.valid_o(fetch_valid_w), |
.invalidate_i(icache_flush_w), |
|
// Instruction memory |
.wbm_addr_o(imem_addr_o), |
213,7 → 216,9
end |
endgenerate |
|
//----------------------------------------------------------------- |
// Instruction Fetch |
//----------------------------------------------------------------- |
altor32_fetch |
#( |
.BOOT_VECTOR(BOOT_VECTOR), |
226,28 → 231,30
.rst_i(rst_i), |
|
// Instruction memory |
.pc_o(icache_pc), |
.data_i(icache_inst), |
.fetch_o(icache_rd), |
.data_valid_i(icache_valid), |
.pc_o(fetch_pc_w), |
.data_i(fetch_opcode_w), |
.fetch_o(fetch_rd_w), |
.data_valid_i(fetch_valid_w), |
|
// Fetched opcode |
.opcode_o(w_d_opcode), |
.opcode_pc_o(w_d_pc), |
.opcode_valid_o(w_d_valid), |
.opcode_o(dec_opcode_w), |
.opcode_pc_o(dec_opcode_pc_w), |
.opcode_valid_o(dec_opcode_valid_w), |
|
// Branch target |
.branch_i(w_e_branch), |
.branch_pc_i(w_e_branch_pc), |
.stall_i(w_e_stall), |
.branch_i(ex_branch_w), |
.branch_pc_i(ex_branch_pc_w), |
.stall_i(ex_stall_w), |
|
// Decoded register details |
.ra_o(w_ra), |
.rb_o(w_rb), |
.rd_o(w_rd) |
.ra_o(dec_ra_w), |
.rb_o(dec_rb_w), |
.rd_o(dec_rd_w) |
); |
|
// Register file |
//----------------------------------------------------------------- |
// [Xilinx] Register file |
//----------------------------------------------------------------- |
generate |
if (REGISTER_FILE_TYPE == "XILINX") |
begin : REGFILE_XIL |
255,22 → 262,25
#( |
.SUPPORT_32REGS(SUPPORT_32REGS) |
) |
reg_bank |
u_regfile |
( |
// Clocking |
.clk_i(clk_i), |
.rst_i(rst_i), |
.wr_i(w_wb_write_rd), |
.wr_i(wb_rd_write_w), |
|
// Tri-port |
.rs_i(w_ra), |
.rt_i(w_rb), |
.rd_i(w_wb_rd), |
.reg_rs_o(w_reg_ra), |
.reg_rt_o(w_reg_rb), |
.reg_rd_i(w_wb_reg_rd) |
.ra_i(dec_ra_w), |
.rb_i(dec_rb_w), |
.rd_i(wb_rd_w), |
.reg_ra_o(dec_ra_val_w), |
.reg_rb_o(dec_rb_val_w), |
.reg_rd_i(wb_rd_val_w) |
); |
end |
//----------------------------------------------------------------- |
// [Altera] Register file |
//----------------------------------------------------------------- |
else if (REGISTER_FILE_TYPE == "ALTERA") |
begin : REGFILE_ALT |
altor32_regfile_alt |
277,22 → 287,25
#( |
.SUPPORT_32REGS(SUPPORT_32REGS) |
) |
reg_bank |
u_regfile |
( |
// Clocking |
.clk_i(clk_i), |
.rst_i(rst_i), |
.wr_i(w_wb_write_rd), |
.wr_i(wb_rd_write_w), |
|
// Tri-port |
.rs_i(w_ra), |
.rt_i(w_rb), |
.rd_i(w_wb_rd), |
.reg_rs_o(w_reg_ra), |
.reg_rt_o(w_reg_rb), |
.reg_rd_i(w_wb_reg_rd) |
.ra_i(dec_ra_w), |
.rb_i(dec_rb_w), |
.rd_i(wb_rd_w), |
.reg_ra_o(dec_ra_val_w), |
.reg_rb_o(dec_rb_val_w), |
.reg_rd_i(wb_rd_val_w) |
); |
end |
//----------------------------------------------------------------- |
// [Simulation] Register file |
//----------------------------------------------------------------- |
else |
begin : REGFILE_SIM |
altor32_regfile_sim |
299,28 → 312,30
#( |
.SUPPORT_32REGS(SUPPORT_32REGS) |
) |
reg_bank |
u_regfile |
( |
// Clocking |
.clk_i(clk_i), |
.rst_i(rst_i), |
.wr_i(w_wb_write_rd), |
.wr_i(wb_rd_write_w), |
|
// Tri-port |
.rs_i(w_ra), |
.rt_i(w_rb), |
.rd_i(w_wb_rd), |
.reg_rs_o(w_reg_ra), |
.reg_rt_o(w_reg_rb), |
.reg_rd_i(w_wb_reg_rd) |
.ra_i(dec_ra_w), |
.rb_i(dec_rb_w), |
.rd_i(wb_rd_w), |
.reg_ra_o(dec_ra_val_w), |
.reg_rb_o(dec_rb_val_w), |
.reg_rd_i(wb_rd_val_w) |
); |
end |
endgenerate |
|
//----------------------------------------------------------------- |
// Data cache |
//----------------------------------------------------------------- |
generate |
if (ENABLE_DCACHE == "ENABLED") |
begin : DCACHE |
// Data cache |
altor32_dcache |
u_dcache |
( |
327,17 → 342,17
.clk_i(clk_i), |
.rst_i(rst_i), |
|
.flush_i(dcache_flush), |
.flush_i(dcache_flush_w), |
|
// Processor interface |
.address_i({dcache_addr[31:2], 2'b00}), |
.data_o(dcache_data_i), |
.data_i(dcache_data_o), |
.we_i(dcache_we), |
.stb_i(dcache_stb), |
.sel_i(dcache_sel), |
.stall_o(dcache_stall), |
.ack_o(dcache_ack), |
.address_i({dcache_addr_w[31:2], 2'b00}), |
.data_o(dcache_data_in_w), |
.data_i(dcache_data_out_w), |
.we_i(dcache_we_w), |
.stb_i(dcache_stb_w), |
.sel_i(dcache_sel_w), |
.stall_o(dcache_stall_w), |
.ack_o(dcache_ack_w), |
|
// Memory interface (slave) |
.mem_addr_o(dmem_addr_o), |
352,23 → 367,27
.mem_ack_i(dmem_ack_i) |
); |
end |
//----------------------------------------------------------------- |
// No data cache |
//----------------------------------------------------------------- |
else |
begin: NO_DCACHE |
// No data cache |
assign dmem_addr_o = {dcache_addr[31:2], 2'b00}; |
assign dmem_dat_o = dcache_data_o; |
assign dcache_data_i = dmem_dat_i; |
assign dmem_sel_o = dcache_sel; |
assign dmem_cyc_o = dcache_cyc; |
assign dmem_we_o = dcache_we; |
assign dmem_stb_o = dcache_stb; |
assign dmem_addr_o = {dcache_addr_w[31:2], 2'b00}; |
assign dmem_dat_o = dcache_data_out_w; |
assign dcache_data_in_w = dmem_dat_i; |
assign dmem_sel_o = dcache_sel_w; |
assign dmem_cyc_o = dcache_cyc_w; |
assign dmem_we_o = dcache_we_w; |
assign dmem_stb_o = dcache_stb_w; |
assign dmem_cti_o = 3'b111; |
assign dcache_ack = dmem_ack_i; |
assign dcache_stall = dmem_stall_i; |
assign dcache_ack_w = dmem_ack_i; |
assign dcache_stall_w = dmem_stall_i; |
end |
endgenerate |
|
//----------------------------------------------------------------- |
// Execution unit |
//----------------------------------------------------------------- |
altor32_exec |
#( |
.BOOT_VECTOR(BOOT_VECTOR), |
388,51 → 407,53
.break_o(break_o), |
|
// Cache control |
.icache_flush_o(icache_invalidate), |
.dcache_flush_o(dcache_flush), |
.icache_flush_o(icache_flush_w), |
.dcache_flush_o(dcache_flush_w), |
|
// Branch target |
.branch_o(w_e_branch), |
.branch_pc_o(w_e_branch_pc), |
.stall_o(w_e_stall), |
.branch_o(ex_branch_w), |
.branch_pc_o(ex_branch_pc_w), |
.stall_o(ex_stall_w), |
|
// Opcode & arguments |
.opcode_i(w_d_opcode), |
.opcode_pc_i(w_d_pc), |
.opcode_valid_i(w_d_valid), |
.opcode_i(dec_opcode_w), |
.opcode_pc_i(dec_opcode_pc_w), |
.opcode_valid_i(dec_opcode_valid_w), |
|
.reg_ra_i(w_ra), |
.reg_ra_value_i(w_reg_ra), |
// Operands |
.reg_ra_i(dec_ra_w), |
.reg_ra_value_i(dec_ra_val_w), |
.reg_rb_i(dec_rb_w), |
.reg_rb_value_i(dec_rb_val_w), |
.reg_rd_i(dec_rd_w), |
|
.reg_rb_i(w_rb), |
.reg_rb_value_i(w_reg_rb), |
|
.reg_rd_i(w_rd), |
|
// Output |
.opcode_o(w_e_opcode), |
.reg_rd_o(w_e_rd), |
.reg_rd_value_o(w_e_result), |
.mult_o(w_e_mult), |
.mult_res_o(w_e_mult_result), |
.opcode_o(ex_opcode_w), |
.opcode_pc_o(/* not used */), |
.reg_rd_o(ex_rd_w), |
.reg_rd_value_o(ex_result_w), |
.mult_o(ex_mult_w), |
.mult_res_o(ex_mult_res_w), |
|
// Register write back bypass |
.wb_rd_i(w_wb_rd), |
.wb_rd_value_i(w_wb_reg_rd), |
.wb_rd_i(wb_rd_w), |
.wb_rd_value_i(wb_rd_val_w), |
|
// Memory Interface |
.dmem_addr_o(dcache_addr), |
.dmem_data_out_o(dcache_data_o), |
.dmem_data_in_i(dcache_data_i), |
.dmem_sel_o(dcache_sel), |
.dmem_we_o(dcache_we), |
.dmem_stb_o(dcache_stb), |
.dmem_cyc_o(dcache_cyc), |
.dmem_stall_i(dcache_stall), |
.dmem_ack_i(dcache_ack) |
.dmem_addr_o(dcache_addr_w), |
.dmem_data_out_o(dcache_data_out_w), |
.dmem_data_in_i(dcache_data_in_w), |
.dmem_sel_o(dcache_sel_w), |
.dmem_we_o(dcache_we_w), |
.dmem_stb_o(dcache_stb_w), |
.dmem_cyc_o(dcache_cyc_w), |
.dmem_stall_i(dcache_stall_w), |
.dmem_ack_i(dcache_ack_w) |
); |
|
//----------------------------------------------------------------- |
// Register file writeback |
//----------------------------------------------------------------- |
altor32_writeback |
u_wb |
( |
441,27 → 462,27
.rst_i(rst_i), |
|
// Opcode |
.opcode_i(w_e_opcode), |
.opcode_i(ex_opcode_w), |
|
// Register target |
.rd_i(w_e_rd), |
.rd_i(ex_rd_w), |
|
// ALU result |
.alu_result_i(w_e_result), |
.alu_result_i(ex_result_w), |
|
// Memory load result |
.mem_result_i(dcache_data_i), |
.mem_offset_i(dcache_addr[1:0]), |
.mem_ready_i(dcache_ack), |
.mem_result_i(dcache_data_in_w), |
.mem_offset_i(dcache_addr_w[1:0]), |
.mem_ready_i(dcache_ack_w), |
|
// Multiplier result |
.mult_i(w_e_mult), |
.mult_result_i(w_e_mult_result), |
.mult_i(ex_mult_w), |
.mult_result_i(ex_mult_res_w), |
|
// Outputs |
.write_enable_o(w_wb_write_rd), |
.write_addr_o(w_wb_rd), |
.write_data_o(w_wb_reg_rd) |
.write_enable_o(wb_rd_write_w), |
.write_addr_o(wb_rd_w), |
.write_data_o(wb_rd_val_w) |
); |
|
//------------------------------------------------------------------- |
470,7 → 491,7
`ifdef verilator |
function [31:0] get_pc; |
// verilator public |
get_pc = w_d_pc; |
get_pc = dec_opcode_pc_w; |
endfunction |
function get_fault; |
// verilator public |
/trunk/rtl/cpu/altor32_wb_fetch.v
0,0 → 1,178
//----------------------------------------------------------------- |
// AltOR32 |
// Alternative Lightweight OpenRisc |
// V2.1 |
// Ultra-Embedded.com |
// Copyright 2011 - 2014 |
// |
// Email: admin@ultra-embedded.com |
// |
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
// removed from the file and that any derivative work contains |
// the original copyright notice and the associated disclaimer. |
// |
// This source file is free software; you can redistribute it |
// and/or modify it under the terms of the GNU Lesser General |
// Public License as published by the Free Software Foundation; |
// either version 2.1 of the License, or (at your option) any |
// later version. |
// |
// This source is distributed in the hope that it will be |
// useful, but WITHOUT ANY WARRANTY; without even the implied |
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU Lesser General Public License for more |
// details. |
// |
// You should have received a copy of the GNU Lesser General |
// Public License along with this source; if not, write to the |
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
// Boston, MA 02111-1307 USA |
//----------------------------------------------------------------- |
|
//----------------------------------------------------------------- |
// Includes |
//----------------------------------------------------------------- |
`include "altor32_defs.v" |
|
//----------------------------------------------------------------- |
// Module - Wishbone fetch unit |
//----------------------------------------------------------------- |
module altor32_wb_fetch |
( |
input clk_i /*verilator public*/, |
input rst_i /*verilator public*/, |
|
// Fetch |
input fetch_i /*verilator public*/, |
input burst_i /*verilator public*/, |
input [31:0] address_i /*verilator public*/, |
|
// Response |
output [31:0] resp_addr_o /*verilator public*/, |
output [31:0] data_o /*verilator public*/, |
output valid_o /*verilator public*/, |
output final_o /*verilator public*/, |
|
// Memory interface |
output reg [31:0] wbm_addr_o /*verilator public*/, |
input [31:0] wbm_dat_i /*verilator public*/, |
output reg [2:0] wbm_cti_o /*verilator public*/, |
output reg wbm_cyc_o /*verilator public*/, |
output reg wbm_stb_o /*verilator public*/, |
input wbm_stall_i/*verilator public*/, |
input wbm_ack_i/*verilator public*/ |
); |
|
//----------------------------------------------------------------- |
// Params |
//----------------------------------------------------------------- |
parameter FETCH_WORDS_W = 3; /* 2 ^ 3 * 4 = 32 */ |
parameter FETCH_BYTES_W = FETCH_WORDS_W + 2; |
|
parameter WB_CTI_BURST = 3'b010; |
parameter WB_CTI_FINAL = 3'b111; |
|
//----------------------------------------------------------------- |
// Registers / Wires |
//----------------------------------------------------------------- |
|
// Word currently being fetched within a line |
reg [FETCH_WORDS_W-1:0] fetch_word_q; |
reg [FETCH_WORDS_W-1:0] resp_word_q; |
|
wire [FETCH_WORDS_W-1:0] next_word_w = fetch_word_q + 1; |
|
wire penultimate_word_w = (fetch_word_q == ({FETCH_WORDS_W{1'b1}}-1)); |
|
wire final_resp_w = ((resp_word_q == {FETCH_WORDS_W{1'b1}}) | ~burst_i); |
|
//----------------------------------------------------------------- |
// Pipelined Wishbone Master |
//----------------------------------------------------------------- |
always @ (posedge rst_i or posedge clk_i ) |
begin |
if (rst_i == 1'b1) |
begin |
wbm_addr_o <= 32'h00000000; |
wbm_cti_o <= 3'b0; |
wbm_stb_o <= 1'b0; |
wbm_cyc_o <= 1'b0; |
|
fetch_word_q <= {FETCH_WORDS_W{1'b0}}; |
resp_word_q <= {FETCH_WORDS_W{1'b0}}; |
end |
else |
begin |
// Idle |
if (!wbm_cyc_o) |
begin |
if (fetch_i) |
begin |
if (burst_i) |
begin |
wbm_addr_o <= {address_i[31:FETCH_BYTES_W], {FETCH_BYTES_W{1'b0}}}; |
fetch_word_q <= {FETCH_WORDS_W{1'b0}}; |
resp_word_q <= {FETCH_WORDS_W{1'b0}}; |
|
// Incrementing linear burst |
wbm_cti_o <= WB_CTI_BURST; |
end |
else |
begin |
wbm_addr_o <= address_i; |
resp_word_q <= address_i[FETCH_BYTES_W-1:2]; |
|
// Single fetch |
wbm_cti_o <= WB_CTI_FINAL; |
end |
|
// Start fetch from memory |
wbm_stb_o <= 1'b1; |
wbm_cyc_o <= 1'b1; |
end |
end |
// Access in-progress |
else |
begin |
// Command accepted |
if (~wbm_stall_i) |
begin |
// Fetch next word for line |
if (wbm_cti_o != WB_CTI_FINAL) |
begin |
wbm_addr_o <= {wbm_addr_o[31:FETCH_BYTES_W], next_word_w, 2'b0}; |
fetch_word_q <= next_word_w; |
|
// Final word to read? |
if (penultimate_word_w) |
wbm_cti_o <= WB_CTI_FINAL; |
end |
// Fetch complete |
else |
wbm_stb_o <= 1'b0; |
end |
|
// Response |
if (wbm_ack_i) |
resp_word_q <= resp_word_q + 1; |
|
// Last response? |
if (final_o) |
wbm_cyc_o <= 1'b0; |
end |
end |
end |
|
// Response |
assign data_o = wbm_dat_i; |
assign valid_o = wbm_ack_i; |
assign final_o = final_resp_w & wbm_ack_i; |
assign resp_addr_o = {address_i[31:FETCH_BYTES_W], resp_word_q, 2'b0}; |
|
endmodule |
/trunk/rtl/cpu/altor32_alu.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
73,18 → 73,18
//----------------------------------------------------------------- |
// Registers |
//----------------------------------------------------------------- |
reg [31:0] result; |
reg [31:0] result_r; |
|
reg [31:16] shift_right_fill; |
reg [31:0] shift_right_1; |
reg [31:0] shift_right_2; |
reg [31:0] shift_right_4; |
reg [31:0] shift_right_8; |
reg [31:16] shift_right_fill_r; |
reg [31:0] shift_right_1_r; |
reg [31:0] shift_right_2_r; |
reg [31:0] shift_right_4_r; |
reg [31:0] shift_right_8_r; |
|
reg [31:0] shift_left_1; |
reg [31:0] shift_left_2; |
reg [31:0] shift_left_4; |
reg [31:0] shift_left_8; |
reg [31:0] shift_left_1_r; |
reg [31:0] shift_left_2_r; |
reg [31:0] shift_left_4_r; |
reg [31:0] shift_left_8_r; |
|
//----------------------------------------------------------------- |
// ALU |
98,29 → 98,29
`ALU_SHIFTL : |
begin |
if (b_i[0] == 1'b1) |
shift_left_1 = {a_i[30:0],1'b0}; |
shift_left_1_r = {a_i[30:0],1'b0}; |
else |
shift_left_1 = a_i; |
shift_left_1_r = a_i; |
|
if (b_i[1] == 1'b1) |
shift_left_2 = {shift_left_1[29:0],2'b00}; |
shift_left_2_r = {shift_left_1_r[29:0],2'b00}; |
else |
shift_left_2 = shift_left_1; |
shift_left_2_r = shift_left_1_r; |
|
if (b_i[2] == 1'b1) |
shift_left_4 = {shift_left_2[27:0],4'b0000}; |
shift_left_4_r = {shift_left_2_r[27:0],4'b0000}; |
else |
shift_left_4 = shift_left_2; |
shift_left_4_r = shift_left_2_r; |
|
if (b_i[3] == 1'b1) |
shift_left_8 = {shift_left_4[23:0],8'b00000000}; |
shift_left_8_r = {shift_left_4_r[23:0],8'b00000000}; |
else |
shift_left_8 = shift_left_4; |
shift_left_8_r = shift_left_4_r; |
|
if (b_i[4] == 1'b1) |
result = {shift_left_8[15:0],16'b0000000000000000}; |
result_r = {shift_left_8_r[15:0],16'b0000000000000000}; |
else |
result = shift_left_8; |
result_r = shift_left_8_r; |
|
c_o = 1'b0; |
c_update_o = 1'b0; |
132,34 → 132,34
begin |
// Arithmetic shift? Fill with 1's if MSB set |
if (a_i[31] == 1'b1 && op_i == `ALU_SHIRTR_ARITH) |
shift_right_fill = 16'b1111111111111111; |
shift_right_fill_r = 16'b1111111111111111; |
else |
shift_right_fill = 16'b0000000000000000; |
shift_right_fill_r = 16'b0000000000000000; |
|
if (b_i[0] == 1'b1) |
shift_right_1 = {shift_right_fill[31], a_i[31:1]}; |
shift_right_1_r = {shift_right_fill_r[31], a_i[31:1]}; |
else |
shift_right_1 = a_i; |
shift_right_1_r = a_i; |
|
if (b_i[1] == 1'b1) |
shift_right_2 = {shift_right_fill[31:30], shift_right_1[31:2]}; |
shift_right_2_r = {shift_right_fill_r[31:30], shift_right_1_r[31:2]}; |
else |
shift_right_2 = shift_right_1; |
shift_right_2_r = shift_right_1_r; |
|
if (b_i[2] == 1'b1) |
shift_right_4 = {shift_right_fill[31:28], shift_right_2[31:4]}; |
shift_right_4_r = {shift_right_fill_r[31:28], shift_right_2_r[31:4]}; |
else |
shift_right_4 = shift_right_2; |
shift_right_4_r = shift_right_2_r; |
|
if (b_i[3] == 1'b1) |
shift_right_8 = {shift_right_fill[31:24], shift_right_4[31:8]}; |
shift_right_8_r = {shift_right_fill_r[31:24], shift_right_4_r[31:8]}; |
else |
shift_right_8 = shift_right_4; |
shift_right_8_r = shift_right_4_r; |
|
if (b_i[4] == 1'b1) |
result = {shift_right_fill[31:16], shift_right_8[31:16]}; |
result_r = {shift_right_fill_r[31:16], shift_right_8_r[31:16]}; |
else |
result = shift_right_8; |
result_r = shift_right_8_r; |
|
c_o = 1'b0; |
c_update_o = 1'b0; |
169,17 → 169,17
//---------------------------------------------- |
`ALU_ADD : |
begin |
{c_o, result} = (a_i + b_i); |
c_update_o = 1'b1; |
{c_o, result_r} = (a_i + b_i); |
c_update_o = 1'b1; |
end |
`ALU_ADDC : |
begin |
{c_o, result} = (a_i + b_i) + {31'h00000000, c_i}; |
c_update_o = 1'b1; |
{c_o, result_r} = (a_i + b_i) + {31'h00000000, c_i}; |
c_update_o = 1'b1; |
end |
`ALU_SUB : |
begin |
result = (a_i - b_i); |
result_r = (a_i - b_i); |
c_o = 1'b0; |
c_update_o = 1'b0; |
end |
188,25 → 188,25
//---------------------------------------------- |
`ALU_AND : |
begin |
result = (a_i & b_i); |
result_r = (a_i & b_i); |
c_o = 1'b0; |
c_update_o = 1'b0; |
end |
`ALU_OR : |
begin |
result = (a_i | b_i); |
result_r = (a_i | b_i); |
c_o = 1'b0; |
c_update_o = 1'b0; |
end |
`ALU_XOR : |
begin |
result = (a_i ^ b_i); |
result_r = (a_i ^ b_i); |
c_o = 1'b0; |
c_update_o = 1'b0; |
end |
default : |
begin |
result = a_i; |
result_r = a_i; |
c_o = 1'b0; |
c_update_o = 1'b0; |
end |
213,7 → 213,7
endcase |
end |
|
assign p_o = result; |
assign p_o = result_r; |
|
//----------------------------------------------------------------- |
// Comparisons |
/trunk/rtl/cpu/altor32_defs.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
/trunk/rtl/cpu/altor32_ram_sp.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
55,7 → 55,7
// Registers |
//----------------------------------------------------------------- |
reg [(WIDTH - 1):0] ram [((2<< (SIZE-1)) - 1):0] /*verilator public*/; |
reg [(SIZE - 1):0] rd_addr; |
reg [(SIZE - 1):0] rd_addr_q; |
|
//----------------------------------------------------------------- |
// Processes |
64,12 → 64,26
begin |
if (wr_i == 1'b1) |
ram[adr_i] <= dat_i; |
rd_addr <= adr_i; |
rd_addr_q <= adr_i; |
end |
|
//------------------------------------------------------------------- |
// Combinatorial |
//------------------------------------------------------------------- |
assign dat_o = ram[rd_addr]; |
assign dat_o = ram[rd_addr_q]; |
|
//----------------------------------------------------------------- |
// Init Memory |
//----------------------------------------------------------------- |
`ifdef ALTOR32_CLEAR_RAM |
integer i; |
initial |
begin |
for (i=0;i<((2<< (SIZE-1)) - 1);i=i+1) |
begin |
ram[i] = 0; |
end |
end |
`endif |
|
endmodule |
/trunk/rtl/cpu/altor32_dcache_mem_if.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
/trunk/rtl/cpu/altor32_exec.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
86,6 → 86,7
|
// Output |
output [31:0] opcode_o /*verilator public*/, |
output [31:0] opcode_pc_o /*verilator public*/, |
output [4:0] reg_rd_o /*verilator public*/, |
output [31:0] reg_rd_value_o /*verilator public*/, |
output mult_o /*verilator public*/, |
124,105 → 125,103
//----------------------------------------------------------------- |
|
// Branch PC |
reg [31:0] r_pc_branch; |
reg r_pc_fetch; |
reg [31:0] pc_branch_q; |
reg pc_fetch_q; |
|
// Exception saved program counter |
reg [31:0] r_epc; |
reg [31:0] epc_q; |
|
// Supervisor register |
reg [31:0] r_sr; |
reg [31:0] sr_q; |
|
// Exception saved supervisor register |
reg [31:0] r_esr; |
reg [31:0] esr_q; |
|
// Destination register number (post execute stage) |
reg [4:0] r_e_rd; |
reg [4:0] ex_rd_q; |
|
// Current opcode (PC for debug) |
reg [31:0] r_e_opcode; |
reg [31:0] r_e_opcode_pc; |
reg [31:0] ex_opcode_q; |
reg [31:0] ex_opcode_pc_q; |
|
// ALU input A |
reg [31:0] r_e_alu_a; |
reg [31:0] ex_alu_a_q; |
|
// ALU input B |
reg [31:0] r_e_alu_b; |
reg [31:0] ex_alu_b_q; |
|
// ALU output |
wire [31:0] r_e_result; |
wire [31:0] ex_result_w; |
|
// Resolved RA/RB register contents |
wire [31:0] ra_value_resolved; |
wire [31:0] rb_value_resolved; |
wire operand_resolved; |
wire resolve_failed; |
wire [31:0] ra_resolved_w; |
wire [31:0] rb_resolved_w; |
wire operand_resolved_w; |
wire resolve_failed_w; |
|
// ALU Carry |
wire alu_carry_out; |
wire alu_carry_update; |
wire alu_flag_update; |
wire alu_carry_out_w; |
wire alu_carry_update_w; |
wire alu_flag_update_w; |
|
// ALU Comparisons |
wire compare_equal_w; |
wire compare_gts_w; |
wire compare_gt_w; |
wire compare_lts_w; |
wire compare_lt_w; |
wire compare_equal_w; |
wire compare_gts_w; |
wire compare_gt_w; |
wire compare_lts_w; |
wire compare_lt_w; |
|
// ALU operation selection |
reg [3:0] r_e_alu_func; |
reg [3:0] ex_alu_func_q; |
|
// Load instruction details |
reg [4:0] r_load_rd; |
reg [7:0] r_load_inst; |
reg [1:0] r_load_offset; |
reg [4:0] load_rd_q; |
reg [7:0] load_inst_q; |
reg [1:0] load_offset_q; |
|
// Load forwarding |
wire load_insn; |
wire [31:0] load_result; |
wire load_inst_w; |
wire [31:0] load_result_w; |
|
// Memory access? |
reg r_mem_load; |
reg r_mem_store; |
reg r_mem_access; |
reg mem_load_q; |
reg mem_store_q; |
reg mem_access_q; |
|
wire load_pending; |
wire store_pending; |
wire load_insert; |
wire load_stall; |
wire load_pending_w; |
wire store_pending_w; |
wire load_insert_w; |
wire load_stall_w; |
|
reg d_mem_load; |
reg d_mem_load_q; |
|
// Delayed NMI |
reg r_nmi; |
reg nmi_q; |
|
// SIM PUTC |
`ifdef SIM_EXT_PUTC |
reg [7:0] r_putc; |
reg [7:0] putc_q; |
`endif |
|
//----------------------------------------------------------------- |
// Instantiation |
// ALU |
//----------------------------------------------------------------- |
|
// ALU |
altor32_alu alu |
( |
// ALU operation select |
.op_i(r_e_alu_func), |
.op_i(ex_alu_func_q), |
|
// Operands |
.a_i(r_e_alu_a), |
.b_i(r_e_alu_b), |
.c_i(r_sr[`OR32_SR_CY]), |
.a_i(ex_alu_a_q), |
.b_i(ex_alu_b_q), |
.c_i(sr_q[`OR32_SR_CY]), |
|
// Result |
.p_o(r_e_result), |
.p_o(ex_result_w), |
|
// Carry |
.c_o(alu_carry_out), |
.c_update_o(alu_carry_update), |
.c_o(alu_carry_out_w), |
.c_update_o(alu_carry_update_w), |
|
// Comparisons |
.equal_o(compare_equal_w), |
230,59 → 229,65
.greater_than_o(compare_gt_w), |
.less_than_signed_o(compare_lts_w), |
.less_than_o(compare_lt_w), |
.flag_update_o(alu_flag_update) |
.flag_update_o(alu_flag_update_w) |
); |
|
//----------------------------------------------------------------- |
// Load result forwarding |
//----------------------------------------------------------------- |
altor32_lfu |
u_lfu |
( |
// Opcode |
.opcode_i(r_load_inst), |
.opcode_i(load_inst_q), |
|
// Memory load result |
.mem_result_i(dmem_data_in_i), |
.mem_offset_i(r_load_offset), |
.mem_offset_i(load_offset_q), |
|
// Result |
.load_result_o(load_result), |
.load_insn_o(load_insn) |
.load_result_o(load_result_w), |
.load_insn_o(load_inst_w) |
); |
|
//----------------------------------------------------------------- |
// Load / store pending logic |
//----------------------------------------------------------------- |
altor32_lsu |
u_lsu |
( |
// Current instruction |
.opcode_valid_i(opcode_valid_i & ~r_pc_fetch), |
.opcode_valid_i(opcode_valid_i & ~pc_fetch_q), |
.opcode_i({2'b00,opcode_i[31:26]}), |
|
// Load / Store pending |
.load_pending_i(r_mem_load), |
.store_pending_i(r_mem_store), |
.load_pending_i(mem_load_q), |
.store_pending_i(mem_store_q), |
|
// Load dest register |
.rd_load_i(r_load_rd), |
.rd_load_i(load_rd_q), |
|
// Load insn in WB stage |
.load_wb_i(d_mem_load), |
.load_wb_i(d_mem_load_q), |
|
// Memory status |
.mem_access_i(r_mem_access), |
.mem_access_i(mem_access_q), |
.mem_ack_i(dmem_ack_i), |
|
// Load / store still pending |
.load_pending_o(load_pending), |
.store_pending_o(store_pending), |
.load_pending_o(load_pending_w), |
.store_pending_o(store_pending_w), |
|
// Insert load result into pipeline |
.write_result_o(load_insert), |
.write_result_o(load_insert_w), |
|
// Stall pipeline due |
.stall_o(load_stall) |
.stall_o(load_stall_w) |
); |
|
//----------------------------------------------------------------- |
// Operand forwarding |
//----------------------------------------------------------------- |
altor32_dfu |
u_dfu |
( |
295,14 → 300,14
.rb_regval_i(reg_rb_value_i), |
|
// Dest register (EXEC stage) |
.rd_ex_i(r_e_rd), |
.rd_ex_i(ex_rd_q), |
|
// Dest register (WB stage) |
.rd_wb_i(wb_rd_i), |
|
// Load pending / target |
.load_pending_i(load_pending), |
.rd_load_i(r_load_rd), |
.load_pending_i(load_pending_w), |
.rd_load_i(load_rd_q), |
|
// Multiplier status |
.mult_lo_ex_i(1'b0), |
314,20 → 319,20
.result_mult_i(64'b0), |
|
// Result (EXEC) |
.result_ex_i(r_e_result), |
.result_ex_i(ex_result_w), |
|
// Result (WB) |
.result_wb_i(wb_rd_value_i), |
|
// Resolved register values |
.result_ra_o(ra_value_resolved), |
.result_rb_o(rb_value_resolved), |
.result_ra_o(ra_resolved_w), |
.result_rb_o(rb_resolved_w), |
|
// Operands required forwarding |
.resolved_o(operand_resolved), |
.resolved_o(operand_resolved_w), |
|
// Stall due to failed resolve |
.stall_o(resolve_failed) |
.stall_o(resolve_failed_w) |
); |
|
//----------------------------------------------------------------- |
370,11 → 375,11
uint32_r = extend_imm16(opcode_i[15:0]); |
|
// Register values [ra/rb] |
reg_ra_r = ra_value_resolved; |
reg_rb_r = rb_value_resolved; |
reg_ra_r = ra_resolved_w; |
reg_rb_r = rb_resolved_w; |
|
// Shift ammount (from register[rb]) |
shift_rb_r = {26'b00,rb_value_resolved[5:0]}; |
shift_rb_r = {26'b00,rb_resolved_w[5:0]}; |
|
// Shift ammount (from immediate) |
shift_imm_r = {26'b00,opcode_i[5:0]}; |
461,11 → 466,11
stall_inst_r = 1'b0; |
|
// No opcode ready or branch delay slot |
if (~opcode_valid_i | r_pc_fetch) |
if (~opcode_valid_i | pc_fetch_q) |
execute_inst_r = 1'b0; |
// Valid instruction, but load result / operand not ready |
else if (resolve_failed | load_stall | |
(operand_resolved & (inst_mfspr_w | inst_mtspr_w))) |
else if (resolve_failed_w | load_stall_w | |
(operand_resolved_w & (inst_mfspr_w | inst_mtspr_w))) |
stall_inst_r = 1'b1; |
end |
|
487,15 → 492,15
reg compare_result_r; |
always @ * |
begin |
next_sr_r = r_sr; |
next_sr_r = sr_q; |
|
// Update SR.F |
if (alu_flag_update) |
if (alu_flag_update_w) |
next_sr_r[`OR32_SR_F] = compare_result_r; |
|
// Latch carry if updated |
if (alu_carry_update) |
next_sr_r[`OR32_SR_CY] = alu_carry_out; |
if (alu_carry_update_w) |
next_sr_r[`OR32_SR_CY] = alu_carry_out_w; |
|
// If valid instruction, check if SR needs updating |
if (execute_inst_r & ~stall_inst_r) |
518,7 → 523,7
endcase |
end |
inst_rfe_w: |
next_sr_r = r_esr; |
next_sr_r = esr_q; |
default: |
; |
endcase |
533,8 → 538,8
|
always @ * |
begin |
next_epc_r = r_epc; |
next_esr_r = r_esr; |
next_epc_r = epc_q; |
next_esr_r = esr_q; |
|
case (1'b1) |
inst_mtspr_w: // l.mtspr |
692,7 → 697,7
// EPCR - EPC Exception saved PC |
`SPR_REG_EPCR: |
begin |
alu_input_a_r = r_epc; |
alu_input_a_r = epc_q; |
write_rd_r = 1'b1; |
end |
|
699,7 → 704,7
// ESR - Exception saved SR |
`SPR_REG_ESR: |
begin |
alu_input_a_r = r_esr; |
alu_input_a_r = esr_q; |
write_rd_r = 1'b1; |
end |
default: |
985,7 → 990,7
inst_rfe_w: // l.rfe |
begin |
branch_r = 1'b1; |
branch_target_r = r_epc; |
branch_target_r = epc_q; |
end |
|
inst_sys_w: // l.sys |
1023,7 → 1028,7
inst_sra_w, |
inst_srl_w, |
inst_sub_w, |
inst_xor_w, |
inst_xor_w, |
inst_addi_w, |
inst_andi_w, |
inst_bf_w, |
1076,10 → 1081,10
begin |
if (rst_i == 1'b1) |
begin |
r_e_alu_func <= `ALU_NONE; |
r_e_alu_a <= 32'h00000000; |
r_e_alu_b <= 32'h00000000; |
r_e_rd <= 5'b00000; |
ex_alu_func_q <= `ALU_NONE; |
ex_alu_a_q <= 32'h00000000; |
ex_alu_b_q <= 32'h00000000; |
ex_rd_q <= 5'b00000; |
end |
else |
begin |
1089,21 → 1094,21
if (~execute_inst_r | stall_inst_r) |
begin |
// Insert load result? |
if (load_insert) |
if (load_insert_w) |
begin |
// Feed load result into pipeline |
r_e_alu_func <= `ALU_NONE; |
r_e_alu_a <= load_result; |
r_e_alu_b <= 32'b0; |
r_e_rd <= r_load_rd; |
ex_alu_func_q <= `ALU_NONE; |
ex_alu_a_q <= load_result_w; |
ex_alu_b_q <= 32'b0; |
ex_rd_q <= load_rd_q; |
end |
else |
begin |
// No ALU operation (output == input_a) |
r_e_alu_func <= `ALU_NONE; |
r_e_alu_a <= 32'b0; |
r_e_alu_b <= 32'b0; |
r_e_rd <= 5'b0; |
ex_alu_func_q <= `ALU_NONE; |
ex_alu_a_q <= 32'b0; |
ex_alu_b_q <= 32'b0; |
ex_rd_q <= 5'b0; |
end |
end |
//--------------------------------------------------------------- |
1112,18 → 1117,18
else |
begin |
// Update ALU input flops |
r_e_alu_func <= alu_func_r; |
r_e_alu_a <= alu_input_a_r; |
r_e_alu_b <= alu_input_b_r; |
ex_alu_func_q <= alu_func_r; |
ex_alu_a_q <= alu_input_a_r; |
ex_alu_b_q <= alu_input_b_r; |
|
// Branch and link (Rd = LR/R9) |
if (branch_link_r) |
r_e_rd <= 5'd9; |
ex_rd_q <= 5'd9; |
// Instruction with register writeback |
else if (write_rd_r) |
r_e_rd <= reg_rd_i; |
ex_rd_q <= reg_rd_i; |
else |
r_e_rd <= 5'b0; |
ex_rd_q <= 5'b0; |
end |
end |
end |
1135,8 → 1140,8
begin |
if (rst_i == 1'b1) |
begin |
r_e_opcode <= 32'h00000000; |
r_e_opcode_pc <= 32'h00000000; |
ex_opcode_q <= 32'h00000000; |
ex_opcode_pc_q <= 32'h00000000; |
end |
else |
begin |
1144,15 → 1149,15
if (~execute_inst_r | stall_inst_r) |
begin |
// Store bubble opcode |
r_e_opcode <= `OPCODE_INST_BUBBLE; |
r_e_opcode_pc <= opcode_pc_i; |
ex_opcode_q <= `OPCODE_INST_BUBBLE; |
ex_opcode_pc_q <= opcode_pc_i; |
end |
// Valid instruction |
else |
begin |
// Store opcode |
r_e_opcode <= opcode_i; |
r_e_opcode_pc <= opcode_pc_i; |
ex_opcode_q <= opcode_i; |
ex_opcode_pc_q <= opcode_pc_i; |
|
`ifdef CONF_CORE_TRACE |
$display("%08x: Execute 0x%08x", opcode_pc_i, opcode_i); |
1170,29 → 1175,29
begin |
if (rst_i == 1'b1) |
begin |
r_pc_branch <= 32'h00000000; |
r_pc_fetch <= 1'b0; |
pc_branch_q <= 32'h00000000; |
pc_fetch_q <= 1'b0; |
|
// Status registers |
r_epc <= 32'h00000000; |
r_sr <= 32'h00000000; |
r_esr <= 32'h00000000; |
epc_q <= 32'h00000000; |
sr_q <= 32'h00000000; |
esr_q <= 32'h00000000; |
|
fault_o <= 1'b0; |
|
r_nmi <= 1'b0; |
nmi_q <= 1'b0; |
end |
else |
begin |
// Record NMI in-case it can't be processed this cycle |
if (nmi_i) |
r_nmi <= 1'b1; |
nmi_q <= 1'b1; |
|
// Reset branch request |
r_pc_fetch <= 1'b0; |
pc_fetch_q <= 1'b0; |
|
// Update SR |
r_sr <= next_sr_r; |
sr_q <= next_sr_r; |
|
// Instruction ready |
if (execute_inst_r & ~stall_inst_r) |
1201,18 → 1206,18
if (invalid_inst_r || (opcode_pc_i[1:0] != 2'b00)) |
begin |
// Save PC of next instruction |
r_epc <= next_pc_r; |
r_esr <= next_sr_r; |
epc_q <= next_pc_r; |
esr_q <= next_sr_r; |
|
// Disable further interrupts |
r_sr <= 32'b0; |
sr_q <= 32'b0; |
|
// Set PC to exception vector |
if (invalid_inst_r) |
r_pc_branch <= ISR_VECTOR + `VECTOR_ILLEGAL_INST; |
pc_branch_q <= ISR_VECTOR + `VECTOR_ILLEGAL_INST; |
else |
r_pc_branch <= ISR_VECTOR + `VECTOR_BUS_ERROR; |
r_pc_fetch <= 1'b1; |
pc_branch_q <= ISR_VECTOR + `VECTOR_BUS_ERROR; |
pc_fetch_q <= 1'b1; |
|
fault_o <= 1'b1; |
end |
1220,15 → 1225,15
else if (branch_except_r) |
begin |
// Save PC of next instruction |
r_epc <= next_pc_r; |
r_esr <= next_sr_r; |
epc_q <= next_pc_r; |
esr_q <= next_sr_r; |
|
// Disable further interrupts |
r_sr <= 32'b0; |
sr_q <= 32'b0; |
|
// Set PC to exception vector |
r_pc_branch <= branch_target_r; |
r_pc_fetch <= 1'b1; |
pc_branch_q <= branch_target_r; |
pc_fetch_q <= 1'b1; |
|
`ifdef CONF_CORE_DEBUG |
$display(" Exception 0x%08x", branch_target_r); |
1235,25 → 1240,25
`endif |
end |
// Non-maskable interrupt |
else if (nmi_i | r_nmi) |
else if (nmi_i | nmi_q) |
begin |
r_nmi <= 1'b0; |
nmi_q <= 1'b0; |
|
// Save PC of next instruction |
if (branch_r) |
r_epc <= branch_target_r; |
epc_q <= branch_target_r; |
// Next expected PC (current PC + 4) |
else |
r_epc <= next_pc_r; |
epc_q <= next_pc_r; |
|
r_esr <= next_sr_r; |
esr_q <= next_sr_r; |
|
// Disable further interrupts |
r_sr <= 32'b0; |
sr_q <= 32'b0; |
|
// Set PC to exception vector |
r_pc_branch <= ISR_VECTOR + `VECTOR_NMI; |
r_pc_fetch <= 1'b1; |
pc_branch_q <= ISR_VECTOR + `VECTOR_NMI; |
pc_fetch_q <= 1'b1; |
|
`ifdef CONF_CORE_DEBUG |
$display(" NMI 0x%08x", ISR_VECTOR + `VECTOR_NMI); |
1264,19 → 1269,19
begin |
// Save PC of next instruction & SR |
if (branch_r) |
r_epc <= branch_target_r; |
epc_q <= branch_target_r; |
// Next expected PC (current PC + 4) |
else |
r_epc <= next_pc_r; |
epc_q <= next_pc_r; |
|
r_esr <= next_sr_r; |
esr_q <= next_sr_r; |
|
// Disable further interrupts |
r_sr <= 32'b0; |
sr_q <= 32'b0; |
|
// Set PC to external interrupt vector |
r_pc_branch <= ISR_VECTOR + `VECTOR_EXTINT; |
r_pc_fetch <= 1'b1; |
pc_branch_q <= ISR_VECTOR + `VECTOR_EXTINT; |
pc_fetch_q <= 1'b1; |
|
`ifdef CONF_CORE_DEBUG |
$display(" External Interrupt 0x%08x", ISR_VECTOR + `VECTOR_EXTINT); |
1286,8 → 1291,8
else if (branch_r) |
begin |
// Perform branch |
r_pc_branch <= branch_target_r; |
r_pc_fetch <= 1'b1; |
pc_branch_q <= branch_target_r; |
pc_fetch_q <= 1'b1; |
|
`ifdef CONF_CORE_DEBUG |
$display(" Branch to 0x%08x", branch_target_r); |
1298,8 → 1303,8
begin |
// Update EPC / ESR which may have been updated |
// by an MTSPR write |
r_epc <= next_epc_r; |
r_esr <= next_esr_r; |
epc_q <= next_epc_r; |
esr_q <= next_esr_r; |
end |
end |
end |
1320,15 → 1325,15
dmem_stb_o <= 1'b0; |
dmem_cyc_o <= 1'b0; |
|
r_mem_load <= 1'b0; |
r_mem_store <= 1'b0; |
r_mem_access <= 1'b0; |
mem_load_q <= 1'b0; |
mem_store_q <= 1'b0; |
mem_access_q <= 1'b0; |
|
r_load_rd <= 5'b00000; |
r_load_inst <= 8'h00; |
r_load_offset <= 2'b00; |
load_rd_q <= 5'b00000; |
load_inst_q <= 8'h00; |
load_offset_q <= 2'b00; |
|
d_mem_load <= 1'b0; |
d_mem_load_q <= 1'b0; |
end |
else |
begin |
1340,12 → 1345,12
if (dmem_ack_i) |
dmem_cyc_o <= 1'b0; |
|
r_mem_access <= 1'b0; |
d_mem_load <= r_mem_access & r_mem_load; |
mem_access_q <= 1'b0; |
d_mem_load_q <= mem_access_q & mem_load_q; |
|
// Pending accesses |
r_mem_load <= load_pending; |
r_mem_store <= store_pending; |
mem_load_q <= load_pending_w; |
mem_store_q <= store_pending_w; |
|
//--------------------------------------------------------------- |
// Valid instruction |
1357,9 → 1362,9
begin |
// Load outstanding, check if result target is being |
// overwritten (to avoid WAR hazard) |
if (r_load_rd == 5'd9) |
if (load_rd_q == 5'd9) |
// Ditch load result when it arrives |
r_load_rd <= 5'b00000; |
load_rd_q <= 5'b00000; |
end |
// Instruction with register writeback |
else if (write_rd_r) |
1366,9 → 1371,9
begin |
// Load outstanding, check if result target is being |
// overwritten (to avoid WAR hazard) |
if (reg_rd_i == r_load_rd && ~load_inst_r) |
if (reg_rd_i == load_rd_q && ~load_inst_r) |
// Ditch load result when it arrives |
r_load_rd <= 5'b00000; |
load_rd_q <= 5'b00000; |
end |
|
case (1'b1) |
1384,13 → 1389,13
dmem_cyc_o <= 1'b1; |
|
// Mark load as pending |
r_mem_load <= 1'b1; |
r_mem_access <= 1'b1; |
mem_load_q <= 1'b1; |
mem_access_q <= 1'b1; |
|
// Record target register |
r_load_rd <= reg_rd_i; |
r_load_inst <= inst_r; |
r_load_offset <= mem_addr_r[1:0]; |
load_rd_q <= reg_rd_i; |
load_inst_q <= inst_r; |
load_offset_q <= mem_addr_r[1:0]; |
|
`ifdef CONF_CORE_DEBUG |
$display(" Load from 0x%08x to R%d", mem_addr_r, reg_rd_i); |
1400,7 → 1405,7
inst_sb_w: // l.sb |
begin |
dmem_addr_o <= mem_addr_r; |
r_mem_access <= 1'b1; |
mem_access_q <= 1'b1; |
case (mem_addr_r[1:0]) |
2'b00 : |
begin |
1409,7 → 1414,7
dmem_we_o <= 1'b1; |
dmem_stb_o <= 1'b1; |
dmem_cyc_o <= 1'b1; |
r_mem_store <= 1'b1; |
mem_store_q <= 1'b1; |
end |
2'b01 : |
begin |
1418,7 → 1423,7
dmem_we_o <= 1'b1; |
dmem_stb_o <= 1'b1; |
dmem_cyc_o <= 1'b1; |
r_mem_store <= 1'b1; |
mem_store_q <= 1'b1; |
end |
2'b10 : |
begin |
1427,7 → 1432,7
dmem_we_o <= 1'b1; |
dmem_stb_o <= 1'b1; |
dmem_cyc_o <= 1'b1; |
r_mem_store <= 1'b1; |
mem_store_q <= 1'b1; |
end |
2'b11 : |
begin |
1436,7 → 1441,7
dmem_we_o <= 1'b1; |
dmem_stb_o <= 1'b1; |
dmem_cyc_o <= 1'b1; |
r_mem_store <= 1'b1; |
mem_store_q <= 1'b1; |
end |
default : |
; |
1446,7 → 1451,7
inst_sh_w: // l.sh |
begin |
dmem_addr_o <= mem_addr_r; |
r_mem_access <= 1'b1; |
mem_access_q <= 1'b1; |
case (mem_addr_r[1:0]) |
2'b00 : |
begin |
1455,7 → 1460,7
dmem_we_o <= 1'b1; |
dmem_stb_o <= 1'b1; |
dmem_cyc_o <= 1'b1; |
r_mem_store <= 1'b1; |
mem_store_q <= 1'b1; |
end |
2'b10 : |
begin |
1464,7 → 1469,7
dmem_we_o <= 1'b1; |
dmem_stb_o <= 1'b1; |
dmem_cyc_o <= 1'b1; |
r_mem_store <= 1'b1; |
mem_store_q <= 1'b1; |
end |
default : |
; |
1479,8 → 1484,8
dmem_we_o <= 1'b1; |
dmem_stb_o <= 1'b1; |
dmem_cyc_o <= 1'b1; |
r_mem_access <= 1'b1; |
r_mem_store <= 1'b1; |
mem_access_q <= 1'b1; |
mem_store_q <= 1'b1; |
|
`ifdef CONF_CORE_DEBUG |
$display(" Store R%d to 0x%08x = 0x%08x", reg_rb_i, {mem_addr_r[31:2],2'b00}, reg_rb_r); |
1547,13 → 1552,13
if (rst_i == 1'b1) |
begin |
`ifdef SIM_EXT_PUTC |
r_putc <= 8'b0; |
putc_q <= 8'b0; |
`endif |
end |
else |
begin |
`ifdef SIM_EXT_PUTC |
r_putc <= 8'b0; |
putc_q <= 8'b0; |
`endif |
//--------------------------------------------------------------- |
// Valid instruction |
1569,7 → 1574,7
16'h0004: |
begin |
`ifdef SIM_EXT_PUTC |
r_putc <= reg_ra_r[7:0]; |
putc_q <= reg_ra_r[7:0]; |
`else |
$write("%c", reg_ra_r[7:0]); |
`endif |
1590,14 → 1595,15
// Assignments |
//------------------------------------------------------------------- |
|
assign branch_pc_o = r_pc_branch; |
assign branch_o = r_pc_fetch; |
assign branch_pc_o = pc_branch_q; |
assign branch_o = pc_fetch_q; |
assign stall_o = stall_inst_r; |
|
assign opcode_o = r_e_opcode; |
assign opcode_o = ex_opcode_q; |
assign opcode_pc_o = ex_opcode_pc_q; |
|
assign reg_rd_o = r_e_rd; |
assign reg_rd_value_o = r_e_result; |
assign reg_rd_o = ex_rd_q; |
assign reg_rd_value_o = ex_result_w; |
|
assign mult_o = 1'b0; |
assign mult_res_o = 32'b0; |
1608,16 → 1614,16
`ifdef verilator |
function [31:0] get_opcode_ex; |
// verilator public |
get_opcode_ex = r_e_opcode; |
get_opcode_ex = ex_opcode_q; |
endfunction |
function [31:0] get_pc_ex; |
// verilator public |
get_pc_ex = r_e_opcode_pc; |
get_pc_ex = ex_opcode_pc_q; |
endfunction |
function [7:0] get_putc; |
// verilator public |
`ifdef SIM_EXT_PUTC |
get_putc = r_putc; |
get_putc = putc_q; |
`else |
get_putc = 8'b0; |
`endif |
1624,7 → 1630,7
endfunction |
function [0:0] get_reg_valid; |
// verilator public |
get_reg_valid = ~(resolve_failed | load_stall | ~opcode_valid_i); |
get_reg_valid = ~(resolve_failed_w | load_stall_w | ~opcode_valid_i); |
endfunction |
function [4:0] get_reg_ra; |
// verilator public |
1632,7 → 1638,7
endfunction |
function [31:0] get_reg_ra_value; |
// verilator public |
get_reg_ra_value = ra_value_resolved; |
get_reg_ra_value = ra_resolved_w; |
endfunction |
function [4:0] get_reg_rb; |
// verilator public |
1640,7 → 1646,7
endfunction |
function [31:0] get_reg_rb_value; |
// verilator public |
get_reg_rb_value = rb_value_resolved; |
get_reg_rb_value = rb_resolved_w; |
endfunction |
`endif |
|
/trunk/rtl/cpu/altor32_regfile_sim.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
48,11 → 48,11
input clk_i /*verilator public*/, |
input rst_i /*verilator public*/, |
input wr_i /*verilator public*/, |
input [4:0] rs_i /*verilator public*/, |
input [4:0] rt_i /*verilator public*/, |
input [4:0] ra_i /*verilator public*/, |
input [4:0] rb_i /*verilator public*/, |
input [4:0] rd_i /*verilator public*/, |
output reg [31:0] reg_rs_o /*verilator public*/, |
output reg [31:0] reg_rt_o /*verilator public*/, |
output reg [31:0] reg_ra_o /*verilator public*/, |
output reg [31:0] reg_rb_o /*verilator public*/, |
input [31:0] reg_rd_i /*verilator public*/ |
); |
|
107,37 → 107,37
begin |
if (rst_i) |
begin |
reg_r1_sp <= 32'h00000000; |
reg_r2_fp <= 32'h00000000; |
reg_r3 <= 32'h00000000; |
reg_r4 <= 32'h00000000; |
reg_r5 <= 32'h00000000; |
reg_r6 <= 32'h00000000; |
reg_r7 <= 32'h00000000; |
reg_r8 <= 32'h00000000; |
reg_r9_lr <= 32'h00000000; |
reg_r10 <= 32'h00000000; |
reg_r11 <= 32'h00000000; |
reg_r12 <= 32'h00000000; |
reg_r13 <= 32'h00000000; |
reg_r14 <= 32'h00000000; |
reg_r15 <= 32'h00000000; |
reg_r16 <= 32'h00000000; |
reg_r17 <= 32'h00000000; |
reg_r18 <= 32'h00000000; |
reg_r19 <= 32'h00000000; |
reg_r20 <= 32'h00000000; |
reg_r21 <= 32'h00000000; |
reg_r22 <= 32'h00000000; |
reg_r23 <= 32'h00000000; |
reg_r24 <= 32'h00000000; |
reg_r25 <= 32'h00000000; |
reg_r26 <= 32'h00000000; |
reg_r27 <= 32'h00000000; |
reg_r28 <= 32'h00000000; |
reg_r29 <= 32'h00000000; |
reg_r30 <= 32'h00000000; |
reg_r31 <= 32'h00000000; |
reg_r1_sp <= 32'h00000000; |
reg_r2_fp <= 32'h00000000; |
reg_r3 <= 32'h00000000; |
reg_r4 <= 32'h00000000; |
reg_r5 <= 32'h00000000; |
reg_r6 <= 32'h00000000; |
reg_r7 <= 32'h00000000; |
reg_r8 <= 32'h00000000; |
reg_r9_lr <= 32'h00000000; |
reg_r10 <= 32'h00000000; |
reg_r11 <= 32'h00000000; |
reg_r12 <= 32'h00000000; |
reg_r13 <= 32'h00000000; |
reg_r14 <= 32'h00000000; |
reg_r15 <= 32'h00000000; |
reg_r16 <= 32'h00000000; |
reg_r17 <= 32'h00000000; |
reg_r18 <= 32'h00000000; |
reg_r19 <= 32'h00000000; |
reg_r20 <= 32'h00000000; |
reg_r21 <= 32'h00000000; |
reg_r22 <= 32'h00000000; |
reg_r23 <= 32'h00000000; |
reg_r24 <= 32'h00000000; |
reg_r25 <= 32'h00000000; |
reg_r26 <= 32'h00000000; |
reg_r27 <= 32'h00000000; |
reg_r28 <= 32'h00000000; |
reg_r29 <= 32'h00000000; |
reg_r30 <= 32'h00000000; |
reg_r31 <= 32'h00000000; |
end |
else |
begin |
217,142 → 217,142
// Asynchronous Register read (Rs & Rd) |
always @ * |
begin |
case (rs_i) |
case (ra_i) |
5'b00000 : |
reg_rs_o = 32'h00000000; |
reg_ra_o = 32'h00000000; |
5'b00001 : |
reg_rs_o = reg_r1_sp; |
reg_ra_o = reg_r1_sp; |
5'b00010 : |
reg_rs_o = reg_r2_fp; |
reg_ra_o = reg_r2_fp; |
5'b00011 : |
reg_rs_o = reg_r3; |
reg_ra_o = reg_r3; |
5'b00100 : |
reg_rs_o = reg_r4; |
reg_ra_o = reg_r4; |
5'b00101 : |
reg_rs_o = reg_r5; |
reg_ra_o = reg_r5; |
5'b00110 : |
reg_rs_o = reg_r6; |
reg_ra_o = reg_r6; |
5'b00111 : |
reg_rs_o = reg_r7; |
reg_ra_o = reg_r7; |
5'b01000 : |
reg_rs_o = reg_r8; |
reg_ra_o = reg_r8; |
5'b01001 : |
reg_rs_o = reg_r9_lr; |
reg_ra_o = reg_r9_lr; |
5'b01010 : |
reg_rs_o = reg_r10; |
reg_ra_o = reg_r10; |
5'b01011 : |
reg_rs_o = reg_r11; |
reg_ra_o = reg_r11; |
5'b01100 : |
reg_rs_o = reg_r12; |
reg_ra_o = reg_r12; |
5'b01101 : |
reg_rs_o = reg_r13; |
reg_ra_o = reg_r13; |
5'b01110 : |
reg_rs_o = reg_r14; |
reg_ra_o = reg_r14; |
5'b01111 : |
reg_rs_o = reg_r15; |
reg_ra_o = reg_r15; |
5'b10000 : |
reg_rs_o = reg_r16; |
reg_ra_o = reg_r16; |
5'b10001 : |
reg_rs_o = reg_r17; |
reg_ra_o = reg_r17; |
5'b10010 : |
reg_rs_o = reg_r18; |
reg_ra_o = reg_r18; |
5'b10011 : |
reg_rs_o = reg_r19; |
reg_ra_o = reg_r19; |
5'b10100 : |
reg_rs_o = reg_r20; |
reg_ra_o = reg_r20; |
5'b10101 : |
reg_rs_o = reg_r21; |
reg_ra_o = reg_r21; |
5'b10110 : |
reg_rs_o = reg_r22; |
reg_ra_o = reg_r22; |
5'b10111 : |
reg_rs_o = reg_r23; |
reg_ra_o = reg_r23; |
5'b11000 : |
reg_rs_o = reg_r24; |
reg_ra_o = reg_r24; |
5'b11001 : |
reg_rs_o = reg_r25; |
reg_ra_o = reg_r25; |
5'b11010 : |
reg_rs_o = reg_r26; |
reg_ra_o = reg_r26; |
5'b11011 : |
reg_rs_o = reg_r27; |
reg_ra_o = reg_r27; |
5'b11100 : |
reg_rs_o = reg_r28; |
reg_ra_o = reg_r28; |
5'b11101 : |
reg_rs_o = reg_r29; |
reg_ra_o = reg_r29; |
5'b11110 : |
reg_rs_o = reg_r30; |
reg_ra_o = reg_r30; |
5'b11111 : |
reg_rs_o = reg_r31; |
reg_ra_o = reg_r31; |
default : |
reg_rs_o = 32'h00000000; |
reg_ra_o = 32'h00000000; |
endcase |
|
case (rt_i) |
case (rb_i) |
5'b00000 : |
reg_rt_o = 32'h00000000; |
reg_rb_o = 32'h00000000; |
5'b00001 : |
reg_rt_o = reg_r1_sp; |
reg_rb_o = reg_r1_sp; |
5'b00010 : |
reg_rt_o = reg_r2_fp; |
reg_rb_o = reg_r2_fp; |
5'b00011 : |
reg_rt_o = reg_r3; |
reg_rb_o = reg_r3; |
5'b00100 : |
reg_rt_o = reg_r4; |
reg_rb_o = reg_r4; |
5'b00101 : |
reg_rt_o = reg_r5; |
reg_rb_o = reg_r5; |
5'b00110 : |
reg_rt_o = reg_r6; |
reg_rb_o = reg_r6; |
5'b00111 : |
reg_rt_o = reg_r7; |
reg_rb_o = reg_r7; |
5'b01000 : |
reg_rt_o = reg_r8; |
reg_rb_o = reg_r8; |
5'b01001 : |
reg_rt_o = reg_r9_lr; |
reg_rb_o = reg_r9_lr; |
5'b01010 : |
reg_rt_o = reg_r10; |
reg_rb_o = reg_r10; |
5'b01011 : |
reg_rt_o = reg_r11; |
reg_rb_o = reg_r11; |
5'b01100 : |
reg_rt_o = reg_r12; |
reg_rb_o = reg_r12; |
5'b01101 : |
reg_rt_o = reg_r13; |
reg_rb_o = reg_r13; |
5'b01110 : |
reg_rt_o = reg_r14; |
reg_rb_o = reg_r14; |
5'b01111 : |
reg_rt_o = reg_r15; |
reg_rb_o = reg_r15; |
5'b10000 : |
reg_rt_o = reg_r16; |
reg_rb_o = reg_r16; |
5'b10001 : |
reg_rt_o = reg_r17; |
reg_rb_o = reg_r17; |
5'b10010 : |
reg_rt_o = reg_r18; |
reg_rb_o = reg_r18; |
5'b10011 : |
reg_rt_o = reg_r19; |
reg_rb_o = reg_r19; |
5'b10100 : |
reg_rt_o = reg_r20; |
reg_rb_o = reg_r20; |
5'b10101 : |
reg_rt_o = reg_r21; |
reg_rb_o = reg_r21; |
5'b10110 : |
reg_rt_o = reg_r22; |
reg_rb_o = reg_r22; |
5'b10111 : |
reg_rt_o = reg_r23; |
reg_rb_o = reg_r23; |
5'b11000 : |
reg_rt_o = reg_r24; |
reg_rb_o = reg_r24; |
5'b11001 : |
reg_rt_o = reg_r25; |
reg_rb_o = reg_r25; |
5'b11010 : |
reg_rt_o = reg_r26; |
reg_rb_o = reg_r26; |
5'b11011 : |
reg_rt_o = reg_r27; |
reg_rb_o = reg_r27; |
5'b11100 : |
reg_rt_o = reg_r28; |
reg_rb_o = reg_r28; |
5'b11101 : |
reg_rt_o = reg_r29; |
reg_rb_o = reg_r29; |
5'b11110 : |
reg_rt_o = reg_r30; |
reg_rb_o = reg_r30; |
5'b11111 : |
reg_rt_o = reg_r31; |
reg_rb_o = reg_r31; |
default : |
reg_rt_o = 32'h00000000; |
reg_rb_o = 32'h00000000; |
endcase |
end |
end |
361,78 → 361,78
// Asynchronous Register read (Rs & Rd) |
always @ * |
begin |
case (rs_i) |
case (ra_i) |
5'b00000 : |
reg_rs_o = 32'h00000000; |
reg_ra_o = 32'h00000000; |
5'b00001 : |
reg_rs_o = reg_r1_sp; |
reg_ra_o = reg_r1_sp; |
5'b00010 : |
reg_rs_o = reg_r2_fp; |
reg_ra_o = reg_r2_fp; |
5'b00011 : |
reg_rs_o = reg_r3; |
reg_ra_o = reg_r3; |
5'b00100 : |
reg_rs_o = reg_r4; |
reg_ra_o = reg_r4; |
5'b00101 : |
reg_rs_o = reg_r5; |
reg_ra_o = reg_r5; |
5'b00110 : |
reg_rs_o = reg_r6; |
reg_ra_o = reg_r6; |
5'b00111 : |
reg_rs_o = reg_r7; |
reg_ra_o = reg_r7; |
5'b01000 : |
reg_rs_o = reg_r8; |
reg_ra_o = reg_r8; |
5'b01001 : |
reg_rs_o = reg_r9_lr; |
reg_ra_o = reg_r9_lr; |
5'b01010 : |
reg_rs_o = reg_r10; |
reg_ra_o = reg_r10; |
5'b01011 : |
reg_rs_o = reg_r11; |
reg_ra_o = reg_r11; |
5'b01100 : |
reg_rs_o = reg_r12; |
reg_ra_o = reg_r12; |
5'b01101 : |
reg_rs_o = reg_r13; |
reg_ra_o = reg_r13; |
5'b01110 : |
reg_rs_o = reg_r14; |
reg_ra_o = reg_r14; |
5'b01111 : |
reg_rs_o = reg_r15; |
reg_ra_o = reg_r15; |
default : |
reg_rs_o = 32'h00000000; |
reg_ra_o = 32'h00000000; |
endcase |
|
case (rt_i) |
case (rb_i) |
5'b00000 : |
reg_rt_o = 32'h00000000; |
reg_rb_o = 32'h00000000; |
5'b00001 : |
reg_rt_o = reg_r1_sp; |
reg_rb_o = reg_r1_sp; |
5'b00010 : |
reg_rt_o = reg_r2_fp; |
reg_rb_o = reg_r2_fp; |
5'b00011 : |
reg_rt_o = reg_r3; |
reg_rb_o = reg_r3; |
5'b00100 : |
reg_rt_o = reg_r4; |
reg_rb_o = reg_r4; |
5'b00101 : |
reg_rt_o = reg_r5; |
reg_rb_o = reg_r5; |
5'b00110 : |
reg_rt_o = reg_r6; |
reg_rb_o = reg_r6; |
5'b00111 : |
reg_rt_o = reg_r7; |
reg_rb_o = reg_r7; |
5'b01000 : |
reg_rt_o = reg_r8; |
reg_rb_o = reg_r8; |
5'b01001 : |
reg_rt_o = reg_r9_lr; |
reg_rb_o = reg_r9_lr; |
5'b01010 : |
reg_rt_o = reg_r10; |
reg_rb_o = reg_r10; |
5'b01011 : |
reg_rt_o = reg_r11; |
reg_rb_o = reg_r11; |
5'b01100 : |
reg_rt_o = reg_r12; |
reg_rb_o = reg_r12; |
5'b01101 : |
reg_rt_o = reg_r13; |
reg_rb_o = reg_r13; |
5'b01110 : |
reg_rt_o = reg_r14; |
reg_rb_o = reg_r14; |
5'b01111 : |
reg_rt_o = reg_r15; |
reg_rb_o = reg_r15; |
default : |
reg_rt_o = 32'h00000000; |
reg_rb_o = 32'h00000000; |
endcase |
end |
end |
/trunk/rtl/cpu/altor32_lfu.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
/trunk/rtl/cpu/altor32_fetch.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
74,74 → 74,76
//----------------------------------------------------------------- |
// Params |
//----------------------------------------------------------------- |
parameter BOOT_VECTOR = 32'h00000000; |
parameter CACHE_LINE_SIZE_WIDTH = 5; /* 5-bits -> 32 entries */ |
parameter PIPELINED_FETCH = "DISABLED"; |
parameter BOOT_VECTOR = 32'h00000000; |
parameter CACHE_LINE_SIZE_WIDTH = 5; /* 5-bits -> 32 entries */ |
parameter PIPELINED_FETCH = "DISABLED"; |
|
//----------------------------------------------------------------- |
// Registers |
//----------------------------------------------------------------- |
reg r_rd; |
reg [31:0] r_pc; |
reg [31:0] d_pc; |
reg rd_q; |
reg [31:0] pc_q; |
reg [31:0] pc_last_q; |
|
//------------------------------------------------------------------- |
// Next PC state machine |
//------------------------------------------------------------------- |
wire [31:0] next_pc = r_pc + 32'd4; |
wire [31:0] next_pc_w = pc_q + 32'd4; |
|
always @ (posedge clk_i or posedge rst_i) |
begin |
if (rst_i) |
begin |
r_pc <= BOOT_VECTOR + `VECTOR_RESET; |
d_pc <= BOOT_VECTOR + `VECTOR_RESET; |
r_rd <= 1'b1; |
pc_q <= BOOT_VECTOR + `VECTOR_RESET; |
pc_last_q <= BOOT_VECTOR + `VECTOR_RESET; |
rd_q <= 1'b1; |
end |
else if (~stall_i) |
begin |
r_rd <= 1'b0; |
d_pc <= pc_o; |
|
// Branch - Next PC = branch target + 4 |
if (branch_i) |
begin |
r_pc <= branch_pc_i + 4; |
rd_q <= 1'b0; |
pc_last_q <= pc_o; |
pc_q <= branch_pc_i + 4; |
end |
// Normal sequential execution (and instruction is ready) |
else if (data_valid_i) |
begin |
// New cache line? |
if (next_pc[CACHE_LINE_SIZE_WIDTH-1:0] == {CACHE_LINE_SIZE_WIDTH{1'b0}}) |
begin |
// Start fetch of next line |
r_rd <= 1'b1; |
end |
if (next_pc_w[CACHE_LINE_SIZE_WIDTH-1:0] == {CACHE_LINE_SIZE_WIDTH{1'b0}}) |
rd_q <= 1'b1; |
else |
rd_q <= 1'b0; |
|
r_pc <= next_pc; |
pc_last_q <= pc_o; |
pc_q <= next_pc_w; |
end |
else |
begin |
rd_q <= 1'b0; |
pc_last_q <= pc_o; |
end |
end |
end |
|
//------------------------------------------------------------------- |
// Assignments |
// Instruction Fetch |
//------------------------------------------------------------------- |
|
// Instruction Fetch |
always @ * |
begin |
// Stall, revert to last requested PC |
if (stall_i) |
pc_o = d_pc; |
pc_o = pc_last_q; |
else if (branch_i) |
pc_o = branch_pc_i; |
pc_o = branch_pc_i; |
else if (~data_valid_i) |
pc_o = d_pc; |
pc_o = pc_last_q; |
else |
pc_o = r_pc; |
pc_o = pc_q; |
end |
|
assign fetch_o = branch_i ? 1'b1 : r_rd; |
assign fetch_o = branch_i ? 1'b1 : rd_q; |
|
//------------------------------------------------------------------- |
// Opcode output (retiming) |
149,37 → 151,37
generate |
if (PIPELINED_FETCH == "ENABLED") |
begin: FETCH_FLOPS |
reg [31:0] r_opcode; |
reg [31:0] r_opcode_pc; |
reg r_opcode_valid; |
reg r_branch; |
reg [31:0] opcode_q; |
reg [31:0] opcode_pc_q; |
reg opcode_valid_q; |
reg branch_q; |
|
always @ (posedge clk_i or posedge rst_i) |
begin |
if (rst_i) |
begin |
r_opcode <= 32'b0; |
r_opcode_pc <= 32'b0; |
r_opcode_valid <= 1'b0; |
r_branch <= 1'b0; |
opcode_q <= 32'b0; |
opcode_pc_q <= 32'b0; |
opcode_valid_q <= 1'b0; |
branch_q <= 1'b0; |
end |
else |
begin |
r_branch <= branch_i; |
branch_q <= branch_i; |
|
if (~stall_i) |
begin |
r_opcode_pc <= d_pc; |
r_opcode <= data_i; |
r_opcode_valid <= (data_valid_i & !branch_i); |
opcode_pc_q <= pc_last_q; |
opcode_q <= data_i; |
opcode_valid_q <= (data_valid_i & !branch_i); |
end |
end |
end |
|
// Opcode output |
assign opcode_valid_o = r_opcode_valid & ~branch_i & ~r_branch; |
assign opcode_o = r_opcode; |
assign opcode_pc_o = r_opcode_pc; |
assign opcode_valid_o = opcode_valid_q & ~branch_i & ~branch_q; |
assign opcode_o = opcode_q; |
assign opcode_pc_o = opcode_pc_q; |
end |
//------------------------------------------------------------------- |
// Opcode output |
186,10 → 188,9
//------------------------------------------------------------------- |
else |
begin : NO_FETCH_FLOPS |
// Opcode output |
assign opcode_valid_o = (data_valid_i & !branch_i); |
assign opcode_o = data_i; |
assign opcode_pc_o = d_pc; |
assign opcode_pc_o = pc_last_q; |
end |
endgenerate |
|
198,9 → 199,9
//------------------------------------------------------------------- |
// If simulation, RA = 03 if NOP instruction |
`ifdef SIMULATION |
wire [7:0] v_fetch_inst = {2'b00, opcode_o[31:26]}; |
wire v_is_nop = (v_fetch_inst == `INST_OR32_NOP); |
assign ra_o = v_is_nop ? 5'd3 : opcode_o[20:16]; |
wire [7:0] fetch_inst_w = {2'b00, opcode_o[31:26]}; |
wire nop_inst_w = (fetch_inst_w == `INST_OR32_NOP); |
assign ra_o = nop_inst_w ? 5'd3 : opcode_o[20:16]; |
`else |
assign ra_o = opcode_o[20:16]; |
`endif |
/trunk/rtl/cpu/altor32_regfile_xil.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
45,15 → 45,15
//----------------------------------------------------------------- |
module altor32_regfile_xil |
( |
input clk_i /*verilator public*/, |
input rst_i /*verilator public*/, |
input wr_i /*verilator public*/, |
input [4:0] rs_i /*verilator public*/, |
input [4:0] rt_i /*verilator public*/, |
input [4:0] rd_i /*verilator public*/, |
output reg [31:0] reg_rs_o /*verilator public*/, |
output reg [31:0] reg_rt_o /*verilator public*/, |
input [31:0] reg_rd_i /*verilator public*/ |
input clk_i /*verilator public*/, |
input rst_i /*verilator public*/, |
input wr_i /*verilator public*/, |
input [4:0] ra_i /*verilator public*/, |
input [4:0] rb_i /*verilator public*/, |
input [4:0] rd_i /*verilator public*/, |
output reg [31:0] reg_ra_o /*verilator public*/, |
output reg [31:0] reg_rb_o /*verilator public*/, |
input [31:0] reg_rd_i /*verilator public*/ |
); |
|
//----------------------------------------------------------------- |
62,45 → 62,19
parameter SUPPORT_32REGS = "ENABLED"; |
|
//----------------------------------------------------------------- |
// Registers |
// Registers / Wires |
//----------------------------------------------------------------- |
reg [4:0] addr_write; |
wire [31:0] data_out1; |
wire [31:0] data_out2; |
reg write_enable; |
wire [31:0] data_out1a; |
wire [31:0] data_out1b; |
wire [31:0] data_out2a; |
wire [31:0] data_out2b; |
wire wea; |
wire web; |
wire [31:0] reg_ra_w; |
wire [31:0] reg_rb_w; |
wire [31:0] ra_0_15_w; |
wire [31:0] ra_16_31_w; |
wire [31:0] rb_0_15_w; |
wire [31:0] rb_16_31_w; |
wire write_enable_w; |
wire write_banka_w; |
wire write_bankb_w; |
|
//----------------------------------------------------------------- |
// Async Read Process |
//----------------------------------------------------------------- |
always @ (clk_i or rs_i or rt_i or rd_i or reg_rd_i or data_out1 or data_out2 or rst_i or wr_i) |
begin |
// Read Rs |
if (rs_i == 5'b00000) |
reg_rs_o <= 32'h00000000; |
else |
reg_rs_o <= data_out1; |
|
// Read Rt |
if (rt_i == 5'b00000) |
reg_rt_o <= 32'h00000000; |
else |
reg_rt_o <= data_out2; |
|
// Write enabled? |
addr_write <= rd_i[4:0]; |
if ((rd_i != 5'b00000) & (wr_i == 1'b1)) |
write_enable <= 1'b1; |
else |
write_enable <= 1'b0; |
end |
|
//----------------------------------------------------------------- |
// Register File (using RAM16X1D ) |
//----------------------------------------------------------------- |
|
110,8 → 84,8
genvar i; |
for (i=0;i<32;i=i+1) |
begin : reg_loop1 |
RAM16X1D reg_bit1a(.WCLK(clk_i), .WE(wea), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rs_i[0]), .DPRA1(rs_i[1]), .DPRA2(rs_i[2]), .DPRA3(rs_i[3]), .DPO(data_out1a[i]), .SPO(/* open */)); |
RAM16X1D reg_bit1b(.WCLK(clk_i), .WE(web), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rs_i[0]), .DPRA1(rs_i[1]), .DPRA2(rs_i[2]), .DPRA3(rs_i[3]), .DPO(data_out1b[i]), .SPO(/* open */)); |
RAM16X1D reg_bit1a(.WCLK(clk_i), .WE(write_banka_w), .A0(rd_i[0]), .A1(rd_i[1]), .A2(rd_i[2]), .A3(rd_i[3]), .D(reg_rd_i[i]), .DPRA0(ra_i[0]), .DPRA1(ra_i[1]), .DPRA2(ra_i[2]), .DPRA3(ra_i[3]), .DPO(ra_0_15_w[i]), .SPO(/* open */)); |
RAM16X1D reg_bit2a(.WCLK(clk_i), .WE(write_banka_w), .A0(rd_i[0]), .A1(rd_i[1]), .A2(rd_i[2]), .A3(rd_i[3]), .D(reg_rd_i[i]), .DPRA0(rb_i[0]), .DPRA1(rb_i[1]), .DPRA2(rb_i[2]), .DPRA3(rb_i[3]), .DPO(rb_0_15_w[i]), .SPO(/* open */)); |
end |
end |
endgenerate |
123,14 → 97,14
genvar i; |
for (i=0;i<32;i=i+1) |
begin : reg_loop2 |
RAM16X1D reg_bit2a(.WCLK(clk_i), .WE(wea), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rt_i[0]), .DPRA1(rt_i[1]), .DPRA2(rt_i[2]), .DPRA3(rt_i[3]), .DPO(data_out2a[i]), .SPO(/* open */)); |
RAM16X1D reg_bit2b(.WCLK(clk_i), .WE(web), .A0(addr_write[0]), .A1(addr_write[1]), .A2(addr_write[2]), .A3(addr_write[3]), .D(reg_rd_i[i]), .DPRA0(rt_i[0]), .DPRA1(rt_i[1]), .DPRA2(rt_i[2]), .DPRA3(rt_i[3]), .DPO(data_out2b[i]), .SPO(/* open */)); |
RAM16X1D reg_bit1b(.WCLK(clk_i), .WE(write_bankb_w), .A0(rd_i[0]), .A1(rd_i[1]), .A2(rd_i[2]), .A3(rd_i[3]), .D(reg_rd_i[i]), .DPRA0(ra_i[0]), .DPRA1(ra_i[1]), .DPRA2(ra_i[2]), .DPRA3(ra_i[3]), .DPO(ra_16_31_w[i]), .SPO(/* open */)); |
RAM16X1D reg_bit2b(.WCLK(clk_i), .WE(write_bankb_w), .A0(rd_i[0]), .A1(rd_i[1]), .A2(rd_i[2]), .A3(rd_i[3]), .D(reg_rd_i[i]), .DPRA0(rb_i[0]), .DPRA1(rb_i[1]), .DPRA2(rb_i[2]), .DPRA3(rb_i[3]), .DPO(rb_16_31_w[i]), .SPO(/* open */)); |
end |
end |
else |
begin |
assign data_out2a = 32'h00000000; |
assign data_out2b = 32'h00000000; |
assign ra_16_31_w = 32'h00000000; |
assign rb_16_31_w = 32'h00000000; |
end |
endgenerate |
|
137,9 → 111,26
//----------------------------------------------------------------- |
// Combinatorial Assignments |
//----------------------------------------------------------------- |
assign data_out1 = (rs_i[4] == 1'b0) ? data_out1a : data_out1b; |
assign data_out2 = (rt_i[4] == 1'b0) ? data_out2a : data_out2b; |
assign wea = (write_enable & ~ (addr_write[4])); |
assign web = (write_enable & addr_write[4]); |
assign reg_ra_w = (ra_i[4] == 1'b0) ? ra_0_15_w : ra_16_31_w; |
assign reg_rb_w = (rb_i[4] == 1'b0) ? rb_0_15_w : rb_16_31_w; |
|
assign write_enable_w = (rd_i != 5'b00000) & wr_i; |
|
assign write_banka_w = (write_enable_w & (~rd_i[4])); |
assign write_bankb_w = (write_enable_w & rd_i[4]); |
|
// Register read ports |
always @ * |
begin |
if (ra_i == 5'b00000) |
reg_ra_o = 32'h00000000; |
else |
reg_ra_o = reg_ra_w; |
|
if (rb_i == 5'b00000) |
reg_rb_o = 32'h00000000; |
else |
reg_rb_o = reg_rb_w; |
end |
|
endmodule |
/trunk/rtl/cpu/altor32_ram_dp.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
64,8 → 64,8
reg [(WIDTH - 1):0] ram [((2<< (SIZE-1)) - 1):0] /*verilator public*/; |
/* verilator lint_on MULTIDRIVEN */ |
|
reg [(SIZE - 1):0] rd_addr_a; |
reg [(SIZE - 1):0] rd_addr_b; |
reg [(SIZE - 1):0] rd_addr_a_q; |
reg [(SIZE - 1):0] rd_addr_b_q; |
|
//----------------------------------------------------------------- |
// Processes |
74,19 → 74,33
begin |
if (awr_i == 1'b1) |
ram[aadr_i] <= adat_i; |
rd_addr_a <= aadr_i; |
rd_addr_a_q <= aadr_i; |
end |
always @ (posedge bclk_i) |
begin |
if (bwr_i == 1'b1) |
ram[badr_i] <= bdat_i; |
rd_addr_b <= badr_i; |
rd_addr_b_q <= badr_i; |
end |
|
//------------------------------------------------------------------- |
// Combinatorial |
//------------------------------------------------------------------- |
assign adat_o = ram[rd_addr_a]; |
assign bdat_o = ram[rd_addr_b]; |
assign adat_o = ram[rd_addr_a_q]; |
assign bdat_o = ram[rd_addr_b_q]; |
|
//----------------------------------------------------------------- |
// Init Memory |
//----------------------------------------------------------------- |
`ifdef ALTOR32_CLEAR_RAM |
integer i; |
initial |
begin |
for (i=0;i<((2<< (SIZE-1)) - 1);i=i+1) |
begin |
ram[i] = 0; |
end |
end |
`endif |
|
endmodule |
/trunk/rtl/cpu/altor32_lsu.v
10,7 → 10,7
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// Copyright (C) 2011 - 2014 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
78,8 → 78,8
//------------------------------------------------------------------- |
// Outstanding memory access logic |
//------------------------------------------------------------------- |
reg v_inst_load; |
reg v_inst_store; |
reg inst_load_r; |
reg inst_store_r; |
|
always @ * |
begin |
90,8 → 90,8
write_result_o = 1'b0; |
|
// Is this instruction a load or store? |
v_inst_load = is_load_operation(opcode_i); |
v_inst_store = is_store_operation(opcode_i); |
inst_load_r = is_load_operation(opcode_i); |
inst_store_r = is_store_operation(opcode_i); |
|
// Store operation just completed? |
if (store_pending_o & mem_ack_i & ~mem_access_i) |
144,7 → 144,7
if ((load_pending_o | store_pending_o) & opcode_valid_i) |
begin |
// Load or store whilst memory bus busy |
if (v_inst_load | v_inst_store) |
if (inst_load_r | inst_store_r) |
begin |
`ifdef CONF_CORE_DEBUG |
$display(" Data bus already busy, stall (load_pending_o=%d, store_pending_o=%d)", load_pending_o, store_pending_o); |
/trunk/rtl/sim_icarus/test_image.lst
0,0 → 1,4630
|
firmware.elf: file format elf32-or1k |
|
Sections: |
Idx Name Size VMA LMA File off Algn |
0 .text 00002fd8 10000000 10000000 00002000 2**2 |
CONTENTS, ALLOC, LOAD, READONLY, CODE |
1 .data 00000008 10002fd8 10002fd8 00004fd8 2**2 |
CONTENTS, ALLOC, LOAD, DATA |
2 .bss 00001030 10002fe0 10002fe0 00004fe0 2**2 |
ALLOC |
3 .debug_info 00002151 00000000 00000000 00004fe0 2**0 |
CONTENTS, READONLY, DEBUGGING |
4 .debug_abbrev 00000b63 00000000 00000000 00007131 2**0 |
CONTENTS, READONLY, DEBUGGING |
5 .debug_loc 00000fc6 00000000 00000000 00007c94 2**0 |
CONTENTS, READONLY, DEBUGGING |
6 .debug_aranges 00000140 00000000 00000000 00008c5a 2**0 |
CONTENTS, READONLY, DEBUGGING |
7 .debug_ranges 000000b8 00000000 00000000 00008d9a 2**0 |
CONTENTS, READONLY, DEBUGGING |
8 .debug_line 00000ad7 00000000 00000000 00008e52 2**0 |
CONTENTS, READONLY, DEBUGGING |
9 .debug_str 000006d5 00000000 00000000 00009929 2**0 |
CONTENTS, READONLY, DEBUGGING |
10 .comment 00000029 00000000 00000000 00009ffe 2**0 |
CONTENTS, READONLY |
11 .debug_frame 0000039c 00000000 00000000 0000a028 2**2 |
CONTENTS, READONLY, DEBUGGING |
|
Disassembly of section .text: |
|
10000000 <_start-0x100>: |
... |
|
10000100 <_start>: |
10000100: 18 80 10 00 l.movhi r4,0x1000 |
10000104: a8 24 40 00 l.ori r1,r4,0x4000 |
10000108: 18 80 10 00 l.movhi r4,0x1000 |
1000010c: a8 84 2f e0 l.ori r4,r4,0x2fe0 |
10000110: 18 a0 10 00 l.movhi r5,0x1000 |
10000114: a8 a5 40 10 l.ori r5,r5,0x4010 |
|
10000118 <BSS_CLEAR>: |
10000118: d4 04 00 00 l.sw 0(r4),r0 |
1000011c: e4 a4 28 00 l.sfleu r4,r5 |
10000120: 9c 84 00 04 l.addi r4,r4,4 |
10000124: 13 ff ff fd l.bf 10000118 <BSS_CLEAR> |
10000128: 15 00 00 00 l.nop 0x0 |
1000012c: 04 00 03 b5 l.jal 10001000 <main> |
10000130: 15 00 00 00 l.nop 0x0 |
... |
|
10000400 <vector_extint>: |
10000400: 24 00 00 00 l.rfe |
10000404: 15 00 00 00 l.nop 0x0 |
... |
10000ffc: 15 00 00 00 l.nop 0x0 |
|
10001000 <main>: |
int main(void) |
{ |
int res; |
|
// Setup printf to serial port |
printf_register(serial_putchar); |
10001000: 18 60 10 00 l.movhi r3,0x1000 |
|
//----------------------------------------------------------------- |
// main: |
//----------------------------------------------------------------- |
int main(void) |
{ |
10001004: d7 e1 4f fc l.sw -4(r1),r9 |
10001008: d7 e1 0f f8 l.sw -8(r1),r1 |
int res; |
|
// Setup printf to serial port |
printf_register(serial_putchar); |
1000100c: a8 63 1a 54 l.ori r3,r3,0x1a54 |
|
//----------------------------------------------------------------- |
// main: |
//----------------------------------------------------------------- |
int main(void) |
{ |
10001010: 9c 21 ff f8 l.addi r1,r1,-8 |
int res; |
|
// Setup printf to serial port |
printf_register(serial_putchar); |
10001014: 04 00 01 32 l.jal 100014dc <printf_register> |
|
// Run test |
res = test(); |
10001018: 04 00 03 35 l.jal 10001cec <test> |
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
|
// No error? |
if (exit_code == 0) |
1000101c: bc 2b 00 00 l.sfnei r11,0 |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10001020: a5 6b 00 ff l.andi r11,r11,0xff |
10001024: a8 2b 00 00 l.ori r1,r11,0x0 |
|
// No error? |
if (exit_code == 0) |
10001028: 0c 00 00 06 l.bnf 10001040 <main+0x40> |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
1000102c: c8 00 00 00 lf.add.s r0,r0,r0 |
|
// Exit with result |
exit(res); |
} |
10001030: 9c 21 00 08 l.addi r1,r1,8 |
10001034: 85 21 ff fc l.lwz r9,-4(r1) |
10001038: 84 21 ff f8 l.lwz r1,-8(r1) |
1000103c: 44 00 48 00 l.jr r9 |
|
// No error? |
if (exit_code == 0) |
{ |
// Trap instruction |
__asm__ __volatile__ ( "\t l.trap 0 "); |
10001040: 21 00 00 00 l.trap 0x0 |
10001044: 03 ff ff fb l.j 10001030 <main+0x30> |
|
10001048 <exception_register_fault_handler>: |
static volatile int in_interrupt = 0; |
|
//----------------------------------------------------------------- |
// exception_register: |
//----------------------------------------------------------------- |
void exception_register_fault_handler(void (*func)(void)) { func_fault = func; } |
10001048: 18 80 10 00 l.movhi r4,0x1000 |
1000104c: d7 e1 0f fc l.sw -4(r1),r1 |
10001050: a8 84 2f f0 l.ori r4,r4,0x2ff0 |
10001054: 9c 21 ff fc l.addi r1,r1,-4 |
10001058: d4 04 18 00 l.sw 0(r4),r3 |
1000105c: 9c 21 00 04 l.addi r1,r1,4 |
10001060: 84 21 ff fc l.lwz r1,-4(r1) |
10001064: 44 00 48 00 l.jr r9 |
|
10001068 <exception_register_break_handler>: |
void exception_register_break_handler(void (*func)(void)) { func_break = func; } |
10001068: 18 80 10 00 l.movhi r4,0x1000 |
1000106c: d7 e1 0f fc l.sw -4(r1),r1 |
10001070: a8 84 2f ec l.ori r4,r4,0x2fec |
10001074: 9c 21 ff fc l.addi r1,r1,-4 |
10001078: d4 04 18 00 l.sw 0(r4),r3 |
1000107c: 9c 21 00 04 l.addi r1,r1,4 |
10001080: 84 21 ff fc l.lwz r1,-4(r1) |
10001084: 44 00 48 00 l.jr r9 |
|
10001088 <exception_register_extint_handler>: |
void exception_register_extint_handler(void (*func)(void)) { func_extint = func; } |
10001088: 18 80 10 00 l.movhi r4,0x1000 |
1000108c: d7 e1 0f fc l.sw -4(r1),r1 |
10001090: a8 84 2f e8 l.ori r4,r4,0x2fe8 |
10001094: 9c 21 ff fc l.addi r1,r1,-4 |
10001098: d4 04 18 00 l.sw 0(r4),r3 |
1000109c: 9c 21 00 04 l.addi r1,r1,4 |
100010a0: 84 21 ff fc l.lwz r1,-4(r1) |
100010a4: 44 00 48 00 l.jr r9 |
|
100010a8 <exception_register_syscall_handler>: |
void exception_register_syscall_handler(void (*func)(void)) { func_syscall = func; } |
100010a8: 18 80 10 00 l.movhi r4,0x1000 |
100010ac: d7 e1 0f fc l.sw -4(r1),r1 |
100010b0: a8 84 2f e4 l.ori r4,r4,0x2fe4 |
100010b4: 9c 21 ff fc l.addi r1,r1,-4 |
100010b8: d4 04 18 00 l.sw 0(r4),r3 |
100010bc: 9c 21 00 04 l.addi r1,r1,4 |
100010c0: 84 21 ff fc l.lwz r1,-4(r1) |
100010c4: 44 00 48 00 l.jr r9 |
|
100010c8 <cpu_handle_irq>: |
|
//----------------------------------------------------------------- |
// cpu_handle_irq: |
//----------------------------------------------------------------- |
void cpu_handle_irq(unsigned cause) |
{ |
100010c8: d7 e1 17 f4 l.sw -12(r1),r2 |
int recursive_int = (in_interrupt != 0); |
100010cc: 18 40 10 00 l.movhi r2,0x1000 |
|
in_interrupt = 1; |
100010d0: 9c 80 00 01 l.addi r4,r0,1 |
//----------------------------------------------------------------- |
// cpu_handle_irq: |
//----------------------------------------------------------------- |
void cpu_handle_irq(unsigned cause) |
{ |
int recursive_int = (in_interrupt != 0); |
100010d4: a8 42 2f e0 l.ori r2,r2,0x2fe0 |
|
//----------------------------------------------------------------- |
// cpu_handle_irq: |
//----------------------------------------------------------------- |
void cpu_handle_irq(unsigned cause) |
{ |
100010d8: d7 e1 77 f8 l.sw -8(r1),r14 |
100010dc: d7 e1 4f fc l.sw -4(r1),r9 |
100010e0: d7 e1 0f f0 l.sw -16(r1),r1 |
int recursive_int = (in_interrupt != 0); |
100010e4: 85 c2 00 00 l.lwz r14,0(r2) |
|
in_interrupt = 1; |
|
switch (cause) |
100010e8: bc 43 00 08 l.sfgtui r3,8 |
//----------------------------------------------------------------- |
void cpu_handle_irq(unsigned cause) |
{ |
int recursive_int = (in_interrupt != 0); |
|
in_interrupt = 1; |
100010ec: d4 02 20 00 l.sw 0(r2),r4 |
|
//----------------------------------------------------------------- |
// cpu_handle_irq: |
//----------------------------------------------------------------- |
void cpu_handle_irq(unsigned cause) |
{ |
100010f0: 9c 21 ff e4 l.addi r1,r1,-28 |
int recursive_int = (in_interrupt != 0); |
|
in_interrupt = 1; |
|
switch (cause) |
100010f4: 10 00 00 71 l.bf 100012b8 <cpu_handle_irq+0x1f0> |
100010f8: 18 80 10 00 l.movhi r4,0x1000 |
100010fc: b8 63 00 02 l.slli r3,r3,0x2 |
10001100: a8 84 2b 00 l.ori r4,r4,0x2b00 |
10001104: e0 63 20 00 l.add r3,r3,r4 |
10001108: 84 63 00 00 l.lwz r3,0(r3) |
1000110c: 44 00 18 00 l.jr r3 |
case EXCEPTION_DIV: |
panic("DIV!"); |
break; |
|
case EXCEPTION_UDIV: |
panic("UDIV!"); |
10001110: 18 60 10 00 l.movhi r3,0x1000 |
10001114: a8 63 2c e4 l.ori r3,r3,0x2ce4 |
10001118: d4 01 18 00 l.sw 0(r1),r3 |
1000111c: 18 60 10 00 l.movhi r3,0x1000 |
10001120: a8 63 2c 9a l.ori r3,r3,0x2c9a |
10001124: d4 01 18 04 l.sw 4(r1),r3 |
10001128: 9c 60 00 6e l.addi r3,r0,110 |
break; |
|
default: |
panic("UNKNOWN"); |
1000112c: d4 01 18 08 l.sw 8(r1),r3 |
10001130: 18 60 10 00 l.movhi r3,0x1000 |
10001134: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10001138: 04 00 02 2b l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
1000113c: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10001140: c8 00 00 00 lf.add.s r0,r0,r0 |
break; |
} |
|
assert(recursive_int == 0); |
10001144: bc 0e 00 00 l.sfeqi r14,0 |
10001148: 10 00 00 0e l.bf 10001180 <cpu_handle_irq+0xb8> |
1000114c: 18 60 10 00 l.movhi r3,0x1000 |
10001150: a8 63 2c f6 l.ori r3,r3,0x2cf6 |
10001154: d4 01 18 00 l.sw 0(r1),r3 |
10001158: 18 60 10 00 l.movhi r3,0x1000 |
1000115c: a8 63 2c 9a l.ori r3,r3,0x2c9a |
10001160: d4 01 18 04 l.sw 4(r1),r3 |
10001164: 9c 60 00 76 l.addi r3,r0,118 |
10001168: d4 01 18 08 l.sw 8(r1),r3 |
1000116c: 18 60 10 00 l.movhi r3,0x1000 |
10001170: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10001174: 04 00 02 1c l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10001178: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
1000117c: c8 00 00 00 lf.add.s r0,r0,r0 |
|
in_interrupt = 0; |
10001180: 9c 60 00 00 l.addi r3,r0,0 |
10001184: d4 02 18 00 l.sw 0(r2),r3 |
} |
10001188: 9c 21 00 1c l.addi r1,r1,28 |
1000118c: 85 21 ff fc l.lwz r9,-4(r1) |
10001190: 84 21 ff f0 l.lwz r1,-16(r1) |
10001194: 84 41 ff f4 l.lwz r2,-12(r1) |
10001198: 85 c1 ff f8 l.lwz r14,-8(r1) |
1000119c: 44 00 48 00 l.jr r9 |
in_interrupt = 1; |
|
switch (cause) |
{ |
case EXCEPTION_SYSCALL: |
if (func_syscall) |
100011a0: 18 60 10 00 l.movhi r3,0x1000 |
100011a4: a8 63 2f e4 l.ori r3,r3,0x2fe4 |
100011a8: 84 63 00 00 l.lwz r3,0(r3) |
100011ac: bc 03 00 00 l.sfeqi r3,0 |
100011b0: 10 00 00 4a l.bf 100012d8 <cpu_handle_irq+0x210> |
panic("EXT_INT!"); |
break; |
|
case EXCEPTION_FAULT: |
if (func_fault) |
func_fault(); |
100011b4: 48 00 18 00 l.jalr r3 |
100011b8: 03 ff ff e3 l.j 10001144 <cpu_handle_irq+0x7c> |
else |
panic("SYSCALL!"); |
break; |
|
case EXCEPTION_BREAK: |
if (func_break) |
100011bc: 18 60 10 00 l.movhi r3,0x1000 |
100011c0: a8 63 2f ec l.ori r3,r3,0x2fec |
100011c4: 84 63 00 00 l.lwz r3,0(r3) |
100011c8: bc 03 00 00 l.sfeqi r3,0 |
100011cc: 0f ff ff fa l.bnf 100011b4 <cpu_handle_irq+0xec> |
func_break(); |
else |
panic("BREAK!"); |
100011d0: 18 60 10 00 l.movhi r3,0x1000 |
100011d4: a8 63 2c b0 l.ori r3,r3,0x2cb0 |
100011d8: d4 01 18 00 l.sw 0(r1),r3 |
100011dc: 18 60 10 00 l.movhi r3,0x1000 |
100011e0: a8 63 2c 9a l.ori r3,r3,0x2c9a |
100011e4: d4 01 18 04 l.sw 4(r1),r3 |
100011e8: 9c 60 00 50 l.addi r3,r0,80 |
100011ec: 03 ff ff d0 l.j 1000112c <cpu_handle_irq+0x64> |
break; |
|
case EXCEPTION_EXTINT: |
if (func_extint) |
100011f0: 18 60 10 00 l.movhi r3,0x1000 |
100011f4: a8 63 2f e8 l.ori r3,r3,0x2fe8 |
100011f8: 84 63 00 00 l.lwz r3,0(r3) |
100011fc: bc 03 00 00 l.sfeqi r3,0 |
10001200: 0f ff ff ed l.bnf 100011b4 <cpu_handle_irq+0xec> |
func_extint(); |
else |
panic("EXT_INT!"); |
10001204: 18 60 10 00 l.movhi r3,0x1000 |
10001208: a8 63 2c b9 l.ori r3,r3,0x2cb9 |
1000120c: d4 01 18 00 l.sw 0(r1),r3 |
10001210: 18 60 10 00 l.movhi r3,0x1000 |
10001214: a8 63 2c 9a l.ori r3,r3,0x2c9a |
10001218: d4 01 18 04 l.sw 4(r1),r3 |
1000121c: 9c 60 00 57 l.addi r3,r0,87 |
10001220: 03 ff ff c3 l.j 1000112c <cpu_handle_irq+0x64> |
break; |
|
case EXCEPTION_FAULT: |
if (func_fault) |
10001224: 18 60 10 00 l.movhi r3,0x1000 |
10001228: a8 63 2f f0 l.ori r3,r3,0x2ff0 |
1000122c: 84 63 00 00 l.lwz r3,0(r3) |
10001230: bc 03 00 00 l.sfeqi r3,0 |
10001234: 0f ff ff e0 l.bnf 100011b4 <cpu_handle_irq+0xec> |
func_fault(); |
else |
panic("FAULT"); |
10001238: 18 60 10 00 l.movhi r3,0x1000 |
1000123c: a8 63 2c c4 l.ori r3,r3,0x2cc4 |
10001240: d4 01 18 00 l.sw 0(r1),r3 |
10001244: 18 60 10 00 l.movhi r3,0x1000 |
10001248: a8 63 2c 9a l.ori r3,r3,0x2c9a |
1000124c: d4 01 18 04 l.sw 4(r1),r3 |
10001250: 9c 60 00 5e l.addi r3,r0,94 |
10001254: 03 ff ff b6 l.j 1000112c <cpu_handle_irq+0x64> |
break; |
|
case EXCEPTION_MULT: |
panic("MULT!"); |
10001258: 18 60 10 00 l.movhi r3,0x1000 |
1000125c: a8 63 2c cc l.ori r3,r3,0x2ccc |
10001260: d4 01 18 00 l.sw 0(r1),r3 |
10001264: 18 60 10 00 l.movhi r3,0x1000 |
10001268: a8 63 2c 9a l.ori r3,r3,0x2c9a |
1000126c: d4 01 18 04 l.sw 4(r1),r3 |
10001270: 9c 60 00 62 l.addi r3,r0,98 |
10001274: 03 ff ff ae l.j 1000112c <cpu_handle_irq+0x64> |
break; |
|
case EXCEPTION_UMULT: |
panic("UMULT!"); |
10001278: 18 60 10 00 l.movhi r3,0x1000 |
1000127c: a8 63 2c d4 l.ori r3,r3,0x2cd4 |
10001280: d4 01 18 00 l.sw 0(r1),r3 |
10001284: 18 60 10 00 l.movhi r3,0x1000 |
10001288: a8 63 2c 9a l.ori r3,r3,0x2c9a |
1000128c: d4 01 18 04 l.sw 4(r1),r3 |
10001290: 9c 60 00 66 l.addi r3,r0,102 |
10001294: 03 ff ff a6 l.j 1000112c <cpu_handle_irq+0x64> |
break; |
|
case EXCEPTION_DIV: |
panic("DIV!"); |
10001298: 18 60 10 00 l.movhi r3,0x1000 |
1000129c: a8 63 2c dd l.ori r3,r3,0x2cdd |
100012a0: d4 01 18 00 l.sw 0(r1),r3 |
100012a4: 18 60 10 00 l.movhi r3,0x1000 |
100012a8: a8 63 2c 9a l.ori r3,r3,0x2c9a |
100012ac: d4 01 18 04 l.sw 4(r1),r3 |
100012b0: 9c 60 00 6a l.addi r3,r0,106 |
100012b4: 03 ff ff 9e l.j 1000112c <cpu_handle_irq+0x64> |
case EXCEPTION_UDIV: |
panic("UDIV!"); |
break; |
|
default: |
panic("UNKNOWN"); |
100012b8: 18 60 10 00 l.movhi r3,0x1000 |
100012bc: a8 63 2c ec l.ori r3,r3,0x2cec |
100012c0: d4 01 18 00 l.sw 0(r1),r3 |
100012c4: 18 60 10 00 l.movhi r3,0x1000 |
100012c8: a8 63 2c 9a l.ori r3,r3,0x2c9a |
100012cc: d4 01 18 04 l.sw 4(r1),r3 |
100012d0: 9c 60 00 72 l.addi r3,r0,114 |
100012d4: 03 ff ff 96 l.j 1000112c <cpu_handle_irq+0x64> |
{ |
case EXCEPTION_SYSCALL: |
if (func_syscall) |
func_syscall(); |
else |
panic("SYSCALL!"); |
100012d8: 18 60 10 00 l.movhi r3,0x1000 |
100012dc: a8 63 2c 8f l.ori r3,r3,0x2c8f |
100012e0: d4 01 18 00 l.sw 0(r1),r3 |
100012e4: 18 60 10 00 l.movhi r3,0x1000 |
100012e8: a8 63 2c 9a l.ori r3,r3,0x2c9a |
100012ec: d4 01 18 04 l.sw 4(r1),r3 |
100012f0: 9c 60 00 49 l.addi r3,r0,73 |
100012f4: 03 ff ff 8e l.j 1000112c <cpu_handle_irq+0x64> |
|
100012f8 <outnum.isra.1>: |
static void outnum( struct vbuf *buf, const long n, const long base, params_t *par) |
{ |
char* cp; |
int negative; |
char outbuf[32]; |
const char udigits[] = "0123456789ABCDEF"; |
100012f8: 18 e0 38 39 l.movhi r7,0x3839 |
/* This routine moves a number to the output buffer */ |
/* as directed by the padding and positioning flags. */ |
/* */ |
//---------------------------------------------------- |
#if defined PRINTF_DEC_PRINT || defined PRINTF_HEX_PRINT |
static void outnum( struct vbuf *buf, const long n, const long base, params_t *par) |
100012fc: d7 e1 17 dc l.sw -36(r1),r2 |
{ |
char* cp; |
int negative; |
char outbuf[32]; |
const char udigits[] = "0123456789ABCDEF"; |
10001300: a9 07 41 42 l.ori r8,r7,0x4142 |
/* This routine moves a number to the output buffer */ |
/* as directed by the padding and positioning flags. */ |
/* */ |
//---------------------------------------------------- |
#if defined PRINTF_DEC_PRINT || defined PRINTF_HEX_PRINT |
static void outnum( struct vbuf *buf, const long n, const long base, params_t *par) |
10001304: d7 e1 a7 e8 l.sw -24(r1),r20 |
10001308: d7 e1 b7 ec l.sw -20(r1),r22 |
1000130c: d7 e1 4f fc l.sw -4(r1),r9 |
10001310: d7 e1 0f d8 l.sw -40(r1),r1 |
10001314: d7 e1 77 e0 l.sw -32(r1),r14 |
10001318: d7 e1 97 e4 l.sw -28(r1),r18 |
1000131c: d7 e1 c7 f0 l.sw -16(r1),r24 |
10001320: d7 e1 d7 f4 l.sw -12(r1),r26 |
10001324: d7 e1 e7 f8 l.sw -8(r1),r28 |
{ |
char* cp; |
int negative; |
char outbuf[32]; |
const char udigits[] = "0123456789ABCDEF"; |
10001328: 18 40 34 35 l.movhi r2,0x3435 |
/* This routine moves a number to the output buffer */ |
/* as directed by the padding and positioning flags. */ |
/* */ |
//---------------------------------------------------- |
#if defined PRINTF_DEC_PRINT || defined PRINTF_HEX_PRINT |
static void outnum( struct vbuf *buf, const long n, const long base, params_t *par) |
1000132c: 9c 21 ff 90 l.addi r1,r1,-112 |
const char *digits; |
unsigned long num; |
int count; |
|
/* Check if number is negative */ |
if (base == 10 && n < 0L) { |
10001330: ac c4 00 0a l.xori r6,r4,10 |
static void outnum( struct vbuf *buf, const long n, const long base, params_t *par) |
{ |
char* cp; |
int negative; |
char outbuf[32]; |
const char udigits[] = "0123456789ABCDEF"; |
10001334: a8 42 36 37 l.ori r2,r2,0x3637 |
10001338: d4 01 40 08 l.sw 8(r1),r8 |
1000133c: 19 00 43 44 l.movhi r8,0x4344 |
/* This routine moves a number to the output buffer */ |
/* as directed by the padding and positioning flags. */ |
/* */ |
//---------------------------------------------------- |
#if defined PRINTF_DEC_PRINT || defined PRINTF_HEX_PRINT |
static void outnum( struct vbuf *buf, const long n, const long base, params_t *par) |
10001340: aa 84 00 00 l.ori r20,r4,0x0 |
{ |
char* cp; |
int negative; |
char outbuf[32]; |
const char udigits[] = "0123456789ABCDEF"; |
10001344: a9 08 45 46 l.ori r8,r8,0x4546 |
const char *digits; |
unsigned long num; |
int count; |
|
/* Check if number is negative */ |
if (base == 10 && n < 0L) { |
10001348: e1 60 30 02 l.sub r11,r0,r6 |
static void outnum( struct vbuf *buf, const long n, const long base, params_t *par) |
{ |
char* cp; |
int negative; |
char outbuf[32]; |
const char udigits[] = "0123456789ABCDEF"; |
1000134c: 18 80 30 31 l.movhi r4,0x3031 |
10001350: d4 01 10 04 l.sw 4(r1),r2 |
const char ldigits[] = "0123456789abcdef"; |
10001354: d4 01 10 18 l.sw 24(r1),r2 |
10001358: 18 40 63 64 l.movhi r2,0x6364 |
static void outnum( struct vbuf *buf, const long n, const long base, params_t *par) |
{ |
char* cp; |
int negative; |
char outbuf[32]; |
const char udigits[] = "0123456789ABCDEF"; |
1000135c: a8 84 32 33 l.ori r4,r4,0x3233 |
const char ldigits[] = "0123456789abcdef"; |
10001360: a8 e7 61 62 l.ori r7,r7,0x6162 |
const char *digits; |
unsigned long num; |
int count; |
|
/* Check if number is negative */ |
if (base == 10 && n < 0L) { |
10001364: e0 cb 30 04 l.or r6,r11,r6 |
static void outnum( struct vbuf *buf, const long n, const long base, params_t *par) |
{ |
char* cp; |
int negative; |
char outbuf[32]; |
const char udigits[] = "0123456789ABCDEF"; |
10001368: d4 01 40 0c l.sw 12(r1),r8 |
const char ldigits[] = "0123456789abcdef"; |
1000136c: a8 42 65 66 l.ori r2,r2,0x6566 |
static void outnum( struct vbuf *buf, const long n, const long base, params_t *par) |
{ |
char* cp; |
int negative; |
char outbuf[32]; |
const char udigits[] = "0123456789ABCDEF"; |
10001370: 9d 00 00 00 l.addi r8,r0,0 |
10001374: d4 01 20 00 l.sw 0(r1),r4 |
10001378: d8 01 40 10 l.sb 16(r1),r8 |
const char ldigits[] = "0123456789abcdef"; |
1000137c: d4 01 20 14 l.sw 20(r1),r4 |
10001380: d4 01 38 1c l.sw 28(r1),r7 |
10001384: d4 01 10 20 l.sw 32(r1),r2 |
10001388: d8 01 40 24 l.sb 36(r1),r8 |
const char *digits; |
unsigned long num; |
int count; |
|
/* Check if number is negative */ |
if (base == 10 && n < 0L) { |
1000138c: bd 86 00 00 l.sfltsi r6,0 |
/* This routine moves a number to the output buffer */ |
/* as directed by the padding and positioning flags. */ |
/* */ |
//---------------------------------------------------- |
#if defined PRINTF_DEC_PRINT || defined PRINTF_HEX_PRINT |
static void outnum( struct vbuf *buf, const long n, const long base, params_t *par) |
10001390: aa c5 00 00 l.ori r22,r5,0x0 |
const char *digits; |
unsigned long num; |
int count; |
|
/* Check if number is negative */ |
if (base == 10 && n < 0L) { |
10001394: 10 00 00 03 l.bf 100013a0 <outnum.isra.1+0xa8> |
10001398: bd 63 00 00 l.sfgesi r3,0 |
1000139c: 0c 00 00 4d l.bnf 100014d0 <outnum.isra.1+0x1d8> |
negative = 1; |
num = -(n); |
} |
else{ |
num = (n); |
100013a0: a8 43 00 00 l.ori r2,r3,0x0 |
negative = 0; |
100013a4: 9f 80 00 00 l.addi r28,r0,0 |
} |
|
if (par->uppercase) |
100013a8: 84 76 00 18 l.lwz r3,24(r22) |
digits = udigits; |
100013ac: ab 41 00 00 l.ori r26,r1,0x0 |
else{ |
num = (n); |
negative = 0; |
} |
|
if (par->uppercase) |
100013b0: bc 03 00 00 l.sfeqi r3,0 |
100013b4: 0c 00 00 02 l.bnf 100013bc <outnum.isra.1+0xc4> |
digits = udigits; |
else |
digits = ldigits; |
100013b8: 9f 41 00 14 l.addi r26,r1,20 |
100013bc: 9f 01 00 28 l.addi r24,r1,40 |
100013c0: a9 d8 00 00 l.ori r14,r24,0x0 |
100013c4: 00 00 00 02 l.j 100013cc <outnum.isra.1+0xd4> |
100013c8: a9 d2 00 00 l.ori r14,r18,0x0 |
|
/* Build number (backwards) in outbuf */ |
cp = outbuf; |
do { |
*cp++ = digits[(int)(num % base)]; |
100013cc: a8 62 00 00 l.ori r3,r2,0x0 |
100013d0: a8 94 00 00 l.ori r4,r20,0x0 |
/* This routine moves a number to the output buffer */ |
/* as directed by the padding and positioning flags. */ |
/* */ |
//---------------------------------------------------- |
#if defined PRINTF_DEC_PRINT || defined PRINTF_HEX_PRINT |
static void outnum( struct vbuf *buf, const long n, const long base, params_t *par) |
100013d4: 9e 4e 00 01 l.addi r18,r14,1 |
digits = ldigits; |
|
/* Build number (backwards) in outbuf */ |
cp = outbuf; |
do { |
*cp++ = digits[(int)(num % base)]; |
100013d8: 04 00 05 52 l.jal 10002920 <__umodsi3> |
100013dc: e1 7a 58 00 l.add r11,r26,r11 |
} while ((num /= base) > 0); |
100013e0: a8 62 00 00 l.ori r3,r2,0x0 |
digits = ldigits; |
|
/* Build number (backwards) in outbuf */ |
cp = outbuf; |
do { |
*cp++ = digits[(int)(num % base)]; |
100013e4: 8d 6b 00 00 l.lbz r11,0(r11) |
} while ((num /= base) > 0); |
100013e8: a8 94 00 00 l.ori r4,r20,0x0 |
digits = ldigits; |
|
/* Build number (backwards) in outbuf */ |
cp = outbuf; |
do { |
*cp++ = digits[(int)(num % base)]; |
100013ec: d8 0e 58 00 l.sb 0(r14),r11 |
} while ((num /= base) > 0); |
100013f0: 04 00 05 43 l.jal 100028fc <__udivsi3> |
100013f4: bc 0b 00 00 l.sfeqi r11,0 |
100013f8: a8 4b 00 00 l.ori r2,r11,0x0 |
100013fc: 0f ff ff f3 l.bnf 100013c8 <outnum.isra.1+0xd0> |
if (negative) |
10001400: bc 1c 00 00 l.sfeqi r28,0 |
10001404: 10 00 00 04 l.bf 10001414 <outnum.isra.1+0x11c> |
*cp++ = '-'; |
10001408: 9c 40 00 2d l.addi r2,r0,45 |
1000140c: 9e 4e 00 02 l.addi r18,r14,2 |
10001410: d8 0e 10 01 l.sb 1(r14),r2 |
*cp-- = 0; |
10001414: 9d 00 00 00 l.addi r8,r0,0 |
10001418: 9d d2 ff ff l.addi r14,r18,-1 |
1000141c: d8 12 40 00 l.sb 0(r18),r8 |
const char * s; |
|
if(!str) |
return 0; |
|
for(s = str; *s; ++ s) |
10001420: 90 81 00 28 l.lbs r4,40(r1) |
10001424: bc 04 00 00 l.sfeqi r4,0 |
10001428: 10 00 00 08 l.bf 10001448 <outnum.isra.1+0x150> |
1000142c: 9c 41 00 29 l.addi r2,r1,41 |
10001430: a8 82 00 00 l.ori r4,r2,0x0 |
10001434: 9c 42 00 01 l.addi r2,r2,1 |
10001438: 90 62 ff ff l.lbs r3,-1(r2) |
1000143c: bc 03 00 00 l.sfeqi r3,0 |
10001440: 0f ff ff fc l.bnf 10001430 <outnum.isra.1+0x138> |
10001444: e0 84 c0 02 l.sub r4,r4,r24 |
*cp++ = '-'; |
*cp-- = 0; |
|
/* Move the converted number to the buffer and */ |
/* add in the padding where needed. */ |
par->len = strlen(outbuf); |
10001448: d4 16 20 00 l.sw 0(r22),r4 |
#ifdef PRINTF_ENABLE_PADDING |
padding(buf, !(par->left_flag), par); |
#endif |
count = 0; |
while (cp >= outbuf && count++ < par->max_len) |
1000144c: e4 6e c0 00 l.sfgeu r14,r24 |
10001450: 0c 00 00 14 l.bnf 100014a0 <outnum.isra.1+0x1a8> |
10001454: 84 56 00 1c l.lwz r2,28(r22) |
10001458: bd a2 00 00 l.sflesi r2,0 |
1000145c: 10 00 00 11 l.bf 100014a0 <outnum.isra.1+0x1a8> |
10001460: 1a 80 10 00 l.movhi r20,0x1000 |
/* This routine moves a number to the output buffer */ |
/* as directed by the padding and positioning flags. */ |
/* */ |
//---------------------------------------------------- |
#if defined PRINTF_DEC_PRINT || defined PRINTF_HEX_PRINT |
static void outnum( struct vbuf *buf, const long n, const long base, params_t *par) |
10001464: e2 52 c0 02 l.sub r18,r18,r24 |
par->len = strlen(outbuf); |
#ifdef PRINTF_ENABLE_PADDING |
padding(buf, !(par->left_flag), par); |
#endif |
count = 0; |
while (cp >= outbuf && count++ < par->max_len) |
10001468: 9c 40 00 01 l.addi r2,r0,1 |
1000146c: aa 94 2f f4 l.ori r20,r20,0x2ff4 |
10001470: 00 00 00 05 l.j 10001484 <outnum.isra.1+0x18c> |
10001474: 84 96 00 1c l.lwz r4,28(r22) |
10001478: e5 a4 10 00 l.sfles r4,r2 |
1000147c: a8 43 00 00 l.ori r2,r3,0x0 |
10001480: 10 00 00 08 l.bf 100014a0 <outnum.isra.1+0x1a8> |
vbuf_putchar(buf, *cp--); |
10001484: 90 6e 00 00 l.lbs r3,0(r14) |
10001488: 85 74 00 00 l.lwz r11,0(r20) |
1000148c: 9d ce ff ff l.addi r14,r14,-1 |
10001490: 48 00 58 00 l.jalr r11 |
par->len = strlen(outbuf); |
#ifdef PRINTF_ENABLE_PADDING |
padding(buf, !(par->left_flag), par); |
#endif |
count = 0; |
while (cp >= outbuf && count++ < par->max_len) |
10001494: e4 02 90 00 l.sfeq r2,r18 |
10001498: 9c 62 00 01 l.addi r3,r2,1 |
1000149c: 0f ff ff f6 l.bnf 10001474 <outnum.isra.1+0x17c> |
vbuf_putchar(buf, *cp--); |
#ifdef PRINTF_ENABLE_PADDING |
padding(buf, par->left_flag, par); |
#endif |
} |
100014a0: 9c 21 00 70 l.addi r1,r1,112 |
100014a4: 85 21 ff fc l.lwz r9,-4(r1) |
100014a8: 84 21 ff d8 l.lwz r1,-40(r1) |
100014ac: 84 41 ff dc l.lwz r2,-36(r1) |
100014b0: 85 c1 ff e0 l.lwz r14,-32(r1) |
100014b4: 86 41 ff e4 l.lwz r18,-28(r1) |
100014b8: 86 81 ff e8 l.lwz r20,-24(r1) |
100014bc: 86 c1 ff ec l.lwz r22,-20(r1) |
100014c0: 87 01 ff f0 l.lwz r24,-16(r1) |
100014c4: 87 41 ff f4 l.lwz r26,-12(r1) |
100014c8: 87 81 ff f8 l.lwz r28,-8(r1) |
100014cc: 44 00 48 00 l.jr r9 |
int count; |
|
/* Check if number is negative */ |
if (base == 10 && n < 0L) { |
negative = 1; |
num = -(n); |
100014d0: e0 40 18 02 l.sub r2,r0,r3 |
unsigned long num; |
int count; |
|
/* Check if number is negative */ |
if (base == 10 && n < 0L) { |
negative = 1; |
100014d4: 9f 80 00 01 l.addi r28,r0,1 |
100014d8: 03 ff ff b4 l.j 100013a8 <outnum.isra.1+0xb0> |
|
100014dc <printf_register>: |
//---------------------------------------------------- |
// printf_register: Assign printf output function |
//---------------------------------------------------- |
void printf_register(FP_OUTCHAR f) |
{ |
_stdout = f; |
100014dc: 18 80 10 00 l.movhi r4,0x1000 |
} |
//---------------------------------------------------- |
// printf_register: Assign printf output function |
//---------------------------------------------------- |
void printf_register(FP_OUTCHAR f) |
{ |
100014e0: d7 e1 0f fc l.sw -4(r1),r1 |
_stdout = f; |
100014e4: a8 84 2f f4 l.ori r4,r4,0x2ff4 |
} |
//---------------------------------------------------- |
// printf_register: Assign printf output function |
//---------------------------------------------------- |
void printf_register(FP_OUTCHAR f) |
{ |
100014e8: 9c 21 ff fc l.addi r1,r1,-4 |
_stdout = f; |
100014ec: d4 04 18 00 l.sw 0(r4),r3 |
} |
100014f0: 9c 21 00 04 l.addi r1,r1,4 |
100014f4: 84 21 ff fc l.lwz r1,-4(r1) |
100014f8: 44 00 48 00 l.jr r9 |
|
100014fc <puts>: |
#endif |
//---------------------------------------------------- |
// puts: |
//---------------------------------------------------- |
int puts( const char * str ) |
{ |
100014fc: d7 e1 77 f8 l.sw -8(r1),r14 |
if (!_stdout) |
10001500: 19 c0 10 00 l.movhi r14,0x1000 |
#endif |
//---------------------------------------------------- |
// puts: |
//---------------------------------------------------- |
int puts( const char * str ) |
{ |
10001504: d7 e1 17 f4 l.sw -12(r1),r2 |
if (!_stdout) |
10001508: a9 ce 2f f4 l.ori r14,r14,0x2ff4 |
#endif |
//---------------------------------------------------- |
// puts: |
//---------------------------------------------------- |
int puts( const char * str ) |
{ |
1000150c: d7 e1 4f fc l.sw -4(r1),r9 |
if (!_stdout) |
10001510: 85 6e 00 00 l.lwz r11,0(r14) |
#endif |
//---------------------------------------------------- |
// puts: |
//---------------------------------------------------- |
int puts( const char * str ) |
{ |
10001514: d7 e1 0f f0 l.sw -16(r1),r1 |
if (!_stdout) |
10001518: bc 0b 00 00 l.sfeqi r11,0 |
#endif |
//---------------------------------------------------- |
// puts: |
//---------------------------------------------------- |
int puts( const char * str ) |
{ |
1000151c: 9c 21 ff f0 l.addi r1,r1,-16 |
10001520: a8 43 00 00 l.ori r2,r3,0x0 |
if (!_stdout) |
10001524: 10 00 00 12 l.bf 1000156c <puts+0x70> |
return -1; |
|
while (*str) |
10001528: 90 63 00 00 l.lbs r3,0(r3) |
1000152c: bc 03 00 00 l.sfeqi r3,0 |
10001530: 10 00 00 07 l.bf 1000154c <puts+0x50> |
_stdout(*str++); |
10001534: 9c 42 00 01 l.addi r2,r2,1 |
10001538: 48 00 58 00 l.jalr r11 |
int puts( const char * str ) |
{ |
if (!_stdout) |
return -1; |
|
while (*str) |
1000153c: 90 62 00 00 l.lbs r3,0(r2) |
10001540: bc 03 00 00 l.sfeqi r3,0 |
10001544: 85 6e 00 00 l.lwz r11,0(r14) |
10001548: 0f ff ff fb l.bnf 10001534 <puts+0x38> |
_stdout(*str++); |
|
return _stdout('\n'); |
1000154c: 9c 60 00 0a l.addi r3,r0,10 |
10001550: 48 00 58 00 l.jalr r11 |
} |
10001554: 9c 21 00 10 l.addi r1,r1,16 |
10001558: 85 21 ff fc l.lwz r9,-4(r1) |
1000155c: 84 21 ff f0 l.lwz r1,-16(r1) |
10001560: 84 41 ff f4 l.lwz r2,-12(r1) |
10001564: 85 c1 ff f8 l.lwz r14,-8(r1) |
10001568: 44 00 48 00 l.jr r9 |
// puts: |
//---------------------------------------------------- |
int puts( const char * str ) |
{ |
if (!_stdout) |
return -1; |
1000156c: 9d 60 ff ff l.addi r11,r0,-1 |
10001570: 03 ff ff f9 l.j 10001554 <puts+0x58> |
|
10001574 <putchar>: |
} |
//---------------------------------------------------- |
// putchar: |
//---------------------------------------------------- |
int putchar( int c ) |
{ |
10001574: d7 e1 17 f8 l.sw -8(r1),r2 |
10001578: a8 43 00 00 l.ori r2,r3,0x0 |
if (!_stdout) |
1000157c: 18 60 10 00 l.movhi r3,0x1000 |
} |
//---------------------------------------------------- |
// putchar: |
//---------------------------------------------------- |
int putchar( int c ) |
{ |
10001580: d7 e1 4f fc l.sw -4(r1),r9 |
if (!_stdout) |
10001584: a8 63 2f f4 l.ori r3,r3,0x2ff4 |
} |
//---------------------------------------------------- |
// putchar: |
//---------------------------------------------------- |
int putchar( int c ) |
{ |
10001588: d7 e1 0f f4 l.sw -12(r1),r1 |
if (!_stdout) |
1000158c: 85 63 00 00 l.lwz r11,0(r3) |
} |
//---------------------------------------------------- |
// putchar: |
//---------------------------------------------------- |
int putchar( int c ) |
{ |
10001590: 9c 21 ff f4 l.addi r1,r1,-12 |
if (!_stdout) |
10001594: bc 0b 00 00 l.sfeqi r11,0 |
10001598: 10 00 00 0a l.bf 100015c0 <putchar+0x4c> |
return -1; |
|
_stdout((char)c); |
1000159c: b8 62 00 18 l.slli r3,r2,0x18 |
100015a0: b8 63 00 98 l.srai r3,r3,0x18 |
100015a4: 48 00 58 00 l.jalr r11 |
|
return c; |
100015a8: a9 62 00 00 l.ori r11,r2,0x0 |
} |
100015ac: 9c 21 00 0c l.addi r1,r1,12 |
100015b0: 85 21 ff fc l.lwz r9,-4(r1) |
100015b4: 84 21 ff f4 l.lwz r1,-12(r1) |
100015b8: 84 41 ff f8 l.lwz r2,-8(r1) |
100015bc: 44 00 48 00 l.jr r9 |
// putchar: |
//---------------------------------------------------- |
int putchar( int c ) |
{ |
if (!_stdout) |
return -1; |
100015c0: 9d 60 ff ff l.addi r11,r0,-1 |
100015c4: 03 ff ff fa l.j 100015ac <putchar+0x38> |
|
100015c8 <vbuf_printf>: |
/* added easily by following the examples shown for */ |
/* the supported formats. */ |
/* */ |
//---------------------------------------------------- |
int vbuf_printf(struct vbuf *buf, const char* ctrl1, va_list argp) |
{ |
100015c8: d7 e1 97 e0 l.sw -32(r1),r18 |
100015cc: d7 e1 f7 f8 l.sw -8(r1),r30 |
100015d0: d7 e1 4f fc l.sw -4(r1),r9 |
100015d4: d7 e1 0f d4 l.sw -44(r1),r1 |
100015d8: d7 e1 17 d8 l.sw -40(r1),r2 |
100015dc: d7 e1 77 dc l.sw -36(r1),r14 |
100015e0: d7 e1 a7 e4 l.sw -28(r1),r20 |
100015e4: d7 e1 b7 e8 l.sw -24(r1),r22 |
100015e8: d7 e1 c7 ec l.sw -20(r1),r24 |
100015ec: d7 e1 d7 f0 l.sw -16(r1),r26 |
100015f0: d7 e1 e7 f4 l.sw -12(r1),r28 |
100015f4: ab c4 00 00 l.ori r30,r4,0x0 |
params_t par; |
|
char ch; |
char* ctrl = (char*)ctrl1; |
|
for ( ; *ctrl; ctrl++) |
100015f8: 90 64 00 00 l.lbs r3,0(r4) |
100015fc: bc 23 00 00 l.sfnei r3,0 |
/* added easily by following the examples shown for */ |
/* the supported formats. */ |
/* */ |
//---------------------------------------------------- |
int vbuf_printf(struct vbuf *buf, const char* ctrl1, va_list argp) |
{ |
10001600: 9c 21 ff b4 l.addi r1,r1,-76 |
10001604: aa 45 00 00 l.ori r18,r5,0x0 |
params_t par; |
|
char ch; |
char* ctrl = (char*)ctrl1; |
|
for ( ; *ctrl; ctrl++) |
10001608: 0c 00 00 77 l.bnf 100017e4 <vbuf_printf+0x21c> |
{ |
/* move format string chars to buffer until a */ |
/* format control is found. */ |
if (*ctrl != '%') |
{ |
vbuf_putchar(buf, *ctrl); |
1000160c: 19 c0 10 00 l.movhi r14,0x1000 |
} |
|
/* initialize all the flags for this format. */ |
dot_flag = long_flag = par.left_flag = par.do_padding = 0; |
par.pad_character = ' '; |
par.num2=32767; |
10001610: 9f 40 7f ff l.addi r26,r0,32767 |
{ |
/* move format string chars to buffer until a */ |
/* format control is found. */ |
if (*ctrl != '%') |
{ |
vbuf_putchar(buf, *ctrl); |
10001614: a9 ce 2f f4 l.ori r14,r14,0x2ff4 |
|
/* initialize all the flags for this format. */ |
dot_flag = long_flag = par.left_flag = par.do_padding = 0; |
par.pad_character = ' '; |
par.num2=32767; |
par.max_len = 10; |
10001618: 9f 00 00 0a l.addi r24,r0,10 |
1000161c: 00 00 00 08 l.j 1000163c <vbuf_printf+0x74> |
{ |
/* move format string chars to buffer until a */ |
/* format control is found. */ |
if (*ctrl != '%') |
{ |
vbuf_putchar(buf, *ctrl); |
10001620: 85 6e 00 00 l.lwz r11,0(r14) |
continue; |
10001624: ab 9e 00 00 l.ori r28,r30,0x0 |
{ |
/* move format string chars to buffer until a */ |
/* format control is found. */ |
if (*ctrl != '%') |
{ |
vbuf_putchar(buf, *ctrl); |
10001628: 48 00 58 00 l.jalr r11 |
params_t par; |
|
char ch; |
char* ctrl = (char*)ctrl1; |
|
for ( ; *ctrl; ctrl++) |
1000162c: 90 7c 00 01 l.lbs r3,1(r28) |
10001630: bc 03 00 00 l.sfeqi r3,0 |
10001634: 9f dc 00 01 l.addi r30,r28,1 |
10001638: 10 00 00 6b l.bf 100017e4 <vbuf_printf+0x21c> |
{ |
/* move format string chars to buffer until a */ |
/* format control is found. */ |
if (*ctrl != '%') |
1000163c: bc 03 00 25 l.sfeqi r3,37 |
10001640: 0f ff ff f8 l.bnf 10001620 <vbuf_printf+0x58> |
|
/* initialize all the flags for this format. */ |
dot_flag = long_flag = par.left_flag = par.do_padding = 0; |
par.pad_character = ' '; |
par.num2=32767; |
par.max_len = 10; |
10001644: 90 be 00 01 l.lbs r5,1(r30) |
continue; |
} |
|
/* initialize all the flags for this format. */ |
dot_flag = long_flag = par.left_flag = par.do_padding = 0; |
par.pad_character = ' '; |
10001648: 9c 60 00 20 l.addi r3,r0,32 |
vbuf_putchar(buf, *ctrl); |
continue; |
} |
|
/* initialize all the flags for this format. */ |
dot_flag = long_flag = par.left_flag = par.do_padding = 0; |
1000164c: 9c 40 00 00 l.addi r2,r0,0 |
par.pad_character = ' '; |
10001650: d8 01 18 0c l.sb 12(r1),r3 |
par.max_len = 10; |
|
try_next: |
ch = *(++ctrl); |
|
if ((ch >= '0' && ch <= '9')) |
10001654: a4 65 00 ff l.andi r3,r5,0xff |
vbuf_putchar(buf, *ctrl); |
continue; |
} |
|
/* initialize all the flags for this format. */ |
dot_flag = long_flag = par.left_flag = par.do_padding = 0; |
10001658: d4 01 10 10 l.sw 16(r1),r2 |
par.max_len = 10; |
|
try_next: |
ch = *(++ctrl); |
|
if ((ch >= '0' && ch <= '9')) |
1000165c: 9c 83 ff d0 l.addi r4,r3,-48 |
vbuf_putchar(buf, *ctrl); |
continue; |
} |
|
/* initialize all the flags for this format. */ |
dot_flag = long_flag = par.left_flag = par.do_padding = 0; |
10001660: d4 01 10 14 l.sw 20(r1),r2 |
par.max_len = 10; |
|
try_next: |
ch = *(++ctrl); |
|
if ((ch >= '0' && ch <= '9')) |
10001664: a4 84 00 ff l.andi r4,r4,0xff |
} |
|
/* initialize all the flags for this format. */ |
dot_flag = long_flag = par.left_flag = par.do_padding = 0; |
par.pad_character = ' '; |
par.num2=32767; |
10001668: d4 01 d0 08 l.sw 8(r1),r26 |
par.max_len = 10; |
1000166c: d4 01 c0 1c l.sw 28(r1),r24 |
|
try_next: |
ch = *(++ctrl); |
|
if ((ch >= '0' && ch <= '9')) |
10001670: bc 44 00 09 l.sfgtui r4,9 |
10001674: 9f 9e 00 01 l.addi r28,r30,1 |
} |
ctrl--; |
goto try_next; |
} |
|
par.uppercase = (ch >= 'A' && ch <= 'Z') ? 1 : 0; |
10001678: 9e 80 00 01 l.addi r20,r0,1 |
par.max_len = 10; |
|
try_next: |
ch = *(++ctrl); |
|
if ((ch >= '0' && ch <= '9')) |
1000167c: 10 00 00 1a l.bf 100016e4 <vbuf_printf+0x11c> |
{ |
if (dot_flag) |
10001680: bc 02 00 00 l.sfeqi r2,0 |
10001684: 10 00 00 9a l.bf 100018ec <vbuf_printf+0x324> |
10001688: 9c c0 00 00 l.addi r6,r0,0 |
1000168c: 9c 85 ff d0 l.addi r4,r5,-48 |
10001690: 00 00 00 02 l.j 10001698 <vbuf_printf+0xd0> |
char* cp; |
|
n = 0; |
cp = *linep; |
while (((*cp) >= '0' && (*cp) <= '9')) |
n = n*10 + ((*cp++) - '0'); |
10001694: ab 83 00 00 l.ori r28,r3,0x0 |
10001698: b8 e6 00 03 l.slli r7,r6,0x3 |
1000169c: 9c 7c 00 01 l.addi r3,r28,1 |
100016a0: e0 c6 30 00 l.add r6,r6,r6 |
long n; |
char* cp; |
|
n = 0; |
cp = *linep; |
while (((*cp) >= '0' && (*cp) <= '9')) |
100016a4: 90 a3 00 00 l.lbs r5,0(r3) |
n = n*10 + ((*cp++) - '0'); |
100016a8: e0 c6 38 00 l.add r6,r6,r7 |
100016ac: e0 c6 20 00 l.add r6,r6,r4 |
long n; |
char* cp; |
|
n = 0; |
cp = *linep; |
while (((*cp) >= '0' && (*cp) <= '9')) |
100016b0: 9c 85 ff d0 l.addi r4,r5,-48 |
100016b4: a4 e4 00 ff l.andi r7,r4,0xff |
100016b8: bc 47 00 09 l.sfgtui r7,9 |
100016bc: 0f ff ff f6 l.bnf 10001694 <vbuf_printf+0xcc> |
100016c0: a8 83 00 00 l.ori r4,r3,0x0 |
ch = *(++ctrl); |
|
if ((ch >= '0' && ch <= '9')) |
{ |
if (dot_flag) |
par.num2 = getnum(&ctrl); |
100016c4: d4 01 30 08 l.sw 8(r1),r6 |
par.pad_character = '0'; |
|
par.num1 = getnum(&ctrl); |
par.do_padding = 1; |
} |
ctrl--; |
100016c8: 9f c3 ff ff l.addi r30,r3,-1 |
100016cc: ab 84 00 00 l.ori r28,r4,0x0 |
par.max_len = 10; |
|
try_next: |
ch = *(++ctrl); |
|
if ((ch >= '0' && ch <= '9')) |
100016d0: a4 65 00 ff l.andi r3,r5,0xff |
100016d4: 9c 83 ff d0 l.addi r4,r3,-48 |
100016d8: a4 84 00 ff l.andi r4,r4,0xff |
100016dc: bc 44 00 09 l.sfgtui r4,9 |
100016e0: 0f ff ff e8 l.bnf 10001680 <vbuf_printf+0xb8> |
} |
ctrl--; |
goto try_next; |
} |
|
par.uppercase = (ch >= 'A' && ch <= 'Z') ? 1 : 0; |
100016e4: 9c 63 ff bf l.addi r3,r3,-65 |
100016e8: 9c 80 00 01 l.addi r4,r0,1 |
100016ec: a4 63 00 ff l.andi r3,r3,0xff |
100016f0: bc a3 00 19 l.sfleui r3,25 |
100016f4: 10 00 00 02 l.bf 100016fc <vbuf_printf+0x134> |
100016f8: 9c 80 00 00 l.addi r4,r0,0 |
100016fc: d4 01 20 18 l.sw 24(r1),r4 |
|
switch ((par.uppercase ? ch + 32: ch)) |
10001700: bc 04 00 00 l.sfeqi r4,0 |
10001704: a8 65 00 00 l.ori r3,r5,0x0 |
10001708: 10 00 00 02 l.bf 10001710 <vbuf_printf+0x148> |
1000170c: 9c 65 00 20 l.addi r3,r5,32 |
10001710: 9c 63 ff db l.addi r3,r3,-37 |
10001714: bc 43 00 53 l.sfgtui r3,83 |
10001718: 13 ff ff c5 l.bf 1000162c <vbuf_printf+0x64> |
1000171c: 18 80 10 00 l.movhi r4,0x1000 |
10001720: b8 63 00 02 l.slli r3,r3,0x2 |
10001724: a8 84 2b 24 l.ori r4,r4,0x2b24 |
10001728: e0 63 20 00 l.add r3,r3,r4 |
1000172c: 84 63 00 00 l.lwz r3,0(r3) |
10001730: 44 00 18 00 l.jr r3 |
} |
continue; |
#endif |
#ifdef PRINTF_STR_PRINT |
case 's': |
outs(buf, va_arg( argp, char*), &par); |
10001734: 86 d2 00 00 l.lwz r22,0(r18) |
10001738: 9e 52 00 04 l.addi r18,r18,4 |
//---------------------------------------------------- |
static int strlen(const char * str) |
{ |
const char * s; |
|
if(!str) |
1000173c: bc 16 00 00 l.sfeqi r22,0 |
10001740: 10 00 00 a4 l.bf 100019d0 <vbuf_printf+0x408> |
return 0; |
|
for(s = str; *s; ++ s) |
10001744: 90 56 00 00 l.lbs r2,0(r22) |
10001748: bc 02 00 00 l.sfeqi r2,0 |
1000174c: 10 00 00 07 l.bf 10001768 <vbuf_printf+0x1a0> |
10001750: a8 56 00 00 l.ori r2,r22,0x0 |
10001754: 9c 42 00 01 l.addi r2,r2,1 |
10001758: 90 62 00 00 l.lbs r3,0(r2) |
1000175c: bc 03 00 00 l.sfeqi r3,0 |
10001760: 0f ff ff fd l.bnf 10001754 <vbuf_printf+0x18c> |
10001764: e0 42 b0 02 l.sub r2,r2,r22 |
//---------------------------------------------------- |
#ifdef PRINTF_STR_PRINT |
static void outs( struct vbuf *buf, char* lp, params_t *par) |
{ |
/* pad on left if needed */ |
par->len = strlen( lp); |
10001768: d4 01 10 00 l.sw 0(r1),r2 |
#ifdef PRINTF_ENABLE_PADDING |
padding(buf, !(par->left_flag), par); |
#endif |
|
/* Move string to the buffer */ |
while (*lp && (par->num2)--) |
1000176c: 90 56 00 00 l.lbs r2,0(r22) |
10001770: bc 02 00 00 l.sfeqi r2,0 |
10001774: 10 00 00 16 l.bf 100017cc <vbuf_printf+0x204> |
10001778: 84 41 00 08 l.lwz r2,8(r1) |
1000177c: aa 96 00 00 l.ori r20,r22,0x0 |
10001780: 9c 62 ff ff l.addi r3,r2,-1 |
10001784: bc 22 00 00 l.sfnei r2,0 |
10001788: d4 01 18 08 l.sw 8(r1),r3 |
1000178c: 10 00 00 09 l.bf 100017b0 <vbuf_printf+0x1e8> |
10001790: 00 00 00 92 l.j 100019d8 <vbuf_printf+0x410> |
10001794: 84 61 00 08 l.lwz r3,8(r1) |
10001798: 9e 94 00 01 l.addi r20,r20,1 |
1000179c: 9c 83 ff ff l.addi r4,r3,-1 |
100017a0: bc 03 00 00 l.sfeqi r3,0 |
100017a4: d4 01 20 08 l.sw 8(r1),r4 |
100017a8: 10 00 00 72 l.bf 10001970 <vbuf_printf+0x3a8> |
vbuf_putchar(buf, *lp++); |
100017ac: aa c2 00 00 l.ori r22,r2,0x0 |
100017b0: 90 74 00 00 l.lbs r3,0(r20) |
100017b4: 85 6e 00 00 l.lwz r11,0(r14) |
100017b8: 9c 56 00 01 l.addi r2,r22,1 |
100017bc: 48 00 58 00 l.jalr r11 |
#ifdef PRINTF_ENABLE_PADDING |
padding(buf, !(par->left_flag), par); |
#endif |
|
/* Move string to the buffer */ |
while (*lp && (par->num2)--) |
100017c0: 90 62 00 00 l.lbs r3,0(r2) |
100017c4: bc 03 00 00 l.sfeqi r3,0 |
100017c8: 0f ff ff f3 l.bnf 10001794 <vbuf_printf+0x1cc> |
const char * s; |
|
if(!str) |
return 0; |
|
for(s = str; *s; ++ s) |
100017cc: 9c 60 00 00 l.addi r3,r0,0 |
/* Move string to the buffer */ |
while (*lp && (par->num2)--) |
vbuf_putchar(buf, *lp++); |
|
/* Pad on right if needed */ |
par->len = strlen( lp); |
100017d0: d4 01 18 00 l.sw 0(r1),r3 |
params_t par; |
|
char ch; |
char* ctrl = (char*)ctrl1; |
|
for ( ; *ctrl; ctrl++) |
100017d4: 90 7c 00 01 l.lbs r3,1(r28) |
100017d8: bc 03 00 00 l.sfeqi r3,0 |
100017dc: 9f dc 00 01 l.addi r30,r28,1 |
100017e0: 0f ff ff 97 l.bnf 1000163c <vbuf_printf+0x74> |
} |
goto try_next; |
} |
|
return res; |
} |
100017e4: 9c 21 00 4c l.addi r1,r1,76 |
100017e8: 9d 60 00 00 l.addi r11,r0,0 |
100017ec: 85 21 ff fc l.lwz r9,-4(r1) |
100017f0: 84 21 ff d4 l.lwz r1,-44(r1) |
100017f4: 84 41 ff d8 l.lwz r2,-40(r1) |
100017f8: 85 c1 ff dc l.lwz r14,-36(r1) |
100017fc: 86 41 ff e0 l.lwz r18,-32(r1) |
10001800: 86 81 ff e4 l.lwz r20,-28(r1) |
10001804: 86 c1 ff e8 l.lwz r22,-24(r1) |
10001808: 87 01 ff ec l.lwz r24,-20(r1) |
1000180c: 87 41 ff f0 l.lwz r26,-16(r1) |
10001810: 87 81 ff f4 l.lwz r28,-12(r1) |
10001814: 87 c1 ff f8 l.lwz r30,-8(r1) |
10001818: 44 00 48 00 l.jr r9 |
case 'x': |
case 'p': |
if (long_flag || ch == 'D') |
{ |
par.max_len = sizeof(long) * 2; |
outnum(buf, (long)va_arg(argp, long), 16L, &par); |
1000181c: 84 72 00 00 l.lwz r3,0(r18) |
#ifdef PRINTF_HEX_PRINT |
case 'x': |
case 'p': |
if (long_flag || ch == 'D') |
{ |
par.max_len = sizeof(long) * 2; |
10001820: 9c 40 00 08 l.addi r2,r0,8 |
outnum(buf, (long)va_arg(argp, long), 16L, &par); |
10001824: 9c 80 00 10 l.addi r4,r0,16 |
10001828: a8 a1 00 00 l.ori r5,r1,0x0 |
1000182c: 9e 52 00 04 l.addi r18,r18,4 |
#ifdef PRINTF_HEX_PRINT |
case 'x': |
case 'p': |
if (long_flag || ch == 'D') |
{ |
par.max_len = sizeof(long) * 2; |
10001830: d4 01 10 1c l.sw 28(r1),r2 |
outnum(buf, (long)va_arg(argp, long), 16L, &par); |
10001834: 07 ff fe b1 l.jal 100012f8 <outnum.isra.1> |
10001838: 03 ff ff 7d l.j 1000162c <vbuf_printf+0x64> |
1000183c: 9c 9e 00 02 l.addi r4,r30,2 |
10001840: 90 be 00 02 l.lbs r5,2(r30) |
par.pad_character = ' '; |
par.num2=32767; |
par.max_len = 10; |
|
try_next: |
ch = *(++ctrl); |
10001844: ab dc 00 00 l.ori r30,r28,0x0 |
10001848: ab 84 00 00 l.ori r28,r4,0x0 |
1000184c: 03 ff ff a1 l.j 100016d0 <vbuf_printf+0x108> |
{ |
outnum(buf, va_arg(argp, long), 10L, &par); |
continue; |
} |
else { |
outnum(buf, va_arg(argp, int), 10L, &par); |
10001850: 84 72 00 00 l.lwz r3,0(r18) |
10001854: 9c 80 00 0a l.addi r4,r0,10 |
10001858: a8 a1 00 00 l.ori r5,r1,0x0 |
1000185c: 9e 52 00 04 l.addi r18,r18,4 |
case 'x': |
case 'p': |
if (long_flag || ch == 'D') |
{ |
par.max_len = sizeof(long) * 2; |
outnum(buf, (long)va_arg(argp, long), 16L, &par); |
10001860: 07 ff fe a6 l.jal 100012f8 <outnum.isra.1> |
10001864: 03 ff ff 72 l.j 1000162c <vbuf_printf+0x64> |
outs(buf, va_arg( argp, char*), &par); |
continue; |
#endif |
#ifdef PRINTF_CHR_PRINT |
case 'c': |
vbuf_putchar(buf, va_arg( argp, int)); |
10001868: 90 72 00 03 l.lbs r3,3(r18) |
1000186c: 85 6e 00 00 l.lwz r11,0(r14) |
10001870: 9e 52 00 04 l.addi r18,r18,4 |
10001874: 48 00 58 00 l.jalr r11 |
continue; |
10001878: 03 ff ff 6d l.j 1000162c <vbuf_printf+0x64> |
#endif |
case '\\': |
switch (*ctrl) { |
1000187c: bc 05 00 68 l.sfeqi r5,104 |
10001880: 10 00 00 50 l.bf 100019c0 <vbuf_printf+0x3f8> |
10001884: bd 45 00 68 l.sfgtsi r5,104 |
10001888: 0c 00 00 30 l.bnf 10001948 <vbuf_printf+0x380> |
1000188c: bc 05 00 6e l.sfeqi r5,110 |
10001890: 10 00 00 48 l.bf 100019b0 <vbuf_printf+0x3e8> |
10001894: bc 05 00 72 l.sfeqi r5,114 |
10001898: 0c 00 00 42 l.bnf 100019a0 <vbuf_printf+0x3d8> |
break; |
case 'h': |
vbuf_putchar(buf, 0x08); |
break; |
case 'r': |
vbuf_putchar(buf, 0x0D); |
1000189c: 85 6e 00 00 l.lwz r11,0(r14) |
100018a0: 9c 60 00 0d l.addi r3,r0,13 |
100018a4: 48 00 58 00 l.jalr r11 |
break; |
100018a8: 00 00 00 2d l.j 1000195c <vbuf_printf+0x394> |
100018ac: 9c 9e 00 02 l.addi r4,r30,2 |
100018b0: 90 be 00 02 l.lbs r5,2(r30) |
case '-': |
par.left_flag = 1; |
break; |
|
case '.': |
dot_flag = 1; |
100018b4: 9c 40 00 01 l.addi r2,r0,1 |
par.pad_character = ' '; |
par.num2=32767; |
par.max_len = 10; |
|
try_next: |
ch = *(++ctrl); |
100018b8: ab dc 00 00 l.ori r30,r28,0x0 |
100018bc: ab 84 00 00 l.ori r28,r4,0x0 |
100018c0: 03 ff ff 84 l.j 100016d0 <vbuf_printf+0x108> |
100018c4: 9c 9e 00 02 l.addi r4,r30,2 |
100018c8: 90 be 00 02 l.lbs r5,2(r30) |
case '%': |
vbuf_putchar(buf, '%'); |
continue; |
|
case '-': |
par.left_flag = 1; |
100018cc: d4 01 a0 14 l.sw 20(r1),r20 |
par.pad_character = ' '; |
par.num2=32767; |
par.max_len = 10; |
|
try_next: |
ch = *(++ctrl); |
100018d0: ab dc 00 00 l.ori r30,r28,0x0 |
100018d4: ab 84 00 00 l.ori r28,r4,0x0 |
100018d8: 03 ff ff 7e l.j 100016d0 <vbuf_printf+0x108> |
par.uppercase = (ch >= 'A' && ch <= 'Z') ? 1 : 0; |
|
switch ((par.uppercase ? ch + 32: ch)) |
{ |
case '%': |
vbuf_putchar(buf, '%'); |
100018dc: 85 6e 00 00 l.lwz r11,0(r14) |
100018e0: 9c 60 00 25 l.addi r3,r0,37 |
100018e4: 48 00 58 00 l.jalr r11 |
continue; |
100018e8: 03 ff ff 51 l.j 1000162c <vbuf_printf+0x64> |
if ((ch >= '0' && ch <= '9')) |
{ |
if (dot_flag) |
par.num2 = getnum(&ctrl); |
else { |
if (ch == '0') |
100018ec: bc 25 00 30 l.sfnei r5,48 |
100018f0: 0c 00 00 14 l.bnf 10001940 <vbuf_printf+0x378> |
static long getnum( char** linep) |
{ |
long n; |
char* cp; |
|
n = 0; |
100018f4: 9c c0 00 00 l.addi r6,r0,0 |
100018f8: 9c 85 ff d0 l.addi r4,r5,-48 |
100018fc: 00 00 00 02 l.j 10001904 <vbuf_printf+0x33c> |
cp = *linep; |
while (((*cp) >= '0' && (*cp) <= '9')) |
n = n*10 + ((*cp++) - '0'); |
10001900: ab 83 00 00 l.ori r28,r3,0x0 |
10001904: b8 e6 00 03 l.slli r7,r6,0x3 |
10001908: 9c 7c 00 01 l.addi r3,r28,1 |
1000190c: e0 c6 30 00 l.add r6,r6,r6 |
long n; |
char* cp; |
|
n = 0; |
cp = *linep; |
while (((*cp) >= '0' && (*cp) <= '9')) |
10001910: 90 a3 00 00 l.lbs r5,0(r3) |
n = n*10 + ((*cp++) - '0'); |
10001914: e0 c6 38 00 l.add r6,r6,r7 |
10001918: e0 c6 20 00 l.add r6,r6,r4 |
long n; |
char* cp; |
|
n = 0; |
cp = *linep; |
while (((*cp) >= '0' && (*cp) <= '9')) |
1000191c: 9c 85 ff d0 l.addi r4,r5,-48 |
10001920: a4 e4 00 ff l.andi r7,r4,0xff |
10001924: bc 47 00 09 l.sfgtui r7,9 |
10001928: 0f ff ff f6 l.bnf 10001900 <vbuf_printf+0x338> |
1000192c: a8 83 00 00 l.ori r4,r3,0x0 |
par.num2 = getnum(&ctrl); |
else { |
if (ch == '0') |
par.pad_character = '0'; |
|
par.num1 = getnum(&ctrl); |
10001930: d4 01 30 04 l.sw 4(r1),r6 |
par.do_padding = 1; |
10001934: d4 01 a0 10 l.sw 16(r1),r20 |
} |
ctrl--; |
10001938: 9f c3 ff ff l.addi r30,r3,-1 |
1000193c: 03 ff ff 64 l.j 100016cc <vbuf_printf+0x104> |
{ |
if (dot_flag) |
par.num2 = getnum(&ctrl); |
else { |
if (ch == '0') |
par.pad_character = '0'; |
10001940: d8 01 28 0c l.sb 12(r1),r5 |
10001944: 03 ff ff ec l.j 100018f4 <vbuf_printf+0x32c> |
case 'c': |
vbuf_putchar(buf, va_arg( argp, int)); |
continue; |
#endif |
case '\\': |
switch (*ctrl) { |
10001948: bc 05 00 61 l.sfeqi r5,97 |
1000194c: 0c 00 00 15 l.bnf 100019a0 <vbuf_printf+0x3d8> |
case 'a': |
vbuf_putchar(buf, 0x07); |
10001950: 85 6e 00 00 l.lwz r11,0(r14) |
10001954: 9c 60 00 07 l.addi r3,r0,7 |
10001958: 48 00 58 00 l.jalr r11 |
1000195c: 9c 9e 00 03 l.addi r4,r30,3 |
10001960: 90 be 00 03 l.lbs r5,3(r30) |
10001964: ab 84 00 00 l.ori r28,r4,0x0 |
break; |
default: |
vbuf_putchar(buf, *ctrl); |
break; |
} |
ctrl++; |
10001968: 9f de 00 02 l.addi r30,r30,2 |
1000196c: 03 ff ff 59 l.j 100016d0 <vbuf_printf+0x108> |
10001970: 90 76 00 01 l.lbs r3,1(r22) |
const char * s; |
|
if(!str) |
return 0; |
|
for(s = str; *s; ++ s) |
10001974: bc 03 00 00 l.sfeqi r3,0 |
10001978: 9c 60 00 00 l.addi r3,r0,0 |
1000197c: 13 ff ff 95 l.bf 100017d0 <vbuf_printf+0x208> |
10001980: a8 62 00 00 l.ori r3,r2,0x0 |
10001984: 9c 63 00 01 l.addi r3,r3,1 |
10001988: 90 83 00 00 l.lbs r4,0(r3) |
1000198c: bc 04 00 00 l.sfeqi r4,0 |
10001990: 0f ff ff fd l.bnf 10001984 <vbuf_printf+0x3bc> |
10001994: e0 63 10 02 l.sub r3,r3,r2 |
/* Move string to the buffer */ |
while (*lp && (par->num2)--) |
vbuf_putchar(buf, *lp++); |
|
/* Pad on right if needed */ |
par->len = strlen( lp); |
10001998: d4 01 18 00 l.sw 0(r1),r3 |
1000199c: 03 ff ff 8e l.j 100017d4 <vbuf_printf+0x20c> |
break; |
case 'n': |
vbuf_putchar(buf, 0x0A); |
break; |
default: |
vbuf_putchar(buf, *ctrl); |
100019a0: 90 7e 00 01 l.lbs r3,1(r30) |
100019a4: 85 6e 00 00 l.lwz r11,0(r14) |
100019a8: 48 00 58 00 l.jalr r11 |
break; |
100019ac: 03 ff ff ec l.j 1000195c <vbuf_printf+0x394> |
break; |
case 'r': |
vbuf_putchar(buf, 0x0D); |
break; |
case 'n': |
vbuf_putchar(buf, 0x0A); |
100019b0: 85 6e 00 00 l.lwz r11,0(r14) |
100019b4: 9c 60 00 0a l.addi r3,r0,10 |
100019b8: 48 00 58 00 l.jalr r11 |
break; |
100019bc: 03 ff ff e8 l.j 1000195c <vbuf_printf+0x394> |
switch (*ctrl) { |
case 'a': |
vbuf_putchar(buf, 0x07); |
break; |
case 'h': |
vbuf_putchar(buf, 0x08); |
100019c0: 85 6e 00 00 l.lwz r11,0(r14) |
100019c4: 9c 60 00 08 l.addi r3,r0,8 |
100019c8: 48 00 58 00 l.jalr r11 |
break; |
100019cc: 03 ff ff e4 l.j 1000195c <vbuf_printf+0x394> |
static int strlen(const char * str) |
{ |
const char * s; |
|
if(!str) |
return 0; |
100019d0: a8 56 00 00 l.ori r2,r22,0x0 |
100019d4: 03 ff ff 65 l.j 10001768 <vbuf_printf+0x1a0> |
100019d8: 90 76 00 00 l.lbs r3,0(r22) |
#ifdef PRINTF_ENABLE_PADDING |
padding(buf, !(par->left_flag), par); |
#endif |
|
/* Move string to the buffer */ |
while (*lp && (par->num2)--) |
100019dc: a8 56 00 00 l.ori r2,r22,0x0 |
100019e0: 03 ff ff e5 l.j 10001974 <vbuf_printf+0x3ac> |
|
100019e4 <printf>: |
{ |
int res = 0; |
va_list argp; |
struct vbuf buf; |
|
if (_stdout && ctrl1) |
100019e4: 18 a0 10 00 l.movhi r5,0x1000 |
} |
//---------------------------------------------------- |
// printf: Console based printf |
//---------------------------------------------------- |
int printf( const char* ctrl1, ... ) |
{ |
100019e8: d7 e1 4f fc l.sw -4(r1),r9 |
int res = 0; |
va_list argp; |
struct vbuf buf; |
|
if (_stdout && ctrl1) |
100019ec: a8 a5 2f f4 l.ori r5,r5,0x2ff4 |
} |
//---------------------------------------------------- |
// printf: Console based printf |
//---------------------------------------------------- |
int printf( const char* ctrl1, ... ) |
{ |
100019f0: d7 e1 0f f4 l.sw -12(r1),r1 |
int res = 0; |
va_list argp; |
struct vbuf buf; |
|
if (_stdout && ctrl1) |
100019f4: 85 65 00 00 l.lwz r11,0(r5) |
} |
//---------------------------------------------------- |
// printf: Console based printf |
//---------------------------------------------------- |
int printf( const char* ctrl1, ... ) |
{ |
100019f8: d7 e1 17 f8 l.sw -8(r1),r2 |
int res = 0; |
va_list argp; |
struct vbuf buf; |
|
if (_stdout && ctrl1) |
100019fc: bc 0b 00 00 l.sfeqi r11,0 |
} |
//---------------------------------------------------- |
// printf: Console based printf |
//---------------------------------------------------- |
int printf( const char* ctrl1, ... ) |
{ |
10001a00: 9c 21 ff e4 l.addi r1,r1,-28 |
10001a04: a8 83 00 00 l.ori r4,r3,0x0 |
int res = 0; |
va_list argp; |
struct vbuf buf; |
|
if (_stdout && ctrl1) |
10001a08: 10 00 00 09 l.bf 10001a2c <printf+0x48> |
{ |
va_start( argp, ctrl1); |
|
// Setup target to be stdout function |
buf.function = _stdout; |
buf.buffer = 0; |
10001a0c: 9c 40 00 00 l.addi r2,r0,0 |
buf.offset = 0; |
buf.max_length = 0; |
|
res = vbuf_printf(&buf, ctrl1, argp); |
10001a10: a8 61 00 00 l.ori r3,r1,0x0 |
10001a14: 9c a1 00 1c l.addi r5,r1,28 |
if (_stdout && ctrl1) |
{ |
va_start( argp, ctrl1); |
|
// Setup target to be stdout function |
buf.function = _stdout; |
10001a18: d4 01 58 00 l.sw 0(r1),r11 |
buf.buffer = 0; |
10001a1c: d4 01 10 04 l.sw 4(r1),r2 |
buf.offset = 0; |
10001a20: d4 01 10 08 l.sw 8(r1),r2 |
buf.max_length = 0; |
10001a24: d4 01 10 0c l.sw 12(r1),r2 |
|
res = vbuf_printf(&buf, ctrl1, argp); |
10001a28: 07 ff fe e8 l.jal 100015c8 <vbuf_printf> |
|
va_end( argp); |
} |
|
return res; |
} |
10001a2c: 9c 21 00 1c l.addi r1,r1,28 |
10001a30: 85 21 ff fc l.lwz r9,-4(r1) |
10001a34: 84 21 ff f4 l.lwz r1,-12(r1) |
10001a38: 84 41 ff f8 l.lwz r2,-8(r1) |
10001a3c: 44 00 48 00 l.jr r9 |
|
10001a40 <serial_init>: |
|
//------------------------------------------------------------- |
// serial_init: |
//------------------------------------------------------------- |
void serial_init (void) |
{ |
10001a40: d7 e1 0f fc l.sw -4(r1),r1 |
10001a44: 9c 21 ff fc l.addi r1,r1,-4 |
|
} |
10001a48: 9c 21 00 04 l.addi r1,r1,4 |
10001a4c: 84 21 ff fc l.lwz r1,-4(r1) |
10001a50: 44 00 48 00 l.jr r9 |
|
10001a54 <serial_putchar>: |
//------------------------------------------------------------- |
// serial_putchar: Write character to Serial Port (used by printf) |
//------------------------------------------------------------- |
int serial_putchar(char ch) |
{ |
10001a54: b8 63 00 18 l.slli r3,r3,0x18 |
10001a58: d7 e1 17 f8 l.sw -8(r1),r2 |
10001a5c: d7 e1 4f fc l.sw -4(r1),r9 |
10001a60: b8 43 00 98 l.srai r2,r3,0x18 |
10001a64: d7 e1 0f f4 l.sw -12(r1),r1 |
10001a68: 9c 21 ff f4 l.addi r1,r1,-12 |
if (ch == '\n') |
10001a6c: bc 22 00 0a l.sfnei r2,10 |
10001a70: 0c 00 00 10 l.bnf 10001ab0 <serial_putchar+0x5c> |
serial_putchar('\r'); |
|
{ |
register char t1 asm ("r3") = ch; |
10001a74: a8 62 00 00 l.ori r3,r2,0x0 |
asm volatile ("\tl.nop\t%0" : : "K" (0x0004), "r" (t1)); |
10001a78: 15 00 00 04 l.nop 0x4 |
} |
|
UART_UDR = ch; |
10001a7c: 18 60 12 00 l.movhi r3,0x1200 |
10001a80: a8 83 00 08 l.ori r4,r3,0x8 |
while (UART_USR & UART_TX_BUSY); |
10001a84: a8 63 00 04 l.ori r3,r3,0x4 |
{ |
register char t1 asm ("r3") = ch; |
asm volatile ("\tl.nop\t%0" : : "K" (0x0004), "r" (t1)); |
} |
|
UART_UDR = ch; |
10001a88: d4 04 10 00 l.sw 0(r4),r2 |
while (UART_USR & UART_TX_BUSY); |
10001a8c: 85 63 00 00 l.lwz r11,0(r3) |
10001a90: a5 6b 00 08 l.andi r11,r11,0x8 |
10001a94: bc 0b 00 00 l.sfeqi r11,0 |
10001a98: 0f ff ff fd l.bnf 10001a8c <serial_putchar+0x38> |
|
return 0; |
} |
10001a9c: 9c 21 00 0c l.addi r1,r1,12 |
10001aa0: 85 21 ff fc l.lwz r9,-4(r1) |
10001aa4: 84 21 ff f4 l.lwz r1,-12(r1) |
10001aa8: 84 41 ff f8 l.lwz r2,-8(r1) |
10001aac: 44 00 48 00 l.jr r9 |
// serial_putchar: Write character to Serial Port (used by printf) |
//------------------------------------------------------------- |
int serial_putchar(char ch) |
{ |
if (ch == '\n') |
serial_putchar('\r'); |
10001ab0: 9c 60 00 0d l.addi r3,r0,13 |
10001ab4: 07 ff ff e8 l.jal 10001a54 <serial_putchar> |
10001ab8: 03 ff ff ef l.j 10001a74 <serial_putchar+0x20> |
|
10001abc <serial_getchar>: |
// serial_haschar: |
//------------------------------------------------------------- |
int serial_haschar() |
{ |
#ifndef USE_NOP_PUTC |
return (UART_USR & UART_RX_AVAIL); |
10001abc: 18 60 12 00 l.movhi r3,0x1200 |
} |
//------------------------------------------------------------- |
// serial_getchar: Read character from Serial Port |
//------------------------------------------------------------- |
int serial_getchar (void) |
{ |
10001ac0: d7 e1 0f fc l.sw -4(r1),r1 |
// serial_haschar: |
//------------------------------------------------------------- |
int serial_haschar() |
{ |
#ifndef USE_NOP_PUTC |
return (UART_USR & UART_RX_AVAIL); |
10001ac4: a8 83 00 04 l.ori r4,r3,0x4 |
} |
//------------------------------------------------------------- |
// serial_getchar: Read character from Serial Port |
//------------------------------------------------------------- |
int serial_getchar (void) |
{ |
10001ac8: 9c 21 ff fc l.addi r1,r1,-4 |
// serial_haschar: |
//------------------------------------------------------------- |
int serial_haschar() |
{ |
#ifndef USE_NOP_PUTC |
return (UART_USR & UART_RX_AVAIL); |
10001acc: 84 84 00 00 l.lwz r4,0(r4) |
10001ad0: a4 84 00 01 l.andi r4,r4,0x1 |
//------------------------------------------------------------- |
int serial_getchar (void) |
{ |
// Read character in from UART0 Recieve Buffer and return |
#ifndef USE_NOP_PUTC |
if (serial_haschar()) |
10001ad4: bc 04 00 00 l.sfeqi r4,0 |
10001ad8: 10 00 00 06 l.bf 10001af0 <serial_getchar+0x34> |
return UART_UDR; |
10001adc: a8 63 00 08 l.ori r3,r3,0x8 |
10001ae0: 85 63 00 00 l.lwz r11,0(r3) |
else |
#endif |
return -1; |
} |
10001ae4: 9c 21 00 04 l.addi r1,r1,4 |
10001ae8: 84 21 ff fc l.lwz r1,-4(r1) |
10001aec: 44 00 48 00 l.jr r9 |
#ifndef USE_NOP_PUTC |
if (serial_haschar()) |
return UART_UDR; |
else |
#endif |
return -1; |
10001af0: 9d 60 ff ff l.addi r11,r0,-1 |
10001af4: 03 ff ff fc l.j 10001ae4 <serial_getchar+0x28> |
|
10001af8 <serial_haschar>: |
// serial_haschar: |
//------------------------------------------------------------- |
int serial_haschar() |
{ |
#ifndef USE_NOP_PUTC |
return (UART_USR & UART_RX_AVAIL); |
10001af8: 18 60 12 00 l.movhi r3,0x1200 |
} |
//------------------------------------------------------------- |
// serial_haschar: |
//------------------------------------------------------------- |
int serial_haschar() |
{ |
10001afc: d7 e1 0f fc l.sw -4(r1),r1 |
#ifndef USE_NOP_PUTC |
return (UART_USR & UART_RX_AVAIL); |
10001b00: a8 63 00 04 l.ori r3,r3,0x4 |
} |
//------------------------------------------------------------- |
// serial_haschar: |
//------------------------------------------------------------- |
int serial_haschar() |
{ |
10001b04: 9c 21 ff fc l.addi r1,r1,-4 |
#ifndef USE_NOP_PUTC |
return (UART_USR & UART_RX_AVAIL); |
10001b08: 85 63 00 00 l.lwz r11,0(r3) |
#else |
return 0; |
#endif |
} |
10001b0c: 9c 21 00 04 l.addi r1,r1,4 |
10001b10: a5 6b 00 01 l.andi r11,r11,0x1 |
10001b14: 84 21 ff fc l.lwz r1,-4(r1) |
10001b18: 44 00 48 00 l.jr r9 |
|
10001b1c <serial_putstr>: |
//------------------------------------------------------------- |
// serial_putstr: |
//------------------------------------------------------------- |
void serial_putstr(char *str) |
{ |
10001b1c: d7 e1 17 f8 l.sw -8(r1),r2 |
10001b20: d7 e1 4f fc l.sw -4(r1),r9 |
10001b24: d7 e1 0f f4 l.sw -12(r1),r1 |
10001b28: a8 43 00 00 l.ori r2,r3,0x0 |
while (*str) |
10001b2c: 90 63 00 00 l.lbs r3,0(r3) |
10001b30: bc 23 00 00 l.sfnei r3,0 |
} |
//------------------------------------------------------------- |
// serial_putstr: |
//------------------------------------------------------------- |
void serial_putstr(char *str) |
{ |
10001b34: 9c 21 ff f4 l.addi r1,r1,-12 |
while (*str) |
10001b38: 0c 00 00 06 l.bnf 10001b50 <serial_putstr+0x34> |
serial_putchar(*str++); |
10001b3c: 9c 42 00 01 l.addi r2,r2,1 |
10001b40: 07 ff ff c5 l.jal 10001a54 <serial_putchar> |
//------------------------------------------------------------- |
// serial_putstr: |
//------------------------------------------------------------- |
void serial_putstr(char *str) |
{ |
while (*str) |
10001b44: 90 62 00 00 l.lbs r3,0(r2) |
10001b48: bc 03 00 00 l.sfeqi r3,0 |
10001b4c: 0f ff ff fc l.bnf 10001b3c <serial_putstr+0x20> |
serial_putchar(*str++); |
} |
10001b50: 9c 21 00 0c l.addi r1,r1,12 |
10001b54: 85 21 ff fc l.lwz r9,-4(r1) |
10001b58: 84 21 ff f4 l.lwz r1,-12(r1) |
10001b5c: 84 41 ff f8 l.lwz r2,-8(r1) |
10001b60: 44 00 48 00 l.jr r9 |
|
10001b64 <serial_putnum>: |
//------------------------------------------------------------- |
// serial_putnum: |
//------------------------------------------------------------- |
void serial_putnum( int n ) |
{ |
10001b64: d7 e1 17 e8 l.sw -24(r1),r2 |
char* cp; |
int negative; |
char outbuf[32]; |
const char digits[] = "0123456789ABCDEF"; |
10001b68: 18 40 30 31 l.movhi r2,0x3031 |
} |
//------------------------------------------------------------- |
// serial_putnum: |
//------------------------------------------------------------- |
void serial_putnum( int n ) |
{ |
10001b6c: d7 e1 4f fc l.sw -4(r1),r9 |
char* cp; |
int negative; |
char outbuf[32]; |
const char digits[] = "0123456789ABCDEF"; |
10001b70: a8 42 32 33 l.ori r2,r2,0x3233 |
} |
//------------------------------------------------------------- |
// serial_putnum: |
//------------------------------------------------------------- |
void serial_putnum( int n ) |
{ |
10001b74: d7 e1 0f e4 l.sw -28(r1),r1 |
10001b78: d7 e1 77 ec l.sw -20(r1),r14 |
10001b7c: d7 e1 97 f0 l.sw -16(r1),r18 |
10001b80: d7 e1 a7 f4 l.sw -12(r1),r20 |
10001b84: d7 e1 b7 f8 l.sw -8(r1),r22 |
10001b88: 9c 21 ff b0 l.addi r1,r1,-80 |
char outbuf[32]; |
const char digits[] = "0123456789ABCDEF"; |
unsigned long num; |
|
/* Check if number is negative */ |
if (n < 0L) { |
10001b8c: bd 63 00 00 l.sfgesi r3,0 |
void serial_putnum( int n ) |
{ |
char* cp; |
int negative; |
char outbuf[32]; |
const char digits[] = "0123456789ABCDEF"; |
10001b90: d4 01 10 00 l.sw 0(r1),r2 |
10001b94: 18 40 34 35 l.movhi r2,0x3435 |
10001b98: a8 42 36 37 l.ori r2,r2,0x3637 |
10001b9c: d4 01 10 04 l.sw 4(r1),r2 |
10001ba0: 18 40 38 39 l.movhi r2,0x3839 |
10001ba4: a8 42 41 42 l.ori r2,r2,0x4142 |
10001ba8: d4 01 10 08 l.sw 8(r1),r2 |
10001bac: 18 40 43 44 l.movhi r2,0x4344 |
10001bb0: a8 42 45 46 l.ori r2,r2,0x4546 |
10001bb4: d4 01 10 0c l.sw 12(r1),r2 |
10001bb8: 9c 40 00 00 l.addi r2,r0,0 |
10001bbc: d8 01 10 10 l.sb 16(r1),r2 |
unsigned long num; |
|
/* Check if number is negative */ |
if (n < 0L) { |
10001bc0: 0c 00 00 2e l.bnf 10001c78 <serial_putnum+0x114> |
negative = 1; |
num = -(n); |
} |
else{ |
num = (n); |
10001bc4: a8 43 00 00 l.ori r2,r3,0x0 |
negative = 0; |
10001bc8: 9e c0 00 00 l.addi r22,r0,0 |
10001bcc: 9e 81 00 14 l.addi r20,r1,20 |
10001bd0: a9 d4 00 00 l.ori r14,r20,0x0 |
10001bd4: 00 00 00 02 l.j 10001bdc <serial_putnum+0x78> |
10001bd8: a9 d2 00 00 l.ori r14,r18,0x0 |
} |
|
/* Build number (backwards) in outbuf */ |
cp = outbuf; |
do { |
*cp++ = digits[(int)(num % 10)]; |
10001bdc: a8 62 00 00 l.ori r3,r2,0x0 |
10001be0: 9c 80 00 0a l.addi r4,r0,10 |
serial_putchar(*str++); |
} |
//------------------------------------------------------------- |
// serial_putnum: |
//------------------------------------------------------------- |
void serial_putnum( int n ) |
10001be4: 9e 4e 00 01 l.addi r18,r14,1 |
} |
|
/* Build number (backwards) in outbuf */ |
cp = outbuf; |
do { |
*cp++ = digits[(int)(num % 10)]; |
10001be8: 04 00 03 4e l.jal 10002920 <__umodsi3> |
10001bec: 9c 61 00 00 l.addi r3,r1,0 |
} while ((num /= 10) > 0); |
10001bf0: 9c 80 00 0a l.addi r4,r0,10 |
} |
|
/* Build number (backwards) in outbuf */ |
cp = outbuf; |
do { |
*cp++ = digits[(int)(num % 10)]; |
10001bf4: e1 63 58 00 l.add r11,r3,r11 |
} while ((num /= 10) > 0); |
10001bf8: a8 62 00 00 l.ori r3,r2,0x0 |
} |
|
/* Build number (backwards) in outbuf */ |
cp = outbuf; |
do { |
*cp++ = digits[(int)(num % 10)]; |
10001bfc: 8d 6b 00 00 l.lbz r11,0(r11) |
10001c00: d8 0e 58 00 l.sb 0(r14),r11 |
} while ((num /= 10) > 0); |
10001c04: 04 00 03 3e l.jal 100028fc <__udivsi3> |
10001c08: bc 0b 00 00 l.sfeqi r11,0 |
10001c0c: a8 4b 00 00 l.ori r2,r11,0x0 |
10001c10: 0f ff ff f2 l.bnf 10001bd8 <serial_putnum+0x74> |
if (negative) |
10001c14: bc 16 00 00 l.sfeqi r22,0 |
10001c18: 10 00 00 04 l.bf 10001c28 <serial_putnum+0xc4> |
*cp++ = '-'; |
10001c1c: 9c 40 00 2d l.addi r2,r0,45 |
10001c20: 9e 4e 00 02 l.addi r18,r14,2 |
10001c24: d8 0e 10 01 l.sb 1(r14),r2 |
*cp-- = 0; |
10001c28: 9c 52 ff ff l.addi r2,r18,-1 |
10001c2c: 9c 60 00 00 l.addi r3,r0,0 |
|
while (cp >= outbuf) |
10001c30: e4 62 a0 00 l.sfgeu r2,r20 |
do { |
*cp++ = digits[(int)(num % 10)]; |
} while ((num /= 10) > 0); |
if (negative) |
*cp++ = '-'; |
*cp-- = 0; |
10001c34: d8 12 18 00 l.sb 0(r18),r3 |
|
while (cp >= outbuf) |
10001c38: 0c 00 00 07 l.bnf 10001c54 <serial_putnum+0xf0> |
serial_putchar(*str++); |
} |
//------------------------------------------------------------- |
// serial_putnum: |
//------------------------------------------------------------- |
void serial_putnum( int n ) |
10001c3c: 9d d4 ff ff l.addi r14,r20,-1 |
if (negative) |
*cp++ = '-'; |
*cp-- = 0; |
|
while (cp >= outbuf) |
serial_putchar(*cp--); |
10001c40: 90 62 00 00 l.lbs r3,0(r2) |
10001c44: 9c 42 ff ff l.addi r2,r2,-1 |
10001c48: 07 ff ff 83 l.jal 10001a54 <serial_putchar> |
} while ((num /= 10) > 0); |
if (negative) |
*cp++ = '-'; |
*cp-- = 0; |
|
while (cp >= outbuf) |
10001c4c: e4 02 70 00 l.sfeq r2,r14 |
10001c50: 0f ff ff fc l.bnf 10001c40 <serial_putnum+0xdc> |
serial_putchar(*cp--); |
} |
10001c54: 9c 21 00 50 l.addi r1,r1,80 |
10001c58: 85 21 ff fc l.lwz r9,-4(r1) |
10001c5c: 84 21 ff e4 l.lwz r1,-28(r1) |
10001c60: 84 41 ff e8 l.lwz r2,-24(r1) |
10001c64: 85 c1 ff ec l.lwz r14,-20(r1) |
10001c68: 86 41 ff f0 l.lwz r18,-16(r1) |
10001c6c: 86 81 ff f4 l.lwz r20,-12(r1) |
10001c70: 86 c1 ff f8 l.lwz r22,-8(r1) |
10001c74: 44 00 48 00 l.jr r9 |
unsigned long num; |
|
/* Check if number is negative */ |
if (n < 0L) { |
negative = 1; |
num = -(n); |
10001c78: e0 40 18 02 l.sub r2,r0,r3 |
const char digits[] = "0123456789ABCDEF"; |
unsigned long num; |
|
/* Check if number is negative */ |
if (n < 0L) { |
negative = 1; |
10001c7c: 9e c0 00 01 l.addi r22,r0,1 |
10001c80: 03 ff ff d3 l.j 10001bcc <serial_putnum+0x68> |
|
10001c84 <timer_init>: |
|
//-------------------------------------------------------------------------- |
// timer_init: |
//-------------------------------------------------------------------------- |
void timer_init(void) |
{ |
10001c84: d7 e1 0f fc l.sw -4(r1),r1 |
10001c88: 9c 21 ff fc l.addi r1,r1,-4 |
|
} |
10001c8c: 9c 21 00 04 l.addi r1,r1,4 |
10001c90: 84 21 ff fc l.lwz r1,-4(r1) |
10001c94: 44 00 48 00 l.jr r9 |
|
10001c98 <timer_sleep>: |
// Prototypes: |
//----------------------------------------------------------------- |
|
// General timer |
void timer_init(void); |
static t_time timer_now(void) { return TIMER_VAL; } |
10001c98: 18 a0 12 00 l.movhi r5,0x1200 |
//-------------------------------------------------------------------------- |
// timer_sleep: |
//-------------------------------------------------------------------------- |
void timer_sleep(int timeMs) |
{ |
10001c9c: d7 e1 0f fc l.sw -4(r1),r1 |
10001ca0: a8 a5 01 00 l.ori r5,r5,0x100 |
10001ca4: 9c 21 ff fc l.addi r1,r1,-4 |
10001ca8: 84 c5 00 00 l.lwz r6,0(r5) |
10001cac: 84 85 00 00 l.lwz r4,0(r5) |
static long timer_diff(t_time a, t_time b) { return (long)(a - b); } |
10001cb0: e0 84 30 02 l.sub r4,r4,r6 |
t_time t = timer_now(); |
|
while (timer_diff(timer_now(), t) < timeMs) |
10001cb4: e5 a3 20 00 l.sfles r3,r4 |
10001cb8: 0f ff ff fd l.bnf 10001cac <timer_sleep+0x14> |
; |
} |
10001cbc: 9c 21 00 04 l.addi r1,r1,4 |
10001cc0: 84 21 ff fc l.lwz r1,-4(r1) |
10001cc4: 44 00 48 00 l.jr r9 |
|
10001cc8 <empty_syscall>: |
volatile int syscall_done = 0; |
|
//----------------------------------------------------------------- |
// Syscall handling: |
//----------------------------------------------------------------- |
void empty_syscall(void) { syscall_done = 1; } |
10001cc8: 18 60 10 00 l.movhi r3,0x1000 |
10001ccc: 9c 80 00 01 l.addi r4,r0,1 |
10001cd0: a8 63 2f f8 l.ori r3,r3,0x2ff8 |
10001cd4: d7 e1 0f fc l.sw -4(r1),r1 |
10001cd8: 9c 21 ff fc l.addi r1,r1,-4 |
10001cdc: d4 03 20 00 l.sw 0(r3),r4 |
10001ce0: 9c 21 00 04 l.addi r1,r1,4 |
10001ce4: 84 21 ff fc l.lwz r1,-4(r1) |
10001ce8: 44 00 48 00 l.jr r9 |
|
10001cec <test>: |
unsigned short sw; |
unsigned short *psw; |
unsigned char sb; |
unsigned char *psb; |
|
serial_putstr("\nTest:\n"); |
10001cec: 18 60 10 00 l.movhi r3,0x1000 |
|
//----------------------------------------------------------------- |
// main: |
//----------------------------------------------------------------- |
int test(void) |
{ |
10001cf0: d7 e1 4f fc l.sw -4(r1),r9 |
10001cf4: d7 e1 17 f0 l.sw -16(r1),r2 |
10001cf8: d7 e1 0f ec l.sw -20(r1),r1 |
10001cfc: d7 e1 77 f4 l.sw -12(r1),r14 |
10001d00: d7 e1 97 f8 l.sw -8(r1),r18 |
unsigned short sw; |
unsigned short *psw; |
unsigned char sb; |
unsigned char *psb; |
|
serial_putstr("\nTest:\n"); |
10001d04: a8 63 2d 09 l.ori r3,r3,0x2d09 |
|
//----------------------------------------------------------------- |
// main: |
//----------------------------------------------------------------- |
int test(void) |
{ |
10001d08: 9c 21 ff e0 l.addi r1,r1,-32 |
|
// Assign empty syscall handler |
exception_register_syscall_handler(empty_syscall); |
|
serial_putstr("1. Initialised data\n"); |
assert(var == 0x1234); // .text |
10001d0c: 18 40 10 00 l.movhi r2,0x1000 |
unsigned short sw; |
unsigned short *psw; |
unsigned char sb; |
unsigned char *psb; |
|
serial_putstr("\nTest:\n"); |
10001d10: 07 ff ff 83 l.jal 10001b1c <serial_putstr> |
|
// Adjust ISR vector to match this app's vector offset |
asm_set_isr_vector(asm_save_context); |
|
// Assign empty syscall handler |
exception_register_syscall_handler(empty_syscall); |
10001d14: 18 60 10 00 l.movhi r3,0x1000 |
|
serial_putstr("1. Initialised data\n"); |
assert(var == 0x1234); // .text |
10001d18: a8 42 2f d8 l.ori r2,r2,0x2fd8 |
|
// Adjust ISR vector to match this app's vector offset |
asm_set_isr_vector(asm_save_context); |
|
// Assign empty syscall handler |
exception_register_syscall_handler(empty_syscall); |
10001d1c: a8 63 1c c8 l.ori r3,r3,0x1cc8 |
10001d20: 07 ff fc e2 l.jal 100010a8 <exception_register_syscall_handler> |
|
serial_putstr("1. Initialised data\n"); |
10001d24: 18 60 10 00 l.movhi r3,0x1000 |
10001d28: a8 63 2d 11 l.ori r3,r3,0x2d11 |
10001d2c: 07 ff ff 7c l.jal 10001b1c <serial_putstr> |
assert(var == 0x1234); // .text |
10001d30: 84 62 00 00 l.lwz r3,0(r2) |
10001d34: bc 03 12 34 l.sfeqi r3,4660 |
10001d38: 10 00 00 0e l.bf 10001d70 <test+0x84> |
10001d3c: 18 60 10 00 l.movhi r3,0x1000 |
10001d40: a8 63 2d 26 l.ori r3,r3,0x2d26 |
10001d44: d4 01 18 00 l.sw 0(r1),r3 |
10001d48: 18 60 10 00 l.movhi r3,0x1000 |
10001d4c: a8 63 2d 34 l.ori r3,r3,0x2d34 |
10001d50: d4 01 18 04 l.sw 4(r1),r3 |
10001d54: 9c 60 00 29 l.addi r3,r0,41 |
10001d58: d4 01 18 08 l.sw 8(r1),r3 |
10001d5c: 18 60 10 00 l.movhi r3,0x1000 |
10001d60: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10001d64: 07 ff ff 20 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10001d68: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10001d6c: c8 00 00 00 lf.add.s r0,r0,r0 |
assert(uvar == 0x0); // .bss |
10001d70: 19 c0 10 00 l.movhi r14,0x1000 |
10001d74: a9 ce 30 04 l.ori r14,r14,0x3004 |
10001d78: 84 6e 00 00 l.lwz r3,0(r14) |
10001d7c: bc 03 00 00 l.sfeqi r3,0 |
10001d80: 0c 00 02 d1 l.bnf 100028c4 <test+0xbd8> |
|
serial_putstr("2. Multiply\n"); |
10001d84: 18 60 10 00 l.movhi r3,0x1000 |
10001d88: a8 63 2d 47 l.ori r3,r3,0x2d47 |
10001d8c: 07 ff ff 64 l.jal 10001b1c <serial_putstr> |
var = var * 3; |
10001d90: 84 62 00 00 l.lwz r3,0(r2) |
10001d94: e0 83 18 00 l.add r4,r3,r3 |
10001d98: e0 64 18 00 l.add r3,r4,r3 |
10001d9c: d4 02 18 00 l.sw 0(r2),r3 |
assert(var == 13980); |
10001da0: 84 62 00 00 l.lwz r3,0(r2) |
10001da4: bc 03 36 9c l.sfeqi r3,13980 |
10001da8: 10 00 00 0e l.bf 10001de0 <test+0xf4> |
10001dac: 18 60 10 00 l.movhi r3,0x1000 |
10001db0: a8 63 2d 54 l.ori r3,r3,0x2d54 |
10001db4: d4 01 18 00 l.sw 0(r1),r3 |
10001db8: 18 60 10 00 l.movhi r3,0x1000 |
10001dbc: a8 63 2d 34 l.ori r3,r3,0x2d34 |
10001dc0: d4 01 18 04 l.sw 4(r1),r3 |
10001dc4: 9c 60 00 2e l.addi r3,r0,46 |
10001dc8: d4 01 18 08 l.sw 8(r1),r3 |
10001dcc: 18 60 10 00 l.movhi r3,0x1000 |
10001dd0: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10001dd4: 07 ff ff 04 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10001dd8: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10001ddc: c8 00 00 00 lf.add.s r0,r0,r0 |
var = -1; |
10001de0: 9c 60 ff ff l.addi r3,r0,-1 |
10001de4: d4 02 18 00 l.sw 0(r2),r3 |
var = var * 3; |
10001de8: 84 62 00 00 l.lwz r3,0(r2) |
10001dec: e0 83 18 00 l.add r4,r3,r3 |
10001df0: e0 64 18 00 l.add r3,r4,r3 |
10001df4: d4 02 18 00 l.sw 0(r2),r3 |
assert(var == -3); |
10001df8: 84 62 00 00 l.lwz r3,0(r2) |
10001dfc: bc 03 ff fd l.sfeqi r3,-3 |
10001e00: 10 00 00 0e l.bf 10001e38 <test+0x14c> |
10001e04: 18 60 10 00 l.movhi r3,0x1000 |
10001e08: a8 63 2d 61 l.ori r3,r3,0x2d61 |
10001e0c: d4 01 18 00 l.sw 0(r1),r3 |
10001e10: 18 60 10 00 l.movhi r3,0x1000 |
10001e14: a8 63 2d 34 l.ori r3,r3,0x2d34 |
10001e18: d4 01 18 04 l.sw 4(r1),r3 |
10001e1c: 9c 60 00 31 l.addi r3,r0,49 |
10001e20: d4 01 18 08 l.sw 8(r1),r3 |
10001e24: 18 60 10 00 l.movhi r3,0x1000 |
10001e28: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10001e2c: 07 ff fe ee l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10001e30: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10001e34: c8 00 00 00 lf.add.s r0,r0,r0 |
var = -5; |
10001e38: 9c 60 ff fb l.addi r3,r0,-5 |
10001e3c: d4 02 18 00 l.sw 0(r2),r3 |
var = var * 13; |
10001e40: 84 62 00 00 l.lwz r3,0(r2) |
10001e44: e0 83 18 00 l.add r4,r3,r3 |
10001e48: e0 84 18 00 l.add r4,r4,r3 |
10001e4c: b8 84 00 02 l.slli r4,r4,0x2 |
10001e50: e0 64 18 00 l.add r3,r4,r3 |
10001e54: d4 02 18 00 l.sw 0(r2),r3 |
assert(var == -65); |
10001e58: 84 62 00 00 l.lwz r3,0(r2) |
10001e5c: bc 03 ff bf l.sfeqi r3,-65 |
10001e60: 10 00 00 0e l.bf 10001e98 <test+0x1ac> |
10001e64: 18 60 10 00 l.movhi r3,0x1000 |
10001e68: a8 63 2d 6b l.ori r3,r3,0x2d6b |
10001e6c: d4 01 18 00 l.sw 0(r1),r3 |
10001e70: 18 60 10 00 l.movhi r3,0x1000 |
10001e74: a8 63 2d 34 l.ori r3,r3,0x2d34 |
10001e78: d4 01 18 04 l.sw 4(r1),r3 |
10001e7c: 9c 60 00 34 l.addi r3,r0,52 |
10001e80: d4 01 18 08 l.sw 8(r1),r3 |
10001e84: 18 60 10 00 l.movhi r3,0x1000 |
10001e88: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10001e8c: 07 ff fe d6 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10001e90: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10001e94: c8 00 00 00 lf.add.s r0,r0,r0 |
var = -5; |
10001e98: 9c 60 ff fb l.addi r3,r0,-5 |
var = var * -13; |
10001e9c: 9c 80 ff f3 l.addi r4,r0,-13 |
var = var * 3; |
assert(var == -3); |
var = -5; |
var = var * 13; |
assert(var == -65); |
var = -5; |
10001ea0: d4 02 18 00 l.sw 0(r2),r3 |
var = var * -13; |
10001ea4: 84 62 00 00 l.lwz r3,0(r2) |
10001ea8: 04 00 03 04 l.jal 10002ab8 <__mulsi3> |
10001eac: d4 02 58 00 l.sw 0(r2),r11 |
assert(var == (-5*-13)); |
10001eb0: 84 62 00 00 l.lwz r3,0(r2) |
10001eb4: bc 03 00 41 l.sfeqi r3,65 |
10001eb8: 10 00 00 0e l.bf 10001ef0 <test+0x204> |
10001ebc: 18 60 10 00 l.movhi r3,0x1000 |
10001ec0: a8 63 2d 76 l.ori r3,r3,0x2d76 |
10001ec4: d4 01 18 00 l.sw 0(r1),r3 |
10001ec8: 18 60 10 00 l.movhi r3,0x1000 |
10001ecc: a8 63 2d 34 l.ori r3,r3,0x2d34 |
10001ed0: d4 01 18 04 l.sw 4(r1),r3 |
10001ed4: 9c 60 00 37 l.addi r3,r0,55 |
10001ed8: d4 01 18 08 l.sw 8(r1),r3 |
10001edc: 18 60 10 00 l.movhi r3,0x1000 |
10001ee0: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10001ee4: 07 ff fe c0 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10001ee8: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10001eec: c8 00 00 00 lf.add.s r0,r0,r0 |
var = -123123415; |
10001ef0: 18 60 f8 a9 l.movhi r3,0xf8a9 |
var = var * 9664563; |
10001ef4: 18 80 00 93 l.movhi r4,0x93 |
var = var * 13; |
assert(var == -65); |
var = -5; |
var = var * -13; |
assert(var == (-5*-13)); |
var = -123123415; |
10001ef8: a8 63 49 29 l.ori r3,r3,0x4929 |
var = var * 9664563; |
10001efc: a8 84 78 33 l.ori r4,r4,0x7833 |
var = var * 13; |
assert(var == -65); |
var = -5; |
var = var * -13; |
assert(var == (-5*-13)); |
var = -123123415; |
10001f00: d4 02 18 00 l.sw 0(r2),r3 |
var = var * 9664563; |
10001f04: 84 62 00 00 l.lwz r3,0(r2) |
10001f08: 04 00 02 ec l.jal 10002ab8 <__mulsi3> |
assert(var == (-123123415*9664563)); |
10001f0c: 18 80 e6 8f l.movhi r4,0xe68f |
assert(var == -65); |
var = -5; |
var = var * -13; |
assert(var == (-5*-13)); |
var = -123123415; |
var = var * 9664563; |
10001f10: d4 02 58 00 l.sw 0(r2),r11 |
assert(var == (-123123415*9664563)); |
10001f14: a8 84 cb 2b l.ori r4,r4,0xcb2b |
10001f18: 84 62 00 00 l.lwz r3,0(r2) |
10001f1c: e4 03 20 00 l.sfeq r3,r4 |
10001f20: 10 00 00 0e l.bf 10001f58 <test+0x26c> |
10001f24: 18 60 10 00 l.movhi r3,0x1000 |
10001f28: a8 63 2d 86 l.ori r3,r3,0x2d86 |
10001f2c: d4 01 18 00 l.sw 0(r1),r3 |
10001f30: 18 60 10 00 l.movhi r3,0x1000 |
10001f34: a8 63 2d 34 l.ori r3,r3,0x2d34 |
10001f38: d4 01 18 04 l.sw 4(r1),r3 |
10001f3c: 9c 60 00 3a l.addi r3,r0,58 |
10001f40: d4 01 18 08 l.sw 8(r1),r3 |
10001f44: 18 60 10 00 l.movhi r3,0x1000 |
10001f48: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10001f4c: 07 ff fe a6 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10001f50: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10001f54: c8 00 00 00 lf.add.s r0,r0,r0 |
|
serial_putstr("3. Divide\n"); |
10001f58: 18 60 10 00 l.movhi r3,0x1000 |
10001f5c: a8 63 2d a2 l.ori r3,r3,0x2da2 |
10001f60: 07 ff fe ef l.jal 10001b1c <serial_putstr> |
var = 13980; |
10001f64: 9c 60 36 9c l.addi r3,r0,13980 |
var = var / 5; |
10001f68: 9c 80 00 05 l.addi r4,r0,5 |
var = -123123415; |
var = var * 9664563; |
assert(var == (-123123415*9664563)); |
|
serial_putstr("3. Divide\n"); |
var = 13980; |
10001f6c: d4 02 18 00 l.sw 0(r2),r3 |
var = var / 5; |
10001f70: 84 62 00 00 l.lwz r3,0(r2) |
10001f74: 04 00 02 74 l.jal 10002944 <__divsi3> |
10001f78: d4 02 58 00 l.sw 0(r2),r11 |
assert(var == 2796); |
10001f7c: 84 62 00 00 l.lwz r3,0(r2) |
10001f80: bc 03 0a ec l.sfeqi r3,2796 |
10001f84: 10 00 00 0e l.bf 10001fbc <test+0x2d0> |
10001f88: 18 60 10 00 l.movhi r3,0x1000 |
10001f8c: a8 63 2d ad l.ori r3,r3,0x2dad |
10001f90: d4 01 18 00 l.sw 0(r1),r3 |
10001f94: 18 60 10 00 l.movhi r3,0x1000 |
10001f98: a8 63 2d 34 l.ori r3,r3,0x2d34 |
10001f9c: d4 01 18 04 l.sw 4(r1),r3 |
10001fa0: 9c 60 00 3f l.addi r3,r0,63 |
10001fa4: d4 01 18 08 l.sw 8(r1),r3 |
10001fa8: 18 60 10 00 l.movhi r3,0x1000 |
10001fac: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10001fb0: 07 ff fe 8d l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10001fb4: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10001fb8: c8 00 00 00 lf.add.s r0,r0,r0 |
var = var % 100; |
10001fbc: 84 62 00 00 l.lwz r3,0(r2) |
10001fc0: 9c 80 00 64 l.addi r4,r0,100 |
10001fc4: 04 00 02 7a l.jal 100029ac <__modsi3> |
10001fc8: d4 02 58 00 l.sw 0(r2),r11 |
assert(var == 96); |
10001fcc: 84 62 00 00 l.lwz r3,0(r2) |
10001fd0: bc 03 00 60 l.sfeqi r3,96 |
10001fd4: 10 00 00 0e l.bf 1000200c <test+0x320> |
10001fd8: 18 60 10 00 l.movhi r3,0x1000 |
10001fdc: a8 63 2d b9 l.ori r3,r3,0x2db9 |
10001fe0: d4 01 18 00 l.sw 0(r1),r3 |
10001fe4: 18 60 10 00 l.movhi r3,0x1000 |
10001fe8: a8 63 2d 34 l.ori r3,r3,0x2d34 |
10001fec: d4 01 18 04 l.sw 4(r1),r3 |
10001ff0: 9c 60 00 41 l.addi r3,r0,65 |
10001ff4: d4 01 18 08 l.sw 8(r1),r3 |
10001ff8: 18 60 10 00 l.movhi r3,0x1000 |
10001ffc: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10002000: 07 ff fe 79 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10002004: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10002008: c8 00 00 00 lf.add.s r0,r0,r0 |
var = -1273; |
1000200c: 9c 60 fb 07 l.addi r3,r0,-1273 |
var = var / 19; |
10002010: 9c 80 00 13 l.addi r4,r0,19 |
var = 13980; |
var = var / 5; |
assert(var == 2796); |
var = var % 100; |
assert(var == 96); |
var = -1273; |
10002014: d4 02 18 00 l.sw 0(r2),r3 |
var = var / 19; |
10002018: 84 62 00 00 l.lwz r3,0(r2) |
1000201c: 04 00 02 4a l.jal 10002944 <__divsi3> |
10002020: d4 02 58 00 l.sw 0(r2),r11 |
assert(var == -67); |
10002024: 84 62 00 00 l.lwz r3,0(r2) |
10002028: bc 03 ff bd l.sfeqi r3,-67 |
1000202c: 10 00 00 0e l.bf 10002064 <test+0x378> |
10002030: 18 60 10 00 l.movhi r3,0x1000 |
10002034: a8 63 2d c3 l.ori r3,r3,0x2dc3 |
10002038: d4 01 18 00 l.sw 0(r1),r3 |
1000203c: 18 60 10 00 l.movhi r3,0x1000 |
10002040: a8 63 2d 34 l.ori r3,r3,0x2d34 |
10002044: d4 01 18 04 l.sw 4(r1),r3 |
10002048: 9c 60 00 44 l.addi r3,r0,68 |
1000204c: d4 01 18 08 l.sw 8(r1),r3 |
10002050: 18 60 10 00 l.movhi r3,0x1000 |
10002054: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10002058: 07 ff fe 63 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
1000205c: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10002060: c8 00 00 00 lf.add.s r0,r0,r0 |
|
serial_putstr("4. Shift left\n"); |
10002064: 18 60 10 00 l.movhi r3,0x1000 |
var = 0x1; |
10002068: 9e 40 00 01 l.addi r18,r0,1 |
assert(var == 96); |
var = -1273; |
var = var / 19; |
assert(var == -67); |
|
serial_putstr("4. Shift left\n"); |
1000206c: a8 63 2d ce l.ori r3,r3,0x2dce |
10002070: 07 ff fe ab l.jal 10001b1c <serial_putstr> |
var = 0x1; |
10002074: d4 02 90 00 l.sw 0(r2),r18 |
var <<= 31; |
assert(var == 0x80000000); |
10002078: 18 80 80 00 l.movhi r4,0x8000 |
var = var / 19; |
assert(var == -67); |
|
serial_putstr("4. Shift left\n"); |
var = 0x1; |
var <<= 31; |
1000207c: 84 62 00 00 l.lwz r3,0(r2) |
10002080: b8 63 00 1f l.slli r3,r3,0x1f |
10002084: d4 02 18 00 l.sw 0(r2),r3 |
assert(var == 0x80000000); |
10002088: 84 62 00 00 l.lwz r3,0(r2) |
1000208c: e4 03 20 00 l.sfeq r3,r4 |
10002090: 10 00 00 0e l.bf 100020c8 <test+0x3dc> |
10002094: 18 60 10 00 l.movhi r3,0x1000 |
10002098: a8 63 2d dd l.ori r3,r3,0x2ddd |
1000209c: d4 01 18 00 l.sw 0(r1),r3 |
100020a0: 18 60 10 00 l.movhi r3,0x1000 |
100020a4: a8 63 2d 34 l.ori r3,r3,0x2d34 |
100020a8: d4 01 18 04 l.sw 4(r1),r3 |
100020ac: 9c 60 00 49 l.addi r3,r0,73 |
100020b0: d4 01 18 08 l.sw 8(r1),r3 |
100020b4: 18 60 10 00 l.movhi r3,0x1000 |
100020b8: a8 63 2c 74 l.ori r3,r3,0x2c74 |
100020bc: 07 ff fe 4a l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
100020c0: a8 32 00 00 l.ori r1,r18,0x0 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
100020c4: c8 00 00 00 lf.add.s r0,r0,r0 |
|
serial_putstr("5. Shift right\n"); |
100020c8: 18 60 10 00 l.movhi r3,0x1000 |
100020cc: a8 63 2d ef l.ori r3,r3,0x2def |
100020d0: 07 ff fe 93 l.jal 10001b1c <serial_putstr> |
uvar = 0x80000000; |
100020d4: 18 60 80 00 l.movhi r3,0x8000 |
uvar >>= 1; |
assert(uvar == 0x40000000); |
100020d8: 18 80 40 00 l.movhi r4,0x4000 |
var = 0x1; |
var <<= 31; |
assert(var == 0x80000000); |
|
serial_putstr("5. Shift right\n"); |
uvar = 0x80000000; |
100020dc: d4 0e 18 00 l.sw 0(r14),r3 |
uvar >>= 1; |
100020e0: 84 6e 00 00 l.lwz r3,0(r14) |
100020e4: b8 63 00 41 l.srli r3,r3,0x1 |
100020e8: d4 0e 18 00 l.sw 0(r14),r3 |
assert(uvar == 0x40000000); |
100020ec: 84 6e 00 00 l.lwz r3,0(r14) |
100020f0: e4 03 20 00 l.sfeq r3,r4 |
100020f4: 10 00 00 0e l.bf 1000212c <test+0x440> |
100020f8: 18 60 10 00 l.movhi r3,0x1000 |
100020fc: a8 63 2d ff l.ori r3,r3,0x2dff |
10002100: d4 01 18 00 l.sw 0(r1),r3 |
10002104: 18 60 10 00 l.movhi r3,0x1000 |
10002108: a8 63 2d 34 l.ori r3,r3,0x2d34 |
1000210c: d4 01 18 04 l.sw 4(r1),r3 |
10002110: 9c 60 00 4e l.addi r3,r0,78 |
10002114: d4 01 18 08 l.sw 8(r1),r3 |
10002118: 18 60 10 00 l.movhi r3,0x1000 |
1000211c: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10002120: 07 ff fe 31 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10002124: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10002128: c8 00 00 00 lf.add.s r0,r0,r0 |
uvar >>= 30; |
1000212c: 84 6e 00 00 l.lwz r3,0(r14) |
10002130: b8 63 00 5e l.srli r3,r3,0x1e |
10002134: d4 0e 18 00 l.sw 0(r14),r3 |
assert(uvar == 0x00000001); |
10002138: 84 6e 00 00 l.lwz r3,0(r14) |
1000213c: bc 03 00 01 l.sfeqi r3,1 |
10002140: 10 00 00 0e l.bf 10002178 <test+0x48c> |
10002144: 18 60 10 00 l.movhi r3,0x1000 |
10002148: a8 63 2e 12 l.ori r3,r3,0x2e12 |
1000214c: d4 01 18 00 l.sw 0(r1),r3 |
10002150: 18 60 10 00 l.movhi r3,0x1000 |
10002154: a8 63 2d 34 l.ori r3,r3,0x2d34 |
10002158: d4 01 18 04 l.sw 4(r1),r3 |
1000215c: 9c 60 00 50 l.addi r3,r0,80 |
10002160: d4 01 18 08 l.sw 8(r1),r3 |
10002164: 18 60 10 00 l.movhi r3,0x1000 |
10002168: a8 63 2c 74 l.ori r3,r3,0x2c74 |
1000216c: 07 ff fe 1e l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10002170: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10002174: c8 00 00 00 lf.add.s r0,r0,r0 |
|
serial_putstr("6. Shift right arithmetic\n"); |
10002178: 18 60 10 00 l.movhi r3,0x1000 |
1000217c: a8 63 2e 25 l.ori r3,r3,0x2e25 |
10002180: 07 ff fe 67 l.jal 10001b1c <serial_putstr> |
var = 0x80000000; |
10002184: 18 60 80 00 l.movhi r3,0x8000 |
var >>= 1; |
assert(var == 0xC0000000); |
10002188: 18 80 c0 00 l.movhi r4,0xc000 |
assert(uvar == 0x40000000); |
uvar >>= 30; |
assert(uvar == 0x00000001); |
|
serial_putstr("6. Shift right arithmetic\n"); |
var = 0x80000000; |
1000218c: d4 02 18 00 l.sw 0(r2),r3 |
var >>= 1; |
10002190: 84 62 00 00 l.lwz r3,0(r2) |
10002194: b8 63 00 81 l.srai r3,r3,0x1 |
10002198: d4 02 18 00 l.sw 0(r2),r3 |
assert(var == 0xC0000000); |
1000219c: 84 62 00 00 l.lwz r3,0(r2) |
100021a0: e4 03 20 00 l.sfeq r3,r4 |
100021a4: 10 00 00 0e l.bf 100021dc <test+0x4f0> |
100021a8: 18 60 10 00 l.movhi r3,0x1000 |
100021ac: a8 63 2e 40 l.ori r3,r3,0x2e40 |
100021b0: d4 01 18 00 l.sw 0(r1),r3 |
100021b4: 18 60 10 00 l.movhi r3,0x1000 |
100021b8: a8 63 2d 34 l.ori r3,r3,0x2d34 |
100021bc: d4 01 18 04 l.sw 4(r1),r3 |
100021c0: 9c 60 00 55 l.addi r3,r0,85 |
100021c4: d4 01 18 08 l.sw 8(r1),r3 |
100021c8: 18 60 10 00 l.movhi r3,0x1000 |
100021cc: a8 63 2c 74 l.ori r3,r3,0x2c74 |
100021d0: 07 ff fe 05 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
100021d4: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
100021d8: c8 00 00 00 lf.add.s r0,r0,r0 |
|
serial_putstr("7. Signed comparision\n"); |
100021dc: 18 60 10 00 l.movhi r3,0x1000 |
100021e0: a8 63 2e 52 l.ori r3,r3,0x2e52 |
100021e4: 07 ff fe 4e l.jal 10001b1c <serial_putstr> |
var = -1; |
100021e8: 9c 60 ff ff l.addi r3,r0,-1 |
100021ec: d4 02 18 00 l.sw 0(r2),r3 |
assert(var < 1); |
100021f0: 84 62 00 00 l.lwz r3,0(r2) |
100021f4: bd a3 00 00 l.sflesi r3,0 |
100021f8: 10 00 00 0e l.bf 10002230 <test+0x544> |
100021fc: 18 60 10 00 l.movhi r3,0x1000 |
10002200: a8 63 2e 69 l.ori r3,r3,0x2e69 |
10002204: d4 01 18 00 l.sw 0(r1),r3 |
10002208: 18 60 10 00 l.movhi r3,0x1000 |
1000220c: a8 63 2d 34 l.ori r3,r3,0x2d34 |
10002210: d4 01 18 04 l.sw 4(r1),r3 |
10002214: 9c 60 00 59 l.addi r3,r0,89 |
10002218: d4 01 18 08 l.sw 8(r1),r3 |
1000221c: 18 60 10 00 l.movhi r3,0x1000 |
10002220: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10002224: 07 ff fd f0 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10002228: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
1000222c: c8 00 00 00 lf.add.s r0,r0,r0 |
x = 10; |
assert(var < x); |
10002230: 84 62 00 00 l.lwz r3,0(r2) |
10002234: bd a3 00 09 l.sflesi r3,9 |
10002238: 0c 00 01 95 l.bnf 1000288c <test+0xba0> |
assert(!(var > x)); |
1000223c: 84 62 00 00 l.lwz r3,0(r2) |
10002240: bd a3 00 0a l.sflesi r3,10 |
10002244: 0c 00 01 84 l.bnf 10002854 <test+0xb68> |
x = -3; |
assert(var > x); |
10002248: 84 62 00 00 l.lwz r3,0(r2) |
1000224c: bd 63 ff fe l.sfgesi r3,-2 |
10002250: 0c 00 01 73 l.bnf 1000281c <test+0xb30> |
assert(x <= var); |
10002254: 84 42 00 00 l.lwz r2,0(r2) |
10002258: bd 62 ff fd l.sfgesi r2,-3 |
1000225c: 0c 00 01 62 l.bnf 100027e4 <test+0xaf8> |
|
serial_putstr("8. Word access\n"); |
10002260: 18 60 10 00 l.movhi r3,0x1000 |
uvar = 0x12345678; |
10002264: 18 40 12 34 l.movhi r2,0x1234 |
assert(!(var > x)); |
x = -3; |
assert(var > x); |
assert(x <= var); |
|
serial_putstr("8. Word access\n"); |
10002268: a8 63 2e 95 l.ori r3,r3,0x2e95 |
uvar = 0x12345678; |
1000226c: a8 42 56 78 l.ori r2,r2,0x5678 |
assert(!(var > x)); |
x = -3; |
assert(var > x); |
assert(x <= var); |
|
serial_putstr("8. Word access\n"); |
10002270: 07 ff fe 2b l.jal 10001b1c <serial_putstr> |
uvar = 0x12345678; |
assert(uvar == 0x12345678); |
10002274: 18 60 12 34 l.movhi r3,0x1234 |
x = -3; |
assert(var > x); |
assert(x <= var); |
|
serial_putstr("8. Word access\n"); |
uvar = 0x12345678; |
10002278: d4 0e 10 00 l.sw 0(r14),r2 |
assert(uvar == 0x12345678); |
1000227c: a8 63 56 78 l.ori r3,r3,0x5678 |
10002280: 84 4e 00 00 l.lwz r2,0(r14) |
10002284: e4 02 18 00 l.sfeq r2,r3 |
10002288: 10 00 00 0e l.bf 100022c0 <test+0x5d4> |
1000228c: 18 40 10 00 l.movhi r2,0x1000 |
10002290: 18 60 10 00 l.movhi r3,0x1000 |
10002294: a8 42 2e a5 l.ori r2,r2,0x2ea5 |
10002298: a8 63 2c 74 l.ori r3,r3,0x2c74 |
1000229c: d4 01 10 00 l.sw 0(r1),r2 |
100022a0: 18 40 10 00 l.movhi r2,0x1000 |
100022a4: a8 42 2d 34 l.ori r2,r2,0x2d34 |
100022a8: d4 01 10 04 l.sw 4(r1),r2 |
100022ac: 9c 40 00 63 l.addi r2,r0,99 |
100022b0: d4 01 10 08 l.sw 8(r1),r2 |
100022b4: 07 ff fd cc l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
100022b8: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
100022bc: c8 00 00 00 lf.add.s r0,r0,r0 |
sw = uvar; |
100022c0: 84 4e 00 00 l.lwz r2,0(r14) |
assert(sw == 0x5678); |
100022c4: a4 42 ff ff l.andi r2,r2,0xffff |
100022c8: bc 02 56 78 l.sfeqi r2,22136 |
100022cc: 10 00 00 0e l.bf 10002304 <test+0x618> |
100022d0: 18 40 10 00 l.movhi r2,0x1000 |
100022d4: 18 60 10 00 l.movhi r3,0x1000 |
100022d8: a8 42 2e b8 l.ori r2,r2,0x2eb8 |
100022dc: a8 63 2c 74 l.ori r3,r3,0x2c74 |
100022e0: d4 01 10 00 l.sw 0(r1),r2 |
100022e4: 18 40 10 00 l.movhi r2,0x1000 |
100022e8: a8 42 2d 34 l.ori r2,r2,0x2d34 |
100022ec: d4 01 10 04 l.sw 4(r1),r2 |
100022f0: 9c 40 00 65 l.addi r2,r0,101 |
100022f4: d4 01 10 08 l.sw 8(r1),r2 |
100022f8: 07 ff fd bb l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
100022fc: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10002300: c8 00 00 00 lf.add.s r0,r0,r0 |
psw = &uvar; |
assert(*psw++ == 0x1234); |
10002304: 94 4e 00 00 l.lhz r2,0(r14) |
10002308: bc 02 12 34 l.sfeqi r2,4660 |
1000230c: 10 00 00 0e l.bf 10002344 <test+0x658> |
10002310: 18 40 10 00 l.movhi r2,0x1000 |
10002314: 18 60 10 00 l.movhi r3,0x1000 |
10002318: a8 42 2e c5 l.ori r2,r2,0x2ec5 |
1000231c: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10002320: d4 01 10 00 l.sw 0(r1),r2 |
10002324: 18 40 10 00 l.movhi r2,0x1000 |
10002328: a8 42 2d 34 l.ori r2,r2,0x2d34 |
1000232c: d4 01 10 04 l.sw 4(r1),r2 |
10002330: 9c 40 00 67 l.addi r2,r0,103 |
10002334: d4 01 10 08 l.sw 8(r1),r2 |
10002338: 07 ff fd ab l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
1000233c: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10002340: c8 00 00 00 lf.add.s r0,r0,r0 |
assert(*psw++ == 0x5678); |
10002344: 94 4e 00 02 l.lhz r2,2(r14) |
10002348: bc 02 56 78 l.sfeqi r2,22136 |
1000234c: 10 00 01 1f l.bf 100027c8 <test+0xadc> |
10002350: 9c 60 00 68 l.addi r3,r0,104 |
10002354: 1a 40 10 00 l.movhi r18,0x1000 |
10002358: 18 40 10 00 l.movhi r2,0x1000 |
1000235c: d4 01 18 08 l.sw 8(r1),r3 |
10002360: aa 52 2e d6 l.ori r18,r18,0x2ed6 |
10002364: a8 42 2d 34 l.ori r2,r2,0x2d34 |
10002368: 18 60 10 00 l.movhi r3,0x1000 |
1000236c: d4 01 90 00 l.sw 0(r1),r18 |
10002370: d4 01 10 04 l.sw 4(r1),r2 |
10002374: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10002378: 07 ff fd 9b l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
1000237c: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10002380: c8 00 00 00 lf.add.s r0,r0,r0 |
10002384: 94 6e 00 02 l.lhz r3,2(r14) |
psw = &uvar; |
*psw = 0xcafe; |
10002388: 9c 80 ca fe l.addi r4,r0,-13570 |
assert(*psw++ == 0xcafe); |
assert(*psw++ == 0x5678); |
1000238c: bc 03 56 78 l.sfeqi r3,22136 |
assert(sw == 0x5678); |
psw = &uvar; |
assert(*psw++ == 0x1234); |
assert(*psw++ == 0x5678); |
psw = &uvar; |
*psw = 0xcafe; |
10002390: dc 0e 20 00 l.sh 0(r14),r4 |
assert(*psw++ == 0xcafe); |
assert(*psw++ == 0x5678); |
10002394: 10 00 01 11 l.bf 100027d8 <test+0xaec> |
10002398: 9c 60 00 6c l.addi r3,r0,108 |
1000239c: d4 01 90 00 l.sw 0(r1),r18 |
100023a0: d4 01 18 08 l.sw 8(r1),r3 |
100023a4: 18 60 10 00 l.movhi r3,0x1000 |
100023a8: d4 01 10 04 l.sw 4(r1),r2 |
100023ac: a8 63 2c 74 l.ori r3,r3,0x2c74 |
100023b0: 07 ff fd 8d l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
100023b4: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
100023b8: c8 00 00 00 lf.add.s r0,r0,r0 |
psw = &uvar; |
*(++psw) = 0xbabe; |
100023bc: 9c 80 ba be l.addi r4,r0,-17730 |
100023c0: 94 6e 00 00 l.lhz r3,0(r14) |
100023c4: dc 0e 20 02 l.sh 2(r14),r4 |
psw = &uvar; |
assert(*psw++ == 0xcafe); |
100023c8: a8 80 ca fe l.ori r4,r0,0xcafe |
100023cc: e4 23 20 00 l.sfne r3,r4 |
100023d0: 0c 00 00 1b l.bnf 1000243c <test+0x750> |
100023d4: 18 60 10 00 l.movhi r3,0x1000 |
100023d8: d4 01 10 04 l.sw 4(r1),r2 |
100023dc: a8 63 2e e7 l.ori r3,r3,0x2ee7 |
100023e0: d4 01 18 00 l.sw 0(r1),r3 |
100023e4: 9c 60 00 70 l.addi r3,r0,112 |
100023e8: d4 01 18 08 l.sw 8(r1),r3 |
100023ec: 18 60 10 00 l.movhi r3,0x1000 |
100023f0: a8 63 2c 74 l.ori r3,r3,0x2c74 |
100023f4: 07 ff fd 7c l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
100023f8: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
100023fc: c8 00 00 00 lf.add.s r0,r0,r0 |
assert(*psw++ == 0xbabe); |
10002400: a8 80 ba be l.ori r4,r0,0xbabe |
10002404: 94 6e 00 02 l.lhz r3,2(r14) |
10002408: e4 03 20 00 l.sfeq r3,r4 |
1000240c: 10 00 00 0c l.bf 1000243c <test+0x750> |
10002410: 18 60 10 00 l.movhi r3,0x1000 |
10002414: d4 01 10 04 l.sw 4(r1),r2 |
10002418: a8 63 2e f8 l.ori r3,r3,0x2ef8 |
1000241c: 9c 40 00 71 l.addi r2,r0,113 |
10002420: d4 01 18 00 l.sw 0(r1),r3 |
10002424: 18 60 10 00 l.movhi r3,0x1000 |
10002428: d4 01 10 08 l.sw 8(r1),r2 |
1000242c: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10002430: 07 ff fd 6d l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10002434: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10002438: c8 00 00 00 lf.add.s r0,r0,r0 |
|
serial_putstr("9. Byte access\n"); |
1000243c: 18 60 10 00 l.movhi r3,0x1000 |
uvar = 0x12345678; |
10002440: 18 40 12 34 l.movhi r2,0x1234 |
*(++psw) = 0xbabe; |
psw = &uvar; |
assert(*psw++ == 0xcafe); |
assert(*psw++ == 0xbabe); |
|
serial_putstr("9. Byte access\n"); |
10002444: a8 63 2f 09 l.ori r3,r3,0x2f09 |
uvar = 0x12345678; |
10002448: a8 42 56 78 l.ori r2,r2,0x5678 |
*(++psw) = 0xbabe; |
psw = &uvar; |
assert(*psw++ == 0xcafe); |
assert(*psw++ == 0xbabe); |
|
serial_putstr("9. Byte access\n"); |
1000244c: 07 ff fd b4 l.jal 10001b1c <serial_putstr> |
uvar = 0x12345678; |
assert(uvar == 0x12345678); |
10002450: 18 60 12 34 l.movhi r3,0x1234 |
psw = &uvar; |
assert(*psw++ == 0xcafe); |
assert(*psw++ == 0xbabe); |
|
serial_putstr("9. Byte access\n"); |
uvar = 0x12345678; |
10002454: d4 0e 10 00 l.sw 0(r14),r2 |
assert(uvar == 0x12345678); |
10002458: a8 63 56 78 l.ori r3,r3,0x5678 |
1000245c: 84 4e 00 00 l.lwz r2,0(r14) |
10002460: e4 02 18 00 l.sfeq r2,r3 |
10002464: 10 00 00 0e l.bf 1000249c <test+0x7b0> |
10002468: 18 40 10 00 l.movhi r2,0x1000 |
1000246c: 18 60 10 00 l.movhi r3,0x1000 |
10002470: a8 42 2e a5 l.ori r2,r2,0x2ea5 |
10002474: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10002478: d4 01 10 00 l.sw 0(r1),r2 |
1000247c: 18 40 10 00 l.movhi r2,0x1000 |
10002480: a8 42 2d 34 l.ori r2,r2,0x2d34 |
10002484: d4 01 10 04 l.sw 4(r1),r2 |
10002488: 9c 40 00 75 l.addi r2,r0,117 |
1000248c: d4 01 10 08 l.sw 8(r1),r2 |
10002490: 07 ff fd 55 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10002494: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10002498: c8 00 00 00 lf.add.s r0,r0,r0 |
sb = uvar; |
1000249c: 84 4e 00 00 l.lwz r2,0(r14) |
assert(sb == 0x78); |
100024a0: a4 42 00 ff l.andi r2,r2,0xff |
100024a4: bc 02 00 78 l.sfeqi r2,120 |
100024a8: 10 00 00 0e l.bf 100024e0 <test+0x7f4> |
100024ac: 18 40 10 00 l.movhi r2,0x1000 |
100024b0: 18 60 10 00 l.movhi r3,0x1000 |
100024b4: a8 42 2f 19 l.ori r2,r2,0x2f19 |
100024b8: a8 63 2c 74 l.ori r3,r3,0x2c74 |
100024bc: d4 01 10 00 l.sw 0(r1),r2 |
100024c0: 18 40 10 00 l.movhi r2,0x1000 |
100024c4: a8 42 2d 34 l.ori r2,r2,0x2d34 |
100024c8: d4 01 10 04 l.sw 4(r1),r2 |
100024cc: 9c 40 00 77 l.addi r2,r0,119 |
100024d0: d4 01 10 08 l.sw 8(r1),r2 |
100024d4: 07 ff fd 44 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
100024d8: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
100024dc: c8 00 00 00 lf.add.s r0,r0,r0 |
psb = &uvar; |
assert(*psb++ == 0x12); |
100024e0: 8c 4e 00 00 l.lbz r2,0(r14) |
100024e4: bc 02 00 12 l.sfeqi r2,18 |
100024e8: 10 00 00 0e l.bf 10002520 <test+0x834> |
100024ec: 18 40 10 00 l.movhi r2,0x1000 |
100024f0: 18 60 10 00 l.movhi r3,0x1000 |
100024f4: a8 42 2f 24 l.ori r2,r2,0x2f24 |
100024f8: a8 63 2c 74 l.ori r3,r3,0x2c74 |
100024fc: d4 01 10 00 l.sw 0(r1),r2 |
10002500: 18 40 10 00 l.movhi r2,0x1000 |
10002504: a8 42 2d 34 l.ori r2,r2,0x2d34 |
10002508: d4 01 10 04 l.sw 4(r1),r2 |
1000250c: 9c 40 00 79 l.addi r2,r0,121 |
10002510: d4 01 10 08 l.sw 8(r1),r2 |
10002514: 07 ff fd 34 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10002518: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
1000251c: c8 00 00 00 lf.add.s r0,r0,r0 |
assert(*psb++ == 0x34); |
10002520: 8c 4e 00 01 l.lbz r2,1(r14) |
10002524: bc 02 00 34 l.sfeqi r2,52 |
10002528: 10 00 00 0e l.bf 10002560 <test+0x874> |
1000252c: 18 40 10 00 l.movhi r2,0x1000 |
10002530: 18 60 10 00 l.movhi r3,0x1000 |
10002534: a8 42 2f 33 l.ori r2,r2,0x2f33 |
10002538: a8 63 2c 74 l.ori r3,r3,0x2c74 |
1000253c: d4 01 10 00 l.sw 0(r1),r2 |
10002540: 18 40 10 00 l.movhi r2,0x1000 |
10002544: a8 42 2d 34 l.ori r2,r2,0x2d34 |
10002548: d4 01 10 04 l.sw 4(r1),r2 |
1000254c: 9c 40 00 7a l.addi r2,r0,122 |
10002550: d4 01 10 08 l.sw 8(r1),r2 |
10002554: 07 ff fd 24 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10002558: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
1000255c: c8 00 00 00 lf.add.s r0,r0,r0 |
assert(*psb++ == 0x56); |
10002560: 8c 4e 00 02 l.lbz r2,2(r14) |
10002564: bc 02 00 56 l.sfeqi r2,86 |
10002568: 10 00 00 0e l.bf 100025a0 <test+0x8b4> |
1000256c: 18 40 10 00 l.movhi r2,0x1000 |
10002570: 18 60 10 00 l.movhi r3,0x1000 |
10002574: a8 42 2f 42 l.ori r2,r2,0x2f42 |
10002578: a8 63 2c 74 l.ori r3,r3,0x2c74 |
1000257c: d4 01 10 00 l.sw 0(r1),r2 |
10002580: 18 40 10 00 l.movhi r2,0x1000 |
10002584: a8 42 2d 34 l.ori r2,r2,0x2d34 |
10002588: d4 01 10 04 l.sw 4(r1),r2 |
1000258c: 9c 40 00 7b l.addi r2,r0,123 |
10002590: d4 01 10 08 l.sw 8(r1),r2 |
10002594: 07 ff fd 14 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10002598: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
1000259c: c8 00 00 00 lf.add.s r0,r0,r0 |
assert(*psb++ == 0x78); |
100025a0: 8c 4e 00 03 l.lbz r2,3(r14) |
100025a4: bc 02 00 78 l.sfeqi r2,120 |
100025a8: 10 00 00 0e l.bf 100025e0 <test+0x8f4> |
100025ac: 18 40 10 00 l.movhi r2,0x1000 |
100025b0: 18 60 10 00 l.movhi r3,0x1000 |
100025b4: a8 42 2f 51 l.ori r2,r2,0x2f51 |
100025b8: a8 63 2c 74 l.ori r3,r3,0x2c74 |
100025bc: d4 01 10 00 l.sw 0(r1),r2 |
100025c0: 18 40 10 00 l.movhi r2,0x1000 |
100025c4: a8 42 2d 34 l.ori r2,r2,0x2d34 |
100025c8: d4 01 10 04 l.sw 4(r1),r2 |
100025cc: 9c 40 00 7c l.addi r2,r0,124 |
100025d0: d4 01 10 08 l.sw 8(r1),r2 |
100025d4: 07 ff fd 04 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
100025d8: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
100025dc: c8 00 00 00 lf.add.s r0,r0,r0 |
psb = &uvar; |
*psb++ = 0xab; |
100025e0: 9c 80 ff ab l.addi r4,r0,-85 |
assert(uvar == 0xab345678); |
100025e4: 18 60 ab 34 l.movhi r3,0xab34 |
assert(*psb++ == 0x12); |
assert(*psb++ == 0x34); |
assert(*psb++ == 0x56); |
assert(*psb++ == 0x78); |
psb = &uvar; |
*psb++ = 0xab; |
100025e8: d8 0e 20 00 l.sb 0(r14),r4 |
assert(uvar == 0xab345678); |
100025ec: a8 63 56 78 l.ori r3,r3,0x5678 |
100025f0: 84 4e 00 00 l.lwz r2,0(r14) |
100025f4: e4 02 18 00 l.sfeq r2,r3 |
100025f8: 10 00 00 0e l.bf 10002630 <test+0x944> |
100025fc: 18 40 10 00 l.movhi r2,0x1000 |
10002600: 18 60 10 00 l.movhi r3,0x1000 |
10002604: a8 42 2f 60 l.ori r2,r2,0x2f60 |
10002608: a8 63 2c 74 l.ori r3,r3,0x2c74 |
1000260c: d4 01 10 00 l.sw 0(r1),r2 |
10002610: 18 40 10 00 l.movhi r2,0x1000 |
10002614: a8 42 2d 34 l.ori r2,r2,0x2d34 |
10002618: d4 01 10 04 l.sw 4(r1),r2 |
1000261c: 9c 40 00 7f l.addi r2,r0,127 |
10002620: d4 01 10 08 l.sw 8(r1),r2 |
10002624: 07 ff fc f0 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10002628: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
1000262c: c8 00 00 00 lf.add.s r0,r0,r0 |
*psb++ = 0xcd; |
10002630: 9c 80 ff cd l.addi r4,r0,-51 |
assert(uvar == 0xabcd5678); |
10002634: 18 60 ab cd l.movhi r3,0xabcd |
assert(*psb++ == 0x56); |
assert(*psb++ == 0x78); |
psb = &uvar; |
*psb++ = 0xab; |
assert(uvar == 0xab345678); |
*psb++ = 0xcd; |
10002638: d8 0e 20 01 l.sb 1(r14),r4 |
assert(uvar == 0xabcd5678); |
1000263c: a8 63 56 78 l.ori r3,r3,0x5678 |
10002640: 84 4e 00 00 l.lwz r2,0(r14) |
10002644: e4 02 18 00 l.sfeq r2,r3 |
10002648: 10 00 00 0e l.bf 10002680 <test+0x994> |
1000264c: 18 40 10 00 l.movhi r2,0x1000 |
10002650: 18 60 10 00 l.movhi r3,0x1000 |
10002654: a8 42 2f 73 l.ori r2,r2,0x2f73 |
10002658: a8 63 2c 74 l.ori r3,r3,0x2c74 |
1000265c: d4 01 10 00 l.sw 0(r1),r2 |
10002660: 18 40 10 00 l.movhi r2,0x1000 |
10002664: a8 42 2d 34 l.ori r2,r2,0x2d34 |
10002668: d4 01 10 04 l.sw 4(r1),r2 |
1000266c: 9c 40 00 81 l.addi r2,r0,129 |
10002670: d4 01 10 08 l.sw 8(r1),r2 |
10002674: 07 ff fc dc l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10002678: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
1000267c: c8 00 00 00 lf.add.s r0,r0,r0 |
*psb++ = 0xef; |
10002680: 9c 80 ff ef l.addi r4,r0,-17 |
assert(uvar == 0xabcdef78); |
10002684: 18 60 ab cd l.movhi r3,0xabcd |
psb = &uvar; |
*psb++ = 0xab; |
assert(uvar == 0xab345678); |
*psb++ = 0xcd; |
assert(uvar == 0xabcd5678); |
*psb++ = 0xef; |
10002688: d8 0e 20 02 l.sb 2(r14),r4 |
assert(uvar == 0xabcdef78); |
1000268c: a8 63 ef 78 l.ori r3,r3,0xef78 |
10002690: 84 4e 00 00 l.lwz r2,0(r14) |
10002694: e4 02 18 00 l.sfeq r2,r3 |
10002698: 10 00 00 0e l.bf 100026d0 <test+0x9e4> |
1000269c: 18 40 10 00 l.movhi r2,0x1000 |
100026a0: 18 60 10 00 l.movhi r3,0x1000 |
100026a4: a8 42 2f 86 l.ori r2,r2,0x2f86 |
100026a8: a8 63 2c 74 l.ori r3,r3,0x2c74 |
100026ac: d4 01 10 00 l.sw 0(r1),r2 |
100026b0: 18 40 10 00 l.movhi r2,0x1000 |
100026b4: a8 42 2d 34 l.ori r2,r2,0x2d34 |
100026b8: d4 01 10 04 l.sw 4(r1),r2 |
100026bc: 9c 40 00 83 l.addi r2,r0,131 |
100026c0: d4 01 10 08 l.sw 8(r1),r2 |
100026c4: 07 ff fc c8 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
100026c8: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
100026cc: c8 00 00 00 lf.add.s r0,r0,r0 |
*psb++ = 0x01; |
100026d0: 9c 80 00 01 l.addi r4,r0,1 |
assert(uvar == 0xabcdef01); |
100026d4: 18 60 ab cd l.movhi r3,0xabcd |
assert(uvar == 0xab345678); |
*psb++ = 0xcd; |
assert(uvar == 0xabcd5678); |
*psb++ = 0xef; |
assert(uvar == 0xabcdef78); |
*psb++ = 0x01; |
100026d8: d8 0e 20 03 l.sb 3(r14),r4 |
assert(uvar == 0xabcdef01); |
100026dc: a8 63 ef 01 l.ori r3,r3,0xef01 |
100026e0: 84 4e 00 00 l.lwz r2,0(r14) |
100026e4: e4 02 18 00 l.sfeq r2,r3 |
100026e8: 10 00 00 0e l.bf 10002720 <test+0xa34> |
100026ec: 18 40 10 00 l.movhi r2,0x1000 |
100026f0: 18 60 10 00 l.movhi r3,0x1000 |
100026f4: a8 42 2f 99 l.ori r2,r2,0x2f99 |
100026f8: a8 63 2c 74 l.ori r3,r3,0x2c74 |
100026fc: d4 01 10 00 l.sw 0(r1),r2 |
10002700: 18 40 10 00 l.movhi r2,0x1000 |
10002704: a8 42 2d 34 l.ori r2,r2,0x2d34 |
10002708: d4 01 10 04 l.sw 4(r1),r2 |
1000270c: 9c 40 00 85 l.addi r2,r0,133 |
10002710: d4 01 10 08 l.sw 8(r1),r2 |
10002714: 07 ff fc b4 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10002718: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
1000271c: c8 00 00 00 lf.add.s r0,r0,r0 |
|
serial_putstr("10. Comparision\n"); |
10002720: 18 60 10 00 l.movhi r3,0x1000 |
longvar = 0x1db9; |
10002724: 18 40 10 00 l.movhi r2,0x1000 |
*psb++ = 0xef; |
assert(uvar == 0xabcdef78); |
*psb++ = 0x01; |
assert(uvar == 0xabcdef01); |
|
serial_putstr("10. Comparision\n"); |
10002728: a8 63 2f ac l.ori r3,r3,0x2fac |
longvar = 0x1db9; |
1000272c: a8 42 30 00 l.ori r2,r2,0x3000 |
*psb++ = 0xef; |
assert(uvar == 0xabcdef78); |
*psb++ = 0x01; |
assert(uvar == 0xabcdef01); |
|
serial_putstr("10. Comparision\n"); |
10002730: 07 ff fc fb l.jal 10001b1c <serial_putstr> |
longvar = 0x1db9; |
10002734: 9c 60 1d b9 l.addi r3,r0,7609 |
if (longvar >= 0xFFF8 && longvar <= 0xFFFF) |
10002738: a8 80 ff f7 l.ori r4,r0,0xfff7 |
assert(uvar == 0xabcdef78); |
*psb++ = 0x01; |
assert(uvar == 0xabcdef01); |
|
serial_putstr("10. Comparision\n"); |
longvar = 0x1db9; |
1000273c: d4 02 18 00 l.sw 0(r2),r3 |
if (longvar >= 0xFFF8 && longvar <= 0xFFFF) |
10002740: 84 62 00 00 l.lwz r3,0(r2) |
10002744: e4 a3 20 00 l.sfleu r3,r4 |
10002748: 10 00 00 05 l.bf 1000275c <test+0xa70> |
1000274c: a8 60 ff ff l.ori r3,r0,0xffff |
10002750: 84 42 00 00 l.lwz r2,0(r2) |
10002754: e4 42 18 00 l.sfgtu r2,r3 |
10002758: 0c 00 00 0b l.bnf 10002784 <test+0xa98> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
1000275c: 9c 20 00 00 l.addi r1,r0,0 |
|
// No error? |
if (exit_code == 0) |
{ |
// Trap instruction |
__asm__ __volatile__ ( "\t l.trap 0 "); |
10002760: 21 00 00 00 l.trap 0x0 |
assert(0); |
} |
|
// Success |
exit(0); |
} |
10002764: 9c 21 00 20 l.addi r1,r1,32 |
10002768: 9d 60 00 00 l.addi r11,r0,0 |
1000276c: 85 21 ff fc l.lwz r9,-4(r1) |
10002770: 84 21 ff ec l.lwz r1,-20(r1) |
10002774: 84 41 ff f0 l.lwz r2,-16(r1) |
10002778: 85 c1 ff f4 l.lwz r14,-12(r1) |
1000277c: 86 41 ff f8 l.lwz r18,-8(r1) |
10002780: 44 00 48 00 l.jr r9 |
|
serial_putstr("10. Comparision\n"); |
longvar = 0x1db9; |
if (longvar >= 0xFFF8 && longvar <= 0xFFFF) |
{ |
serial_putstr("- Incorrect comparision\n"); |
10002784: 18 60 10 00 l.movhi r3,0x1000 |
assert(0); |
10002788: 18 40 10 00 l.movhi r2,0x1000 |
|
serial_putstr("10. Comparision\n"); |
longvar = 0x1db9; |
if (longvar >= 0xFFF8 && longvar <= 0xFFFF) |
{ |
serial_putstr("- Incorrect comparision\n"); |
1000278c: a8 63 2f bd l.ori r3,r3,0x2fbd |
assert(0); |
10002790: a8 42 2d 07 l.ori r2,r2,0x2d07 |
|
serial_putstr("10. Comparision\n"); |
longvar = 0x1db9; |
if (longvar >= 0xFFF8 && longvar <= 0xFFFF) |
{ |
serial_putstr("- Incorrect comparision\n"); |
10002794: 07 ff fc e2 l.jal 10001b1c <serial_putstr> |
assert(0); |
10002798: d4 01 10 00 l.sw 0(r1),r2 |
1000279c: 18 40 10 00 l.movhi r2,0x1000 |
100027a0: 18 60 10 00 l.movhi r3,0x1000 |
100027a4: a8 42 2d 34 l.ori r2,r2,0x2d34 |
100027a8: a8 63 2c 74 l.ori r3,r3,0x2c74 |
100027ac: d4 01 10 04 l.sw 4(r1),r2 |
100027b0: 9c 40 00 8c l.addi r2,r0,140 |
100027b4: d4 01 10 08 l.sw 8(r1),r2 |
100027b8: 07 ff fc 8b l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
100027bc: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
100027c0: c8 00 00 00 lf.add.s r0,r0,r0 |
100027c4: 03 ff ff e6 l.j 1000275c <test+0xa70> |
assert(sw == 0x5678); |
psw = &uvar; |
assert(*psw++ == 0x1234); |
assert(*psw++ == 0x5678); |
psw = &uvar; |
*psw = 0xcafe; |
100027c8: 18 40 10 00 l.movhi r2,0x1000 |
100027cc: 9c 80 ca fe l.addi r4,r0,-13570 |
100027d0: a8 42 30 04 l.ori r2,r2,0x3004 |
100027d4: dc 02 20 00 l.sh 0(r2),r4 |
assert(*psw++ == 0xcafe); |
assert(*psw++ == 0x5678); |
psw = &uvar; |
*(++psw) = 0xbabe; |
100027d8: 9c 40 ba be l.addi r2,r0,-17730 |
100027dc: dc 0e 10 02 l.sh 2(r14),r2 |
100027e0: 03 ff ff 17 l.j 1000243c <test+0x750> |
x = 10; |
assert(var < x); |
assert(!(var > x)); |
x = -3; |
assert(var > x); |
assert(x <= var); |
100027e4: 18 40 10 00 l.movhi r2,0x1000 |
100027e8: 18 60 10 00 l.movhi r3,0x1000 |
100027ec: a8 42 2e 8c l.ori r2,r2,0x2e8c |
100027f0: a8 63 2c 74 l.ori r3,r3,0x2c74 |
100027f4: d4 01 10 00 l.sw 0(r1),r2 |
100027f8: 18 40 10 00 l.movhi r2,0x1000 |
100027fc: a8 42 2d 34 l.ori r2,r2,0x2d34 |
10002800: d4 01 10 04 l.sw 4(r1),r2 |
10002804: 9c 40 00 5f l.addi r2,r0,95 |
10002808: d4 01 10 08 l.sw 8(r1),r2 |
1000280c: 07 ff fc 76 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10002810: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10002814: c8 00 00 00 lf.add.s r0,r0,r0 |
10002818: 03 ff fe 92 l.j 10002260 <test+0x574> |
assert(var < 1); |
x = 10; |
assert(var < x); |
assert(!(var > x)); |
x = -3; |
assert(var > x); |
1000281c: 18 60 10 00 l.movhi r3,0x1000 |
10002820: a8 63 2e 84 l.ori r3,r3,0x2e84 |
10002824: d4 01 18 00 l.sw 0(r1),r3 |
10002828: 18 60 10 00 l.movhi r3,0x1000 |
1000282c: a8 63 2d 34 l.ori r3,r3,0x2d34 |
10002830: d4 01 18 04 l.sw 4(r1),r3 |
10002834: 9c 60 00 5e l.addi r3,r0,94 |
10002838: d4 01 18 08 l.sw 8(r1),r3 |
1000283c: 18 60 10 00 l.movhi r3,0x1000 |
10002840: a8 63 2c 74 l.ori r3,r3,0x2c74 |
10002844: 07 ff fc 68 l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10002848: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
1000284c: c8 00 00 00 lf.add.s r0,r0,r0 |
10002850: 03 ff fe 81 l.j 10002254 <test+0x568> |
serial_putstr("7. Signed comparision\n"); |
var = -1; |
assert(var < 1); |
x = 10; |
assert(var < x); |
assert(!(var > x)); |
10002854: 18 60 10 00 l.movhi r3,0x1000 |
10002858: a8 63 2e 79 l.ori r3,r3,0x2e79 |
1000285c: d4 01 18 00 l.sw 0(r1),r3 |
10002860: 18 60 10 00 l.movhi r3,0x1000 |
10002864: a8 63 2d 34 l.ori r3,r3,0x2d34 |
10002868: d4 01 18 04 l.sw 4(r1),r3 |
1000286c: 9c 60 00 5c l.addi r3,r0,92 |
10002870: d4 01 18 08 l.sw 8(r1),r3 |
10002874: 18 60 10 00 l.movhi r3,0x1000 |
10002878: a8 63 2c 74 l.ori r3,r3,0x2c74 |
1000287c: 07 ff fc 5a l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
10002880: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
10002884: c8 00 00 00 lf.add.s r0,r0,r0 |
10002888: 03 ff fe 70 l.j 10002248 <test+0x55c> |
|
serial_putstr("7. Signed comparision\n"); |
var = -1; |
assert(var < 1); |
x = 10; |
assert(var < x); |
1000288c: 18 60 10 00 l.movhi r3,0x1000 |
10002890: a8 63 2e 71 l.ori r3,r3,0x2e71 |
10002894: d4 01 18 00 l.sw 0(r1),r3 |
10002898: 18 60 10 00 l.movhi r3,0x1000 |
1000289c: a8 63 2d 34 l.ori r3,r3,0x2d34 |
100028a0: d4 01 18 04 l.sw 4(r1),r3 |
100028a4: 9c 60 00 5b l.addi r3,r0,91 |
100028a8: d4 01 18 08 l.sw 8(r1),r3 |
100028ac: 18 60 10 00 l.movhi r3,0x1000 |
100028b0: a8 63 2c 74 l.ori r3,r3,0x2c74 |
100028b4: 07 ff fc 4c l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
100028b8: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
100028bc: c8 00 00 00 lf.add.s r0,r0,r0 |
100028c0: 03 ff fe 5f l.j 1000223c <test+0x550> |
// Assign empty syscall handler |
exception_register_syscall_handler(empty_syscall); |
|
serial_putstr("1. Initialised data\n"); |
assert(var == 0x1234); // .text |
assert(uvar == 0x0); // .bss |
100028c4: 18 60 10 00 l.movhi r3,0x1000 |
100028c8: a8 63 2d 3b l.ori r3,r3,0x2d3b |
100028cc: d4 01 18 00 l.sw 0(r1),r3 |
100028d0: 18 60 10 00 l.movhi r3,0x1000 |
100028d4: a8 63 2d 34 l.ori r3,r3,0x2d34 |
100028d8: d4 01 18 04 l.sw 4(r1),r3 |
100028dc: 9c 60 00 2a l.addi r3,r0,42 |
100028e0: d4 01 18 08 l.sw 8(r1),r3 |
100028e4: 18 60 10 00 l.movhi r3,0x1000 |
100028e8: a8 63 2c 74 l.ori r3,r3,0x2c74 |
100028ec: 07 ff fc 3e l.jal 100019e4 <printf> |
|
} |
|
static inline void exit(unsigned exit_code) |
{ |
volatile register char t1 asm ("r1") = exit_code; |
100028f0: 9c 20 00 01 l.addi r1,r0,1 |
__asm__ __volatile__ ( "\t l.trap 0 "); |
} |
else |
{ |
// Invalid instruction! |
__asm__ __volatile__ ( "\t lf.add.s r0,r0,r0 "); |
100028f4: c8 00 00 00 lf.add.s r0,r0,r0 |
100028f8: 03 ff fd 23 l.j 10001d84 <test+0x98> |
|
100028fc <__udivsi3>: |
|
long udivmodsi4 (); |
|
long |
__udivsi3 (long a, long b) |
{ |
100028fc: d7 e1 4f fc l.sw -4(r1),r9 |
10002900: d7 e1 0f f8 l.sw -8(r1),r1 |
return udivmodsi4 (a, b, 0); |
10002904: 9c a0 00 00 l.addi r5,r0,0 |
|
long udivmodsi4 (); |
|
long |
__udivsi3 (long a, long b) |
{ |
10002908: 9c 21 ff f8 l.addi r1,r1,-8 |
return udivmodsi4 (a, b, 0); |
1000290c: 04 00 00 40 l.jal 10002a0c <udivmodsi4> |
} |
10002910: 9c 21 00 08 l.addi r1,r1,8 |
10002914: 85 21 ff fc l.lwz r9,-4(r1) |
10002918: 84 21 ff f8 l.lwz r1,-8(r1) |
1000291c: 44 00 48 00 l.jr r9 |
|
10002920 <__umodsi3>: |
|
long |
__umodsi3 (long a, long b) |
{ |
10002920: d7 e1 4f fc l.sw -4(r1),r9 |
10002924: d7 e1 0f f8 l.sw -8(r1),r1 |
return udivmodsi4 (a, b, 1); |
10002928: 9c a0 00 01 l.addi r5,r0,1 |
return udivmodsi4 (a, b, 0); |
} |
|
long |
__umodsi3 (long a, long b) |
{ |
1000292c: 9c 21 ff f8 l.addi r1,r1,-8 |
return udivmodsi4 (a, b, 1); |
10002930: 04 00 00 37 l.jal 10002a0c <udivmodsi4> |
} |
10002934: 9c 21 00 08 l.addi r1,r1,8 |
10002938: 85 21 ff fc l.lwz r9,-4(r1) |
1000293c: 84 21 ff f8 l.lwz r1,-8(r1) |
10002940: 44 00 48 00 l.jr r9 |
|
10002944 <__divsi3>: |
|
long udivmodsi4 (); |
|
long |
__divsi3 (long a, long b) |
{ |
10002944: d7 e1 17 f8 l.sw -8(r1),r2 |
10002948: d7 e1 4f fc l.sw -4(r1),r9 |
1000294c: d7 e1 0f f4 l.sw -12(r1),r1 |
int neg = 0; |
long res; |
|
if (a < 0) |
10002950: bd 63 00 00 l.sfgesi r3,0 |
|
long udivmodsi4 (); |
|
long |
__divsi3 (long a, long b) |
{ |
10002954: 9c 21 ff f4 l.addi r1,r1,-12 |
int neg = 0; |
10002958: 9c 40 00 00 l.addi r2,r0,0 |
long res; |
|
if (a < 0) |
1000295c: 0c 00 00 0d l.bnf 10002990 <__divsi3+0x4c> |
{ |
a = -a; |
neg = !neg; |
} |
|
if (b < 0) |
10002960: bd 64 00 00 l.sfgesi r4,0 |
10002964: 0c 00 00 0f l.bnf 100029a0 <__divsi3+0x5c> |
{ |
b = -b; |
neg = !neg; |
} |
|
res = udivmodsi4 (a, b, 0); |
10002968: 9c a0 00 00 l.addi r5,r0,0 |
1000296c: 04 00 00 28 l.jal 10002a0c <udivmodsi4> |
|
if (neg) |
10002970: bc 02 00 00 l.sfeqi r2,0 |
10002974: 10 00 00 02 l.bf 1000297c <__divsi3+0x38> |
res = -res; |
10002978: e1 60 58 02 l.sub r11,r0,r11 |
|
return res; |
} |
1000297c: 9c 21 00 0c l.addi r1,r1,12 |
10002980: 85 21 ff fc l.lwz r9,-4(r1) |
10002984: 84 21 ff f4 l.lwz r1,-12(r1) |
10002988: 84 41 ff f8 l.lwz r2,-8(r1) |
1000298c: 44 00 48 00 l.jr r9 |
{ |
a = -a; |
neg = !neg; |
} |
|
if (b < 0) |
10002990: bd 64 00 00 l.sfgesi r4,0 |
int neg = 0; |
long res; |
|
if (a < 0) |
{ |
a = -a; |
10002994: e0 60 18 02 l.sub r3,r0,r3 |
neg = !neg; |
10002998: 9c 40 00 01 l.addi r2,r0,1 |
} |
|
if (b < 0) |
1000299c: 13 ff ff f3 l.bf 10002968 <__divsi3+0x24> |
{ |
b = -b; |
100029a0: e0 80 20 02 l.sub r4,r0,r4 |
100029a4: ac 42 00 01 l.xori r2,r2,1 |
100029a8: 03 ff ff f0 l.j 10002968 <__divsi3+0x24> |
|
100029ac <__modsi3>: |
return res; |
} |
|
long |
__modsi3 (long a, long b) |
{ |
100029ac: d7 e1 4f fc l.sw -4(r1),r9 |
100029b0: d7 e1 0f f8 l.sw -8(r1),r1 |
int neg = 0; |
long res; |
|
if (a < 0) |
100029b4: bd 63 00 00 l.sfgesi r3,0 |
return res; |
} |
|
long |
__modsi3 (long a, long b) |
{ |
100029b8: 9c 21 ff f8 l.addi r1,r1,-8 |
100029bc: b8 c4 00 9f l.srai r6,r4,0x1f |
int neg = 0; |
long res; |
|
if (a < 0) |
100029c0: 0c 00 00 09 l.bnf 100029e4 <__modsi3+0x38> |
100029c4: e0 86 20 05 l.xor r4,r6,r4 |
} |
|
if (b < 0) |
b = -b; |
|
res = udivmodsi4 (a, b, 1); |
100029c8: 9c a0 00 01 l.addi r5,r0,1 |
100029cc: e0 84 30 02 l.sub r4,r4,r6 |
100029d0: 04 00 00 0f l.jal 10002a0c <udivmodsi4> |
|
if (neg) |
res = -res; |
|
return res; |
} |
100029d4: 9c 21 00 08 l.addi r1,r1,8 |
100029d8: 85 21 ff fc l.lwz r9,-4(r1) |
100029dc: 84 21 ff f8 l.lwz r1,-8(r1) |
100029e0: 44 00 48 00 l.jr r9 |
100029e4: e0 86 20 05 l.xor r4,r6,r4 |
} |
|
if (b < 0) |
b = -b; |
|
res = udivmodsi4 (a, b, 1); |
100029e8: e0 60 18 02 l.sub r3,r0,r3 |
100029ec: 9c a0 00 01 l.addi r5,r0,1 |
100029f0: e0 84 30 02 l.sub r4,r4,r6 |
100029f4: 04 00 00 06 l.jal 10002a0c <udivmodsi4> |
|
if (neg) |
res = -res; |
|
return res; |
} |
100029f8: 9c 21 00 08 l.addi r1,r1,8 |
b = -b; |
|
res = udivmodsi4 (a, b, 1); |
|
if (neg) |
res = -res; |
100029fc: e1 60 58 02 l.sub r11,r0,r11 |
|
return res; |
} |
10002a00: 85 21 ff fc l.lwz r9,-4(r1) |
10002a04: 84 21 ff f8 l.lwz r1,-8(r1) |
10002a08: 44 00 48 00 l.jr r9 |
|
10002a0c <udivmodsi4>: |
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
<http://www.gnu.org/licenses/>. */ |
|
unsigned long |
udivmodsi4(unsigned long num, unsigned long den, int modwanted) |
{ |
10002a0c: d7 e1 0f fc l.sw -4(r1),r1 |
unsigned long bit = 1; |
unsigned long res = 0; |
|
while (den < num && bit && !(den & (1L<<31))) |
10002a10: e4 64 18 00 l.sfgeu r4,r3 |
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
<http://www.gnu.org/licenses/>. */ |
|
unsigned long |
udivmodsi4(unsigned long num, unsigned long den, int modwanted) |
{ |
10002a14: 9c 21 ff fc l.addi r1,r1,-4 |
unsigned long bit = 1; |
unsigned long res = 0; |
|
while (den < num && bit && !(den & (1L<<31))) |
10002a18: 10 00 00 26 l.bf 10002ab0 <udivmodsi4+0xa4> |
10002a1c: bd 64 00 00 l.sfgesi r4,0 |
<http://www.gnu.org/licenses/>. */ |
|
unsigned long |
udivmodsi4(unsigned long num, unsigned long den, int modwanted) |
{ |
unsigned long bit = 1; |
10002a20: 9c c0 00 01 l.addi r6,r0,1 |
unsigned long res = 0; |
|
while (den < num && bit && !(den & (1L<<31))) |
10002a24: 10 00 00 06 l.bf 10002a3c <udivmodsi4+0x30> |
10002a28: 00 00 00 13 l.j 10002a74 <udivmodsi4+0x68> |
10002a2c: bd 88 00 00 l.sfltsi r8,0 |
10002a30: 0c 00 00 0e l.bnf 10002a68 <udivmodsi4+0x5c> |
10002a34: bd 84 00 00 l.sfltsi r4,0 |
10002a38: 10 00 00 0f l.bf 10002a74 <udivmodsi4+0x68> |
{ |
den <<=1; |
bit <<=1; |
10002a3c: e0 c6 30 00 l.add r6,r6,r6 |
unsigned long bit = 1; |
unsigned long res = 0; |
|
while (den < num && bit && !(den & (1L<<31))) |
{ |
den <<=1; |
10002a40: e0 84 20 00 l.add r4,r4,r4 |
udivmodsi4(unsigned long num, unsigned long den, int modwanted) |
{ |
unsigned long bit = 1; |
unsigned long res = 0; |
|
while (den < num && bit && !(den & (1L<<31))) |
10002a44: e1 00 30 02 l.sub r8,r0,r6 |
10002a48: e4 43 20 00 l.sfgtu r3,r4 |
10002a4c: 9c e0 00 01 l.addi r7,r0,1 |
10002a50: e1 08 30 04 l.or r8,r8,r6 |
10002a54: 10 00 00 02 l.bf 10002a5c <udivmodsi4+0x50> |
10002a58: 9c e0 00 00 l.addi r7,r0,0 |
10002a5c: a4 e7 00 ff l.andi r7,r7,0xff |
10002a60: bc 07 00 00 l.sfeqi r7,0 |
10002a64: 0f ff ff f2 l.bnf 10002a2c <udivmodsi4+0x20> |
{ |
den <<=1; |
bit <<=1; |
} |
while (bit) |
10002a68: bc 26 00 00 l.sfnei r6,0 |
10002a6c: a9 66 00 00 l.ori r11,r6,0x0 |
10002a70: 0c 00 00 0a l.bnf 10002a98 <udivmodsi4+0x8c> |
unsigned long res = 0; |
|
while (den < num && bit && !(den & (1L<<31))) |
{ |
den <<=1; |
bit <<=1; |
10002a74: 9d 60 00 00 l.addi r11,r0,0 |
} |
while (bit) |
{ |
if (num >= den) |
10002a78: e4 83 20 00 l.sfltu r3,r4 |
10002a7c: 10 00 00 03 l.bf 10002a88 <udivmodsi4+0x7c> |
{ |
num -= den; |
10002a80: e0 63 20 02 l.sub r3,r3,r4 |
res |= bit; |
10002a84: e1 6b 30 04 l.or r11,r11,r6 |
} |
bit >>=1; |
10002a88: b8 c6 00 41 l.srli r6,r6,0x1 |
den >>=1; |
10002a8c: b8 84 00 41 l.srli r4,r4,0x1 |
while (den < num && bit && !(den & (1L<<31))) |
{ |
den <<=1; |
bit <<=1; |
} |
while (bit) |
10002a90: bc 06 00 00 l.sfeqi r6,0 |
10002a94: 0f ff ff f9 l.bnf 10002a78 <udivmodsi4+0x6c> |
res |= bit; |
} |
bit >>=1; |
den >>=1; |
} |
if (modwanted) return num; |
10002a98: bc 05 00 00 l.sfeqi r5,0 |
10002a9c: 10 00 00 02 l.bf 10002aa4 <udivmodsi4+0x98> |
10002aa0: a9 63 00 00 l.ori r11,r3,0x0 |
return res; |
} |
10002aa4: 9c 21 00 04 l.addi r1,r1,4 |
10002aa8: 84 21 ff fc l.lwz r1,-4(r1) |
10002aac: 44 00 48 00 l.jr r9 |
udivmodsi4(unsigned long num, unsigned long den, int modwanted) |
{ |
unsigned long bit = 1; |
unsigned long res = 0; |
|
while (den < num && bit && !(den & (1L<<31))) |
10002ab0: 9c c0 00 01 l.addi r6,r0,1 |
10002ab4: 03 ff ff f0 l.j 10002a74 <udivmodsi4+0x68> |
|
10002ab8 <__mulsi3>: |
|
typedef unsigned int USItype __attribute__ ((mode (SI))); |
|
USItype |
__mulsi3 (USItype a, USItype b) |
{ |
10002ab8: d7 e1 0f fc l.sw -4(r1),r1 |
USItype c = 0; |
|
while (a != 0) |
10002abc: bc 03 00 00 l.sfeqi r3,0 |
|
typedef unsigned int USItype __attribute__ ((mode (SI))); |
|
USItype |
__mulsi3 (USItype a, USItype b) |
{ |
10002ac0: 9c 21 ff fc l.addi r1,r1,-4 |
USItype c = 0; |
|
while (a != 0) |
10002ac4: 10 00 00 0d l.bf 10002af8 <__mulsi3+0x40> |
typedef unsigned int USItype __attribute__ ((mode (SI))); |
|
USItype |
__mulsi3 (USItype a, USItype b) |
{ |
USItype c = 0; |
10002ac8: 9d 60 00 00 l.addi r11,r0,0 |
|
while (a != 0) |
{ |
if (a & 1) |
10002acc: a4 a3 00 01 l.andi r5,r3,0x1 |
10002ad0: b8 63 00 41 l.srli r3,r3,0x1 |
10002ad4: bc 05 00 00 l.sfeqi r5,0 |
10002ad8: 10 00 00 02 l.bf 10002ae0 <__mulsi3+0x28> |
c += b; |
10002adc: e1 6b 20 00 l.add r11,r11,r4 |
USItype |
__mulsi3 (USItype a, USItype b) |
{ |
USItype c = 0; |
|
while (a != 0) |
10002ae0: bc 03 00 00 l.sfeqi r3,0 |
{ |
if (a & 1) |
c += b; |
a >>= 1; |
b <<= 1; |
10002ae4: e0 84 20 00 l.add r4,r4,r4 |
USItype |
__mulsi3 (USItype a, USItype b) |
{ |
USItype c = 0; |
|
while (a != 0) |
10002ae8: 0f ff ff f9 l.bnf 10002acc <__mulsi3+0x14> |
a >>= 1; |
b <<= 1; |
} |
|
return c; |
} |
10002aec: 9c 21 00 04 l.addi r1,r1,4 |
10002af0: 84 21 ff fc l.lwz r1,-4(r1) |
10002af4: 44 00 48 00 l.jr r9 |
typedef unsigned int USItype __attribute__ ((mode (SI))); |
|
USItype |
__mulsi3 (USItype a, USItype b) |
{ |
USItype c = 0; |
10002af8: a9 63 00 00 l.ori r11,r3,0x0 |
10002afc: 03 ff ff fc l.j 10002aec <__mulsi3+0x34> |
10002b00: 10 00 12 b8 l.bf 100075e0 <_end+0x35d0> |
10002b04: 10 00 11 a0 l.bf 10007184 <_end+0x3174> |
10002b08: 10 00 11 bc l.bf 100071f8 <_end+0x31e8> |
10002b0c: 10 00 11 f0 l.bf 100072cc <_end+0x32bc> |
10002b10: 10 00 12 24 l.bf 100073a0 <_end+0x3390> |
10002b14: 10 00 12 58 l.bf 10007474 <_end+0x3464> |
10002b18: 10 00 12 78 l.bf 100074f8 <_end+0x34e8> |
10002b1c: 10 00 12 98 l.bf 1000757c <_end+0x356c> |
10002b20: 10 00 11 10 l.bf 10006f60 <_end+0x2f50> |
10002b24: 10 00 18 dc l.bf 10008e94 <_end+0x4e84> |
10002b28: 10 00 16 2c l.bf 100083d8 <_end+0x43c8> |
10002b2c: 10 00 16 2c l.bf 100083dc <_end+0x43cc> |
10002b30: 10 00 16 2c l.bf 100083e0 <_end+0x43d0> |
10002b34: 10 00 16 2c l.bf 100083e4 <_end+0x43d4> |
10002b38: 10 00 16 2c l.bf 100083e8 <_end+0x43d8> |
10002b3c: 10 00 16 2c l.bf 100083ec <_end+0x43dc> |
10002b40: 10 00 16 2c l.bf 100083f0 <_end+0x43e0> |
10002b44: 10 00 18 c4 l.bf 10008e54 <_end+0x4e44> |
10002b48: 10 00 18 ac l.bf 10008df8 <_end+0x4de8> |
10002b4c: 10 00 16 2c l.bf 100083fc <_end+0x43ec> |
10002b50: 10 00 16 2c l.bf 10008400 <_end+0x43f0> |
10002b54: 10 00 16 2c l.bf 10008404 <_end+0x43f4> |
10002b58: 10 00 16 2c l.bf 10008408 <_end+0x43f8> |
10002b5c: 10 00 16 2c l.bf 1000840c <_end+0x43fc> |
10002b60: 10 00 16 2c l.bf 10008410 <_end+0x4400> |
10002b64: 10 00 16 2c l.bf 10008414 <_end+0x4404> |
10002b68: 10 00 16 2c l.bf 10008418 <_end+0x4408> |
10002b6c: 10 00 16 2c l.bf 1000841c <_end+0x440c> |
10002b70: 10 00 16 2c l.bf 10008420 <_end+0x4410> |
10002b74: 10 00 16 2c l.bf 10008424 <_end+0x4414> |
10002b78: 10 00 16 2c l.bf 10008428 <_end+0x4418> |
10002b7c: 10 00 16 2c l.bf 1000842c <_end+0x441c> |
10002b80: 10 00 16 2c l.bf 10008430 <_end+0x4420> |
10002b84: 10 00 16 2c l.bf 10008434 <_end+0x4424> |
10002b88: 10 00 16 2c l.bf 10008438 <_end+0x4428> |
10002b8c: 10 00 16 2c l.bf 1000843c <_end+0x442c> |
10002b90: 10 00 16 2c l.bf 10008440 <_end+0x4430> |
10002b94: 10 00 16 2c l.bf 10008444 <_end+0x4434> |
10002b98: 10 00 16 2c l.bf 10008448 <_end+0x4438> |
10002b9c: 10 00 16 2c l.bf 1000844c <_end+0x443c> |
10002ba0: 10 00 16 2c l.bf 10008450 <_end+0x4440> |
10002ba4: 10 00 16 2c l.bf 10008454 <_end+0x4444> |
10002ba8: 10 00 16 2c l.bf 10008458 <_end+0x4448> |
10002bac: 10 00 16 2c l.bf 1000845c <_end+0x444c> |
10002bb0: 10 00 16 2c l.bf 10008460 <_end+0x4450> |
10002bb4: 10 00 16 2c l.bf 10008464 <_end+0x4454> |
10002bb8: 10 00 16 2c l.bf 10008468 <_end+0x4458> |
10002bbc: 10 00 16 2c l.bf 1000846c <_end+0x445c> |
10002bc0: 10 00 16 2c l.bf 10008470 <_end+0x4460> |
10002bc4: 10 00 16 2c l.bf 10008474 <_end+0x4464> |
10002bc8: 10 00 16 2c l.bf 10008478 <_end+0x4468> |
10002bcc: 10 00 16 2c l.bf 1000847c <_end+0x446c> |
10002bd0: 10 00 16 2c l.bf 10008480 <_end+0x4470> |
10002bd4: 10 00 16 2c l.bf 10008484 <_end+0x4474> |
10002bd8: 10 00 16 2c l.bf 10008488 <_end+0x4478> |
10002bdc: 10 00 16 2c l.bf 1000848c <_end+0x447c> |
10002be0: 10 00 16 2c l.bf 10008490 <_end+0x4480> |
10002be4: 10 00 16 2c l.bf 10008494 <_end+0x4484> |
10002be8: 10 00 16 2c l.bf 10008498 <_end+0x4488> |
10002bec: 10 00 16 2c l.bf 1000849c <_end+0x448c> |
10002bf0: 10 00 16 2c l.bf 100084a0 <_end+0x4490> |
10002bf4: 10 00 16 2c l.bf 100084a4 <_end+0x4494> |
10002bf8: 10 00 16 2c l.bf 100084a8 <_end+0x4498> |
10002bfc: 10 00 16 2c l.bf 100084ac <_end+0x449c> |
10002c00: 10 00 18 7c l.bf 10008df0 <_end+0x4de0> |
10002c04: 10 00 16 2c l.bf 100084b4 <_end+0x44a4> |
10002c08: 10 00 16 2c l.bf 100084b8 <_end+0x44a8> |
10002c0c: 10 00 16 2c l.bf 100084bc <_end+0x44ac> |
10002c10: 10 00 16 2c l.bf 100084c0 <_end+0x44b0> |
10002c14: 10 00 16 2c l.bf 100084c4 <_end+0x44b4> |
10002c18: 10 00 16 2c l.bf 100084c8 <_end+0x44b8> |
10002c1c: 10 00 18 68 l.bf 10008dbc <_end+0x4dac> |
10002c20: 10 00 18 50 l.bf 10008d60 <_end+0x4d50> |
10002c24: 10 00 16 2c l.bf 100084d4 <_end+0x44c4> |
10002c28: 10 00 16 2c l.bf 100084d8 <_end+0x44c8> |
10002c2c: 10 00 16 2c l.bf 100084dc <_end+0x44cc> |
10002c30: 10 00 16 2c l.bf 100084e0 <_end+0x44d0> |
10002c34: 10 00 16 2c l.bf 100084e4 <_end+0x44d4> |
10002c38: 10 00 16 2c l.bf 100084e8 <_end+0x44d8> |
10002c3c: 10 00 16 2c l.bf 100084ec <_end+0x44dc> |
10002c40: 10 00 18 3c l.bf 10008d30 <_end+0x4d20> |
10002c44: 10 00 16 2c l.bf 100084f4 <_end+0x44e4> |
10002c48: 10 00 16 2c l.bf 100084f8 <_end+0x44e8> |
10002c4c: 10 00 16 2c l.bf 100084fc <_end+0x44ec> |
10002c50: 10 00 18 1c l.bf 10008cc0 <_end+0x4cb0> |
10002c54: 10 00 16 2c l.bf 10008504 <_end+0x44f4> |
10002c58: 10 00 16 2c l.bf 10008508 <_end+0x44f8> |
10002c5c: 10 00 17 34 l.bf 1000892c <_end+0x491c> |
10002c60: 10 00 16 2c l.bf 10008510 <_end+0x4500> |
10002c64: 10 00 16 2c l.bf 10008514 <_end+0x4504> |
10002c68: 10 00 16 2c l.bf 10008518 <_end+0x4508> |
10002c6c: 10 00 16 2c l.bf 1000851c <_end+0x450c> |
10002c70: 10 00 18 1c l.bf 10008ce0 <_end+0x4cd0> |
10002c74: 41 73 73 65 *unknown* |
10002c78: 72 74 20 66 *unknown* |
10002c7c: 61 69 6c 65 *unknown* |
10002c80: 64 3a 20 25 *unknown* |
10002c84: 73 20 28 25 *unknown* |
10002c88: 73 3a 25 64 *unknown* |
10002c8c: 29 0a 00 22 *unknown* |
10002c90: 53 59 53 43 *unknown* |
10002c94: 41 4c 4c 21 *unknown* |
10002c98: 22 00 2e 2e *unknown* |
10002c9c: 2f 63 6f 6d *unknown* |
10002ca0: 6d 6f 6e 2f *unknown* |
10002ca4: 65 78 63 65 *unknown* |
10002ca8: 70 74 69 6f *unknown* |
10002cac: 6e 2e 63 00 *unknown* |
10002cb0: 22 42 52 45 *unknown* |
10002cb4: 41 4b 21 22 *unknown* |
10002cb8: 00 22 45 58 l.j 10894218 <_end+0x890208> |
10002cbc: 54 5f 49 4e *unknown* |
10002cc0: 54 21 22 00 *unknown* |
10002cc4: 22 46 41 55 *unknown* |
10002cc8: 4c 54 22 00 *unknown* |
10002ccc: 22 4d 55 4c *unknown* |
10002cd0: 54 21 22 00 *unknown* |
10002cd4: 22 55 4d 55 *unknown* |
10002cd8: 4c 54 21 22 *unknown* |
10002cdc: 00 22 44 49 l.j 10893e00 <_end+0x88fdf0> |
10002ce0: 56 21 22 00 *unknown* |
10002ce4: 22 55 44 49 *unknown* |
10002ce8: 56 21 22 00 *unknown* |
10002cec: 22 55 4e 4b *unknown* |
10002cf0: 4e 4f 57 4e *unknown* |
10002cf4: 22 00 72 65 *unknown* |
10002cf8: 63 75 72 73 *unknown* |
10002cfc: 69 76 65 5f *unknown* |
10002d00: 69 6e 74 20 *unknown* |
10002d04: 3d 3d 20 30 *unknown* |
10002d08: 00 0a 54 65 l.j 10297e9c <_end+0x293e8c> |
10002d0c: 73 74 3a 0a *unknown* |
10002d10: 00 31 2e 20 l.j 10c4e590 <_end+0xc4a580> |
10002d14: 49 6e 69 74 *unknown* |
10002d18: 69 61 6c 69 *unknown* |
10002d1c: 73 65 64 20 *unknown* |
10002d20: 64 61 74 61 *unknown* |
10002d24: 0a 00 76 61 *unknown* |
10002d28: 72 20 3d 3d *unknown* |
10002d2c: 20 30 78 31 *unknown* |
10002d30: 32 33 34 00 *unknown* |
10002d34: 74 65 73 74 *unknown* |
10002d38: 2e 63 00 75 *unknown* |
10002d3c: 76 61 72 20 *unknown* |
10002d40: 3d 3d 20 30 *unknown* |
10002d44: 78 30 00 32 *unknown* |
10002d48: 2e 20 4d 75 *unknown* |
10002d4c: 6c 74 69 70 *unknown* |
10002d50: 6c 79 0a 00 *unknown* |
10002d54: 76 61 72 20 *unknown* |
10002d58: 3d 3d 20 31 *unknown* |
10002d5c: 33 39 38 30 *unknown* |
10002d60: 00 76 61 72 l.j 11d9b328 <_end+0x1d97318> |
10002d64: 20 3d 3d 20 *unknown* |
10002d68: 2d 33 00 76 *unknown* |
10002d6c: 61 72 20 3d *unknown* |
10002d70: 3d 20 2d 36 *unknown* |
10002d74: 35 00 76 61 *unknown* |
10002d78: 72 20 3d 3d *unknown* |
10002d7c: 20 28 2d 35 *unknown* |
10002d80: 2a 2d 31 33 *unknown* |
10002d84: 29 00 76 61 *unknown* |
10002d88: 72 20 3d 3d *unknown* |
10002d8c: 20 28 2d 31 *unknown* |
10002d90: 32 33 31 32 *unknown* |
10002d94: 33 34 31 35 *unknown* |
10002d98: 2a 39 36 36 *unknown* |
10002d9c: 34 35 36 33 *unknown* |
10002da0: 29 00 33 2e *unknown* |
10002da4: 20 44 69 76 *unknown* |
10002da8: 69 64 65 0a *unknown* |
10002dac: 00 76 61 72 l.j 11d9b374 <_end+0x1d97364> |
10002db0: 20 3d 3d 20 *unknown* |
10002db4: 32 37 39 36 *unknown* |
10002db8: 00 76 61 72 l.j 11d9b380 <_end+0x1d97370> |
10002dbc: 20 3d 3d 20 *unknown* |
10002dc0: 39 36 00 76 *unknown* |
10002dc4: 61 72 20 3d *unknown* |
10002dc8: 3d 20 2d 36 *unknown* |
10002dcc: 37 00 34 2e *unknown* |
10002dd0: 20 53 68 69 *unknown* |
10002dd4: 66 74 20 6c *unknown* |
10002dd8: 65 66 74 0a *unknown* |
10002ddc: 00 76 61 72 l.j 11d9b3a4 <_end+0x1d97394> |
10002de0: 20 3d 3d 20 *unknown* |
10002de4: 30 78 38 30 *unknown* |
10002de8: 30 30 30 30 *unknown* |
10002dec: 30 30 00 35 *unknown* |
10002df0: 2e 20 53 68 *unknown* |
10002df4: 69 66 74 20 *unknown* |
10002df8: 72 69 67 68 *unknown* |
10002dfc: 74 0a 00 75 *unknown* |
10002e00: 76 61 72 20 *unknown* |
10002e04: 3d 3d 20 30 *unknown* |
10002e08: 78 34 30 30 *unknown* |
10002e0c: 30 30 30 30 *unknown* |
10002e10: 30 00 75 76 *unknown* |
10002e14: 61 72 20 3d *unknown* |
10002e18: 3d 20 30 78 *unknown* |
10002e1c: 30 30 30 30 *unknown* |
10002e20: 30 30 30 31 *unknown* |
10002e24: 00 36 2e 20 l.j 10d8e6a4 <_end+0xd8a694> |
10002e28: 53 68 69 66 *unknown* |
10002e2c: 74 20 72 69 *unknown* |
10002e30: 67 68 74 20 *unknown* |
10002e34: 61 72 69 74 *unknown* |
10002e38: 68 6d 65 74 *unknown* |
10002e3c: 69 63 0a 00 *unknown* |
10002e40: 76 61 72 20 *unknown* |
10002e44: 3d 3d 20 30 *unknown* |
10002e48: 78 43 30 30 *unknown* |
10002e4c: 30 30 30 30 *unknown* |
10002e50: 30 00 37 2e *unknown* |
10002e54: 20 53 69 67 *unknown* |
10002e58: 6e 65 64 20 *unknown* |
10002e5c: 63 6f 6d 70 *unknown* |
10002e60: 61 72 69 73 *unknown* |
10002e64: 69 6f 6e 0a *unknown* |
10002e68: 00 76 61 72 l.j 11d9b430 <_end+0x1d97420> |
10002e6c: 20 3c 20 31 *unknown* |
10002e70: 00 76 61 72 l.j 11d9b438 <_end+0x1d97428> |
10002e74: 20 3c 20 78 *unknown* |
10002e78: 00 21 28 76 l.j 1084d050 <_end+0x849040> |
10002e7c: 61 72 20 3e *unknown* |
10002e80: 20 78 29 00 *unknown* |
10002e84: 76 61 72 20 *unknown* |
10002e88: 3e 20 78 00 *unknown* |
10002e8c: 78 20 3c 3d *unknown* |
10002e90: 20 76 61 72 *unknown* |
10002e94: 00 38 2e 20 l.j 10e0e714 <_end+0xe0a704> |
10002e98: 57 6f 72 64 *unknown* |
10002e9c: 20 61 63 63 *unknown* |
10002ea0: 65 73 73 0a *unknown* |
10002ea4: 00 75 76 61 l.j 11d60828 <_end+0x1d5c818> |
10002ea8: 72 20 3d 3d *unknown* |
10002eac: 20 30 78 31 *unknown* |
10002eb0: 32 33 34 35 *unknown* |
10002eb4: 36 37 38 00 *unknown* |
10002eb8: 73 77 20 3d *unknown* |
10002ebc: 3d 20 30 78 *unknown* |
10002ec0: 35 36 37 38 *unknown* |
10002ec4: 00 2a 70 73 l.j 10a9f090 <_end+0xa9b080> |
10002ec8: 77 2b 2b 20 *unknown* |
10002ecc: 3d 3d 20 30 *unknown* |
10002ed0: 78 31 32 33 *unknown* |
10002ed4: 34 00 2a 70 *unknown* |
10002ed8: 73 77 2b 2b *unknown* |
10002edc: 20 3d 3d 20 *unknown* |
10002ee0: 30 78 35 36 *unknown* |
10002ee4: 37 38 00 2a *unknown* |
10002ee8: 70 73 77 2b *unknown* |
10002eec: 2b 20 3d 3d *unknown* |
10002ef0: 20 30 78 63 *unknown* |
10002ef4: 61 66 65 00 *unknown* |
10002ef8: 2a 70 73 77 *unknown* |
10002efc: 2b 2b 20 3d *unknown* |
10002f00: 3d 20 30 78 *unknown* |
10002f04: 62 61 62 65 *unknown* |
10002f08: 00 39 2e 20 l.j 10e4e788 <_end+0xe4a778> |
10002f0c: 42 79 74 65 *unknown* |
10002f10: 20 61 63 63 *unknown* |
10002f14: 65 73 73 0a *unknown* |
10002f18: 00 73 62 20 l.j 11cdb798 <_end+0x1cd7788> |
10002f1c: 3d 3d 20 30 *unknown* |
10002f20: 78 37 38 00 *unknown* |
10002f24: 2a 70 73 62 *unknown* |
10002f28: 2b 2b 20 3d *unknown* |
10002f2c: 3d 20 30 78 *unknown* |
10002f30: 31 32 00 2a *unknown* |
10002f34: 70 73 62 2b *unknown* |
10002f38: 2b 20 3d 3d *unknown* |
10002f3c: 20 30 78 33 *unknown* |
10002f40: 34 00 2a 70 *unknown* |
10002f44: 73 62 2b 2b *unknown* |
10002f48: 20 3d 3d 20 *unknown* |
10002f4c: 30 78 35 36 *unknown* |
10002f50: 00 2a 70 73 l.j 10a9f11c <_end+0xa9b10c> |
10002f54: 62 2b 2b 20 *unknown* |
10002f58: 3d 3d 20 30 *unknown* |
10002f5c: 78 37 38 00 *unknown* |
10002f60: 75 76 61 72 *unknown* |
10002f64: 20 3d 3d 20 *unknown* |
10002f68: 30 78 61 62 *unknown* |
10002f6c: 33 34 35 36 *unknown* |
10002f70: 37 38 00 75 *unknown* |
10002f74: 76 61 72 20 *unknown* |
10002f78: 3d 3d 20 30 *unknown* |
10002f7c: 78 61 62 63 *unknown* |
10002f80: 64 35 36 37 *unknown* |
10002f84: 38 00 75 76 *unknown* |
10002f88: 61 72 20 3d *unknown* |
10002f8c: 3d 20 30 78 *unknown* |
10002f90: 61 62 63 64 *unknown* |
10002f94: 65 66 37 38 *unknown* |
10002f98: 00 75 76 61 l.j 11d6091c <_end+0x1d5c90c> |
10002f9c: 72 20 3d 3d *unknown* |
10002fa0: 20 30 78 61 *unknown* |
10002fa4: 62 63 64 65 *unknown* |
10002fa8: 66 30 31 00 *unknown* |
10002fac: 31 30 2e 20 *unknown* |
10002fb0: 43 6f 6d 70 *unknown* |
10002fb4: 61 72 69 73 *unknown* |
10002fb8: 69 6f 6e 0a *unknown* |
10002fbc: 00 2d 20 49 l.j 10b4b0e0 <_end+0xb470d0> |
10002fc0: 6e 63 6f 72 *unknown* |
10002fc4: 72 65 63 74 *unknown* |
10002fc8: 20 63 6f 6d *unknown* |
10002fcc: 70 61 72 69 *unknown* |
10002fd0: 73 69 6f 6e *unknown* |
10002fd4: 0a 00 00 00 *unknown* |
/trunk/rtl/sim_icarus/ram.v
0,0 → 1,188
//----------------------------------------------------------------- |
// AltOR32 |
// Alternative Lightweight OpenRisc |
// V2.0 |
// Ultra-Embedded.com |
// Copyright 2011 - 2013 |
// |
// Email: admin@ultra-embedded.com |
// |
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
// removed from the file and that any derivative work contains |
// the original copyright notice and the associated disclaimer. |
// |
// This source file is free software; you can redistribute it |
// and/or modify it under the terms of the GNU Lesser General |
// Public License as published by the Free Software Foundation; |
// either version 2.1 of the License, or (at your option) any |
// later version. |
// |
// This source is distributed in the hope that it will be |
// useful, but WITHOUT ANY WARRANTY; without even the implied |
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU Lesser General Public License for more |
// details. |
// |
// You should have received a copy of the GNU Lesser General |
// Public License along with this source; if not, write to the |
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
// Boston, MA 02111-1307 USA |
//----------------------------------------------------------------- |
|
//----------------------------------------------------------------- |
// Module: ram - dual port block RAM |
//----------------------------------------------------------------- |
module ram |
( |
// Port A |
input clka_i /*verilator public*/, |
input rsta_i /*verilator public*/, |
input stba_i /*verilator public*/, |
input wea_i /*verilator public*/, |
input [3:0] sela_i /*verilator public*/, |
input [31:2] addra_i /*verilator public*/, |
input [31:0] dataa_i /*verilator public*/, |
output [31:0] dataa_o /*verilator public*/, |
output reg acka_o /*verilator public*/, |
|
// Port B |
input clkb_i /*verilator public*/, |
input rstb_i /*verilator public*/, |
input stbb_i /*verilator public*/, |
input web_i /*verilator public*/, |
input [3:0] selb_i /*verilator public*/, |
input [31:2] addrb_i /*verilator public*/, |
input [31:0] datab_i /*verilator public*/, |
output [31:0] datab_o /*verilator public*/, |
output reg ackb_o /*verilator public*/ |
); |
|
//----------------------------------------------------------------- |
// Params |
//----------------------------------------------------------------- |
parameter [31:0] SIZE = 14; |
|
//----------------------------------------------------------------- |
// Instantiation |
//----------------------------------------------------------------- |
|
wire [3:0] wr_a = {4{stba_i}} & {4{wea_i}} & sela_i; |
wire [3:0] wr_b = {4{stbb_i}} & {4{web_i}} & selb_i; |
|
ram_dp8 |
#( |
.WIDTH(8), |
.SIZE(SIZE), |
.FILENAME("mem_3.hex") |
) |
u0 |
( |
.aclk_i(clka_i), |
.aadr_i(addra_i[SIZE+2-1:2]), |
.adat_o(dataa_o[7:0]), |
.adat_i(dataa_i[7:0]), |
.awr_i(wr_a[0]), |
|
.bclk_i(clkb_i), |
.badr_i(addrb_i[SIZE+2-1:2]), |
.bdat_o(datab_o[7:0]), |
.bdat_i(datab_i[7:0]), |
.bwr_i(wr_b[0]) |
); |
|
ram_dp8 |
#( |
.WIDTH(8), |
.SIZE(SIZE), |
.FILENAME("mem_2.hex") |
) |
u1 |
( |
.aclk_i(clka_i), |
.aadr_i(addra_i[SIZE+2-1:2]), |
.adat_o(dataa_o[15:8]), |
.adat_i(dataa_i[15:8]), |
.awr_i(wr_a[1]), |
|
.bclk_i(clkb_i), |
.badr_i(addrb_i[SIZE+2-1:2]), |
.bdat_o(datab_o[15:8]), |
.bdat_i(datab_i[15:8]), |
.bwr_i(wr_b[1]) |
); |
|
ram_dp8 |
#( |
.WIDTH(8), |
.SIZE(SIZE), |
.FILENAME("mem_1.hex") |
) |
u2 |
( |
.aclk_i(clka_i), |
.aadr_i(addra_i[SIZE+2-1:2]), |
.adat_o(dataa_o[23:16]), |
.adat_i(dataa_i[23:16]), |
.awr_i(wr_a[2]), |
|
.bclk_i(clkb_i), |
.badr_i(addrb_i[SIZE+2-1:2]), |
.bdat_o(datab_o[23:16]), |
.bdat_i(datab_i[23:16]), |
.bwr_i(wr_b[2]) |
); |
|
ram_dp8 |
#( |
.WIDTH(8), |
.SIZE(SIZE), |
.FILENAME("mem_0.hex") |
) |
u3 |
( |
.aclk_i(clka_i), |
.aadr_i(addra_i[SIZE+2-1:2]), |
.adat_o(dataa_o[31:24]), |
.adat_i(dataa_i[31:24]), |
.awr_i(wr_a[3]), |
|
.bclk_i(clkb_i), |
.badr_i(addrb_i[SIZE+2-1:2]), |
.bdat_o(datab_o[31:24]), |
.bdat_i(datab_i[31:24]), |
.bwr_i(wr_b[3]) |
); |
|
// AckA |
always @(posedge clka_i or posedge rsta_i) |
begin |
if (rsta_i == 1'b1) |
begin |
acka_o <= 1'b0; |
end |
else |
begin |
acka_o <= stba_i; |
end |
end |
|
// AckB |
always @(posedge clkb_i or posedge rstb_i) |
begin |
if (rstb_i == 1'b1) |
begin |
ackb_o <= 1'b0; |
end |
else |
begin |
ackb_o <= stbb_i; |
end |
end |
|
endmodule |
/trunk/rtl/sim_icarus/top.v
0,0 → 1,211
//----------------------------------------------------------------- |
// AltOR32 |
// Alternative Lightweight OpenRisc |
// V2.0 |
// Ultra-Embedded.com |
// Copyright 2011 - 2013 |
// |
// Email: admin@ultra-embedded.com |
// |
// License: LGPL |
//----------------------------------------------------------------- |
// |
// Copyright (C) 2011 - 2013 Ultra-Embedded.com |
// |
// This source file may be used and distributed without |
// restriction provided that this copyright statement is not |
// removed from the file and that any derivative work contains |
// the original copyright notice and the associated disclaimer. |
// |
// This source file is free software; you can redistribute it |
// and/or modify it under the terms of the GNU Lesser General |
// Public License as published by the Free Software Foundation; |
// either version 2.1 of the License, or (at your option) any |
// later version. |
// |
// This source is distributed in the hope that it will be |
// useful, but WITHOUT ANY WARRANTY; without even the implied |
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU Lesser General Public License for more |
// details. |
// |
// You should have received a copy of the GNU Lesser General |
// Public License along with this source; if not, write to the |
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
// Boston, MA 02111-1307 USA |
//----------------------------------------------------------------- |
|
//----------------------------------------------------------------- |
// Module |
//----------------------------------------------------------------- |
module top |
( |
// Clocking & Reset |
input clk_i, |
input rst_i, |
// Fault Output |
output fault_o, |
// Break Output |
output break_o, |
// Interrupt Input |
input intr_i |
); |
|
//----------------------------------------------------------------- |
// Params |
//----------------------------------------------------------------- |
parameter CLK_KHZ = 8192; |
parameter BOOT_VECTOR = 32'h10000000; |
parameter ISR_VECTOR = 32'h10000000; |
|
//----------------------------------------------------------------- |
// Registers / Wires |
//----------------------------------------------------------------- |
wire [31:0] soc_addr; |
wire [31:0] soc_data_w; |
wire [31:0] soc_data_r; |
wire soc_we; |
wire soc_stb; |
wire soc_ack; |
wire soc_irq; |
|
wire[31:0] dmem_address; |
wire[31:0] dmem_data_w; |
wire[31:0] dmem_data_r; |
wire[3:0] dmem_sel; |
wire[2:0] dmem_cti; |
wire dmem_we; |
wire dmem_stb; |
wire dmem_cyc; |
wire dmem_stall; |
wire dmem_ack; |
|
wire[31:0] imem_addr; |
wire[31:0] imem_data; |
wire[3:0] imem_sel; |
wire imem_stb; |
wire imem_cyc; |
wire[2:0] imem_cti; |
wire imem_stall; |
wire imem_ack; |
|
|
//----------------------------------------------------------------- |
// Instantiation |
//----------------------------------------------------------------- |
ram |
u_ram |
( |
.clka_i(clk_i), |
.rsta_i(rst_i), |
.stba_i(imem_stb), |
.wea_i(1'b0), |
.sela_i(imem_sel), |
.addra_i(imem_addr[31:2]), |
.dataa_i(32'b0), |
.dataa_o(imem_data), |
.acka_o(imem_ack), |
|
.clkb_i(clk_i), |
.rstb_i(rst_i), |
.stbb_i(dmem_stb), |
.web_i(dmem_we), |
.selb_i(dmem_sel), |
.addrb_i(dmem_address[31:2]), |
.datab_i(dmem_data_w), |
.datab_o(dmem_data_r), |
.ackb_o(dmem_ack) |
); |
|
cpu_if |
#( |
.CLK_KHZ(CLK_KHZ), |
.BOOT_VECTOR(32'h10000000), |
.ISR_VECTOR(32'h10000000), |
.ENABLE_ICACHE(`ICACHE_ENABLED), |
.ENABLE_DCACHE(`DCACHE_ENABLED), |
.REGISTER_FILE_TYPE("SIMULATION") |
) |
u_cpu |
( |
// General - clocking & reset |
.clk_i(clk_i), |
.rst_i(rst_i), |
.fault_o(fault_o), |
.break_o(break_o), |
.nmi_i(1'b0), |
.intr_i(soc_irq), |
|
// Instruction Memory 0 (0x10000000 - 0x10FFFFFF) |
.imem0_addr_o(imem_addr), |
.imem0_data_i(imem_data), |
.imem0_sel_o(imem_sel), |
.imem0_cti_o(imem_cti), |
.imem0_cyc_o(imem_cyc), |
.imem0_stb_o(imem_stb), |
.imem0_stall_i(1'b0), |
.imem0_ack_i(imem_ack), |
|
// Data Memory 0 (0x10000000 - 0x10FFFFFF) |
.dmem0_addr_o(dmem_address), |
.dmem0_data_o(dmem_data_w), |
.dmem0_data_i(dmem_data_r), |
.dmem0_sel_o(dmem_sel), |
.dmem0_cti_o(dmem_cti), |
.dmem0_cyc_o(dmem_cyc), |
.dmem0_we_o(dmem_we), |
.dmem0_stb_o(dmem_stb), |
.dmem0_stall_i(1'b0), |
.dmem0_ack_i(dmem_ack), |
|
// Data Memory 1 (0x11000000 - 0x11FFFFFF) |
.dmem1_addr_o(/*open*/), |
.dmem1_data_o(/*open*/), |
.dmem1_data_i(32'b0), |
.dmem1_sel_o(/*open*/), |
.dmem1_we_o(/*open*/), |
.dmem1_stb_o(/*open*/), |
.dmem1_cyc_o(/*open*/), |
.dmem1_cti_o(/*open*/), |
.dmem1_stall_i(1'b0), |
.dmem1_ack_i(1'b1), |
|
// Data Memory 2 (0x12000000 - 0x12FFFFFF) |
.dmem2_addr_o(soc_addr), |
.dmem2_data_o(soc_data_w), |
.dmem2_data_i(soc_data_r), |
.dmem2_sel_o(/*open*/), |
.dmem2_we_o(soc_we), |
.dmem2_stb_o(soc_stb), |
.dmem2_cyc_o(/*open*/), |
.dmem2_cti_o(/*open*/), |
.dmem2_stall_i(1'b0), |
.dmem2_ack_i(soc_ack) |
); |
|
// CPU SOC |
soc |
#( |
.CLK_KHZ(CLK_KHZ), |
.ENABLE_SYSTICK_TIMER("ENABLED"), |
.ENABLE_HIGHRES_TIMER("ENABLED"), |
.EXTERNAL_INTERRUPTS(1) |
) |
u_soc |
( |
// General - clocking & reset |
.clk_i(clk_i), |
.rst_i(rst_i), |
.ext_intr_i(1'b0), |
.intr_o(soc_irq), |
|
// Memory Port |
.io_addr_i(soc_addr), |
.io_data_i(soc_data_w), |
.io_data_o(soc_data_r), |
.io_we_i(soc_we), |
.io_stb_i(soc_stb), |
.io_ack_o(soc_ack) |
); |
|
endmodule |
/trunk/rtl/sim_icarus/test_image.elf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
trunk/rtl/sim_icarus/test_image.elf
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/rtl/sim_icarus/test_image.bin
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/rtl/sim_icarus/test_image.bin
===================================================================
--- trunk/rtl/sim_icarus/test_image.bin (nonexistent)
+++ trunk/rtl/sim_icarus/test_image.bin (revision 37)
trunk/rtl/sim_icarus/test_image.bin
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/rtl/sim_icarus/top_tb.v
===================================================================
--- trunk/rtl/sim_icarus/top_tb.v (nonexistent)
+++ trunk/rtl/sim_icarus/top_tb.v (revision 37)
@@ -0,0 +1,72 @@
+`timescale 1ns/10ps
+
+//-----------------------------------------------------------------
+// Module
+//-----------------------------------------------------------------
+module top_tb ;
+
+//-----------------------------------------------------------------
+// Registers / Wires
+//-----------------------------------------------------------------
+reg clk;
+reg rst;
+wire fault;
+wire break;
+
+//-----------------------------------------------------------------
+// Instantiation
+//-----------------------------------------------------------------
+top
+u_top
+(
+ .clk_i(clk),
+ .rst_i(rst),
+ .fault_o(fault),
+ .break_o(break),
+ .intr_i(1'b0)
+);
+
+//-----------------------------------------------------------------
+// Test
+//-----------------------------------------------------------------
+initial
+begin
+ clk = 0;
+ rst = 1;
+ $dumpfile("waveform.vcd");
+ $dumpvars(0,top_tb);
+
+#(31.25*2) rst = 0;
+end
+
+always
+begin
+ #31.25 clk = ! clk;
+end
+
+integer cycle_count;
+
+always @(posedge clk or posedge rst)
+begin
+ if (rst)
+ begin
+ cycle_count = 0;
+ end
+ else
+ begin
+ cycle_count = cycle_count + 1;
+
+ if (fault)
+ begin
+ $display("Fault detected");
+ $finish;
+ end
+ else if (break)
+ begin
+ $display("Completed after %2d cycles", cycle_count);
+ $finish;
+ end
+ end
+end
+
+endmodule
Index: trunk/rtl/sim_icarus/readmem.c
===================================================================
--- trunk/rtl/sim_icarus/readmem.c (nonexistent)
+++ trunk/rtl/sim_icarus/readmem.c (revision 37)
@@ -0,0 +1,82 @@
+#include
+#include
+#include
+#include
+
+#include
+
+//-----------------------------------------------------------------
+// main:
+//-----------------------------------------------------------------
+int main(int argc, char *argv[])
+{
+ int c;
+ FILE *f;
+ char filename[256];
+ int help = 0;
+ int offset = 0;
+
+ filename[0] = 0;
+
+ while ((c = getopt(argc, argv, "hf:o:")) != EOF)
+ {
+ switch (c)
+ {
+ case 'h':
+ help = 1;
+ break;
+ case 'o':
+ offset = strtoul(optarg, NULL, 0);
+ case 'f':
+ strcpy(filename, optarg);
+ break;
+ }
+ }
+
+ if (filename[0] == '\0' || help)
+ {
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, " -f inputFile\n");
+ fprintf(stderr, " -o offset\n");
+ return help ? 0 : 1;
+ }
+
+ f = fopen(filename, "rb");
+ if (f)
+ {
+ int i,w,s;
+ unsigned int size;
+ unsigned int words;
+ unsigned char buf;
+ unsigned char data;
+
+ // Get size
+ fseek(f, 0, SEEK_END);
+ size = ftell(f);
+ rewind(f);
+
+ fseek(f, offset, SEEK_SET);
+
+ for (i=0;i mem_0.hex
+ ./readmem -o 1 -f $(TEST_IMAGE) > mem_1.hex
+ ./readmem -o 2 -f $(TEST_IMAGE) > mem_2.hex
+ ./readmem -o 3 -f $(TEST_IMAGE) > mem_3.hex
+
+check:
+ $(VERILOG_CMD) -t null $(SRC) $(INC_DIRS) $(SRC_FLAGS)
+
+compile :
+ $(VERILOG_CMD) -o output.out $(SRC) $(INC_DIRS) $(SRC_FLAGS)
+
+run : compile memory_img
+ $(VVP_CMD) output.out -$(DUMPTYPE) $(VVP_FLAGS)
+
+view : compile
+ $(WAVEFORM_VIEWER) waveform.vcd gtksettings.sav
+
+clean :
+ -rm output.out waveform.vcd *.hex readmem
+
Index: trunk/rtl/sim_icarus/ram_dp8.v
===================================================================
--- trunk/rtl/sim_icarus/ram_dp8.v (nonexistent)
+++ trunk/rtl/sim_icarus/ram_dp8.v (revision 37)
@@ -0,0 +1,124 @@
+//-----------------------------------------------------------------
+// AltOR32
+// Alternative Lightweight OpenRisc
+// V2.0
+// Ultra-Embedded.com
+// Copyright 2011 - 2013
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//-----------------------------------------------------------------
+//
+// Copyright (C) 2011 - 2013 Ultra-Embedded.com
+//
+// This source file may be used and distributed without
+// restriction provided that this copyright statement is not
+// removed from the file and that any derivative work contains
+// the original copyright notice and the associated disclaimer.
+//
+// This source file is free software; you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation;
+// either version 2.1 of the License, or (at your option) any
+// later version.
+//
+// This source is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied
+// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General
+// Public License along with this source; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Module: ram_dp8 - dual port block RAM
+//-----------------------------------------------------------------
+module ram_dp8
+(
+ aclk_i,
+ aadr_i,
+ adat_i,
+ awr_i,
+ adat_o,
+
+ bclk_i,
+ badr_i,
+ bdat_i,
+ bwr_i,
+ bdat_o
+);
+
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+parameter [31:0] WIDTH = 8;
+parameter [31:0] SIZE = 14;
+parameter FILENAME = "mem.hex";
+
+//-----------------------------------------------------------------
+// I/O
+//-----------------------------------------------------------------
+input aclk_i /*verilator public*/;
+output [(WIDTH - 1):0] adat_o /*verilator public*/;
+input [(WIDTH - 1):0] adat_i /*verilator public*/;
+input [(SIZE - 1):0] aadr_i /*verilator public*/;
+input awr_i /*verilator public*/;
+input bclk_i /*verilator public*/;
+output [(WIDTH - 1):0] bdat_o /*verilator public*/;
+input [(WIDTH - 1):0] bdat_i /*verilator public*/;
+input [(SIZE - 1):0] badr_i /*verilator public*/;
+input bwr_i /*verilator public*/;
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+/* verilator lint_off MULTIDRIVEN */
+reg [(WIDTH - 1):0] ram [((2<< (SIZE-1)) - 1):0] /*verilator public*/;
+/* verilator lint_on MULTIDRIVEN */
+
+reg [(SIZE - 1):0] rd_addr_a;
+reg [(SIZE - 1):0] rd_addr_b;
+wire [(WIDTH - 1):0] adat_o;
+wire [(WIDTH - 1):0] bdat_o;
+
+//-----------------------------------------------------------------
+// Processes
+//-----------------------------------------------------------------
+always @ (posedge aclk_i)
+begin
+ if (awr_i == 1'b1)
+ ram[aadr_i] <= adat_i;
+ rd_addr_a <= aadr_i;
+end
+always @ (posedge bclk_i)
+begin
+ if (bwr_i == 1'b1)
+ ram[badr_i] <= bdat_i;
+ rd_addr_b <= badr_i;
+end
+
+//-------------------------------------------------------------------
+// Combinatorial
+//-------------------------------------------------------------------
+assign adat_o = ram[rd_addr_a];
+assign bdat_o = ram[rd_addr_b];
+
+//-----------------------------------------------------------------
+// Load memory image
+//-----------------------------------------------------------------
+integer i;
+initial
+begin
+ for (i=0;i<((2<< (SIZE-1)) - 1);i=i+1)
+ begin
+ ram[i] = 0;
+ end
+ $readmemh(FILENAME, ram);
+end
+
+endmodule