OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /altor32/trunk
    from Rev 36 to Rev 37
    Reverse comparison

Rev 36 → Rev 37

/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
/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
/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
 
/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
/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
/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
/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
/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
/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
/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
 
/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
/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
 
/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
/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
/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
/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
/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
/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
/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
/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
/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
/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
 
/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
/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
/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
/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
/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
/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);
/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*
/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
/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
/rtl/sim_icarus/test_image.elf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
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: rtl/sim_icarus/test_image.bin =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: rtl/sim_icarus/test_image.bin =================================================================== --- rtl/sim_icarus/test_image.bin (nonexistent) +++ rtl/sim_icarus/test_image.bin (revision 37)
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: rtl/sim_icarus/top_tb.v =================================================================== --- rtl/sim_icarus/top_tb.v (nonexistent) +++ 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: rtl/sim_icarus/readmem.c =================================================================== --- rtl/sim_icarus/readmem.c (nonexistent) +++ 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: rtl/sim_icarus/ram_dp8.v =================================================================== --- rtl/sim_icarus/ram_dp8.v (nonexistent) +++ 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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.