diff options
-rw-r--r-- | hdl/alu.v | 37 | ||||
-rw-r--r-- | hdl/alu_ctrl.v | 41 | ||||
-rw-r--r-- | hdl/control.v | 183 | ||||
-rw-r--r-- | hdl/dp_memory.v | 55 | ||||
-rw-r--r-- | hdl/ex_stage.v | 197 | ||||
-rw-r--r-- | hdl/forwarding_unit.v | 220 | ||||
-rw-r--r-- | hdl/hazard_unit.v | 98 | ||||
-rw-r--r-- | hdl/id_stage.v | 325 | ||||
-rw-r--r-- | hdl/if_stage.v | 108 | ||||
-rw-r--r-- | hdl/mips_system.v | 94 | ||||
-rw-r--r-- | hdl/pipeline.v | 447 | ||||
-rw-r--r-- | hdl/testbench.v | 116 | ||||
-rw-r--r-- | hdl/wb_stage.v | 10 | ||||
-rw-r--r-- | sw/test.axf | bin | 0 -> 66751 bytes | |||
-rw-r--r-- | sw/test.lst | 19 | ||||
-rw-r--r-- | sw/test.o | bin | 0 -> 808 bytes | |||
-rw-r--r-- | sw/test.rom | 6 | ||||
-rw-r--r-- | sw/test.vh | 6 |
18 files changed, 938 insertions, 1024 deletions
@@ -3,27 +3,24 @@ /** ALU Unit */ -module alu ( - input wire [4:0] alu_ctl, - input wire [31:0] a_in, b_in, - output reg [31:0] result, - output wire zero_flag - ); +module alu ( input [4:0] alu_ctl, + input [31:0] a_in, b_in, + output reg [31:0] result, + output zero_flag ); - assign zero_flag = (result == 0); + assign zero_flag = (result == 0); - always @(alu_ctl, a_in, b_in) begin // reevaluate if these change - case (alu_ctl) - 0: result = a_in & b_in; // bitwise and - 1: result = a_in | b_in; // bitwise or - 2: result = a_in + b_in; // addition - 6: result = a_in - b_in; // substraction - 7: result = a_in < b_in ? 1 : 0; // set on less than - 8: result = ~(a_in | b_in); // bitwise nor - 9: result = a_in ^ b_in; // bitwise xor - - default: result = 0; - endcase - end + always @(alu_ctl, a_in, b_in) begin // reevaluate if these change + case (alu_ctl) + 0: result = a_in & b_in; // bitwise and + 1: result = a_in | b_in; // bitwise or + 2: result = a_in + b_in; // addition + 6: result = a_in - b_in; // substraction + 7: result = a_in < b_in ? 1 : 0; // set on less than + 8: result = ~(a_in | b_in); // bitwise nor + 9: result = a_in ^ b_in; // bitwise xor + default: result = 0; + endcase + end endmodule diff --git a/hdl/alu_ctrl.v b/hdl/alu_ctrl.v index 881c2c7..1a68d2c 100644 --- a/hdl/alu_ctrl.v +++ b/hdl/alu_ctrl.v @@ -3,29 +3,26 @@ /** ALU Control unit */ -module alu_ctrl( - input wire [1:0] alu_op, - input wire [5:0] func_code, - output reg [4:0] alu_ctl - ); +module alu_ctrl( input [1:0] alu_op, + input [5:0] func_code, + output reg [4:0] alu_ctl ); -always @* - begin - if(alu_op == 0) - alu_ctl = 2; // add - else if(alu_op == 1) - alu_ctl = 6; - else case( func_code ) - 32: alu_ctl = 2; // add - 34: alu_ctl = 6; // subtract - 36: alu_ctl = 0; // and - 37: alu_ctl = 1; // or - 38: alu_ctl = 9; // xor - 39: alu_ctl = 8; // nor - 42: alu_ctl = 7; // slt - default: alu_ctl = 15; // should not happen - endcase - end + always @* begin + if(alu_op == 0) + alu_ctl = 2; // add + else if(alu_op == 1) + alu_ctl = 6; + else case( func_code ) + 32: alu_ctl = 2; // add + 34: alu_ctl = 6; // subtract + 36: alu_ctl = 0; // and + 37: alu_ctl = 1; // or + 38: alu_ctl = 9; // xor + 39: alu_ctl = 8; // nor + 42: alu_ctl = 7; // slt + default: alu_ctl = 15; // should not happen + endcase + end endmodule diff --git a/hdl/control.v b/hdl/control.v index 58f273f..53a6d04 100644 --- a/hdl/control.v +++ b/hdl/control.v @@ -1,114 +1,101 @@ `timescale 1ns / 1ps -module control( - input [5:0] opcode, - input branch_eq, // result of comparison for conditional branch +module control( input [5:0] opcode, + input branch_eq, // result of comparison for conditional branch - output reg [1:0] if_pc_source, - output id_rt_is_source, // rt is source + output reg [1:0] if_pc_source, + output id_rt_is_source, // rt is source - output ex_imm_command, - output reg ex_alu_src_b, - output reg ex_dst_reg_sel, - output reg [1:0] ex_alu_op, - output reg mem_read, - output reg mem_write, - output reg wb_mem_to_reg, - output reg wb_reg_write - ); + output ex_imm_command, + output reg ex_alu_src_b, + output reg ex_dst_reg_sel, + output reg [1:0] ex_alu_op, + output reg mem_read, + output reg mem_write, + output reg wb_mem_to_reg, + output reg wb_reg_write ); - - localparam - LW = 6'b100011, - SW = 6'b101011, - BEQ=6'b000100, - RTYPE = 6'b0, - J=6'd2, - JAL=6'd3, - ADDI = 6'b001000, - ANDI = 6'b001100, - ORI = 6'b001101, - XORI = 6'b001110, - SLTI = 6'b001010; // opcodes - - reg memory_op; - reg r_type_op; - reg immediate_op; - reg branch_op; - reg jump_op; + //opcodes + localparam LW = 6'b100011, + SW = 6'b101011, + BEQ = 6'b000100, + RTYPE = 6'b0, + J = 6'd2, + JAL = 6'd3, + ADDI = 6'b001000, + ANDI = 6'b001100, + ORI = 6'b001101, + XORI = 6'b001110, + SLTI = 6'b001010; + //-------------------------------- - - assign ex_imm_command = immediate_op; - assign id_rt_is_source = (r_type_op | branch_op | opcode == SW); + reg memory_op; + reg r_type_op; + reg immediate_op; + reg branch_op; + reg jump_op; - - always @* - begin - // default values - if_pc_source = 0; - ex_alu_src_b = 0; - ex_dst_reg_sel = 0; - ex_alu_op = 0; - mem_read = 0; - mem_write = 0; - wb_mem_to_reg = 0; - wb_reg_write = 0; + assign ex_imm_command = immediate_op; + assign id_rt_is_source = (r_type_op | branch_op | opcode == SW); + + always @* begin + //default values + if_pc_source = 0; + ex_alu_src_b = 0; + ex_dst_reg_sel = 0; + ex_alu_op = 0; + mem_read = 0; + mem_write = 0; + wb_mem_to_reg = 0; + wb_reg_write = 0; - memory_op = ( (opcode == LW) | (opcode == SW) ); - r_type_op = ( opcode == RTYPE ); - branch_op = ( opcode == BEQ ); - immediate_op = ( (opcode == ADDI) | (opcode == ANDI) | (opcode == ORI) | (opcode == XORI) | (opcode == SLTI) ); - jump_op = ( opcode == J); + memory_op = ( (opcode == LW) | (opcode == SW) ); + r_type_op = ( opcode == RTYPE ); + branch_op = ( opcode == BEQ ); + immediate_op = ( (opcode == ADDI) | (opcode == ANDI) | (opcode == ORI) | (opcode == XORI) | (opcode == SLTI) ); + jump_op = ( opcode == J); - if (memory_op) begin - ex_alu_src_b = 1'b1; // select sign_extend_offset input - ex_dst_reg_sel = 1'b0; // rt - ex_alu_op = 2'b00; // add op - wb_mem_to_reg = 1'b1; // select mem_out + if (memory_op) begin + ex_alu_src_b = 1'b1; // select sign_extend_offset input + ex_dst_reg_sel = 1'b0; // rt + ex_alu_op = 2'b00; // add op + wb_mem_to_reg = 1'b1; // select mem_out - if ( opcode == LW ) begin - mem_read = 1'b1; - wb_reg_write = 1'b1; - end - else - mem_write = 1'b1; // opcode == SW - - end - - else if (r_type_op) begin - ex_alu_src_b = 1'b0; // select B input - ex_dst_reg_sel = 1'b1; // rd - ex_alu_op = 2'b10; // operaction defined by func code + if ( opcode == LW ) begin + mem_read = 1'b1; + wb_reg_write = 1'b1; + end + else + mem_write = 1'b1; // opcode == SW + end + else if (r_type_op) begin + ex_alu_src_b = 1'b0; // select B input + ex_dst_reg_sel = 1'b1; // rd + ex_alu_op = 2'b10; // operaction defined by func code - wb_mem_to_reg = 1'b0; // alu_out - wb_reg_write = 1'b1; // write result to regfile - end + wb_mem_to_reg = 1'b0; // alu_out + wb_reg_write = 1'b1; // write result to regfile + end + else if (immediate_op) begin + ex_alu_src_b = 1'b1; // select sign_extend_offset input + ex_dst_reg_sel = 1'b0; // rt + ex_alu_op = 2'b10; // operation defined by function code - else if (immediate_op) begin - ex_alu_src_b = 1'b1; // select sign_extend_offset input - ex_dst_reg_sel = 1'b0; // rt - ex_alu_op = 2'b10; // operation defined by function code - - wb_mem_to_reg = 1'b0; // alu_out - wb_reg_write = 1'b01; - end - - else if (branch_op) begin - if (branch_eq) if_pc_source = 2'b01; // PC <= branch_addr - else if_pc_source = 2'b00; + wb_mem_to_reg = 1'b0; // alu_out + wb_reg_write = 1'b1; + end + else if (branch_op) begin + if (branch_eq) + if_pc_source = 2'b01; // PC <= branch_addr + else + if_pc_source = 2'b00; - end - - else if (jump_op) begin - if_pc_source = 2'b10; // PC <= jump_addr - end - - else begin - // NOP - end - - + end + else if (jump_op) + if_pc_source = 2'b10; // PC <= jump_addr + else begin + //NOP + end end - endmodule diff --git a/hdl/dp_memory.v b/hdl/dp_memory.v index fa7db30..5064df7 100644 --- a/hdl/dp_memory.v +++ b/hdl/dp_memory.v @@ -4,34 +4,37 @@ Dual-port Instrcution/Data memory */ -module dp_memory( - input wire clk, - - input wire i_read_en, - input wire [31:0] i_addr, - output wire [31:0] i_instr_out, +module dp_memory( input wire clk, + input wire i_read_en, + input wire [31:0] i_addr, + output wire [31:0] i_instr_out, - input wire d_read_en, - input wire d_write_en, - input wire [31:0] d_addr, - input wire [31:0] d_write_data, - output wire [31:0] d_data_out - ); + input wire d_read_en, + input wire d_write_en, + input wire [31:0] d_addr, + input wire [31:0] d_write_data, + output wire [31:0] d_data_out ); - reg [31:0] mem[0:1023]; - - initial begin - $readmemh("./sw/test.rom", mem); - end - - - always @(posedge clk) begin - if (d_write_en) - mem [d_addr] <= d_write_data; - end - - assign i_instr_out = i_read_en ? mem[i_addr] : 0; - assign d_data_out = d_read_en ? mem[d_addr] : 0; + localparam mem_high_addr = 32'h00000400; + + wire i_bram_select, d_bram_select; + + reg [31:0] mem[0:mem_high_addr - 1]; + + initial begin + $readmemh("./sw/test.rom", mem); + end + + assign i_bram_select = (i_addr < mem_high_addr) ? 1'b1 : 1'b0; + assign d_bram_select = (d_addr < mem_high_addr) ? 1'b1 : 1'b0; + + always @(posedge clk) begin + if (d_write_en && d_bram_select) + mem [d_addr] <= d_write_data; + end + assign i_instr_out = (i_read_en && i_bram_select) ? mem[i_addr] : 0; + assign d_data_out = (d_read_en && d_bram_select) ? mem[d_addr] : 0; + endmodule diff --git a/hdl/ex_stage.v b/hdl/ex_stage.v index cca87e9..082113e 100644 --- a/hdl/ex_stage.v +++ b/hdl/ex_stage.v @@ -1,120 +1,105 @@ -module ex_stage( - input clk, - input rst, - - input wb_reg_write, - input wb_mem_to_reg, - - input mem_read, - input mem_write, - - input ex_imm_command, - input ex_alu_src_b, - input ex_dst_reg_sel, - input [1:0] ex_alu_op, +module ex_stage( input clk, + input rst, + input wb_reg_write, + input wb_mem_to_reg, + input mem_read, + input mem_write, + input ex_imm_command, + input ex_alu_src_b, + input ex_dst_reg_sel, + input [1:0] ex_alu_op, - input [31:0] A, - input [31:0] B, - input [31:0] sign_extend_offset, - input [4:0] rt, // target register - input [4:0] rd, // destination register - input [5:0] opcode, - input [1:0] rs_fwd_sel, // forwarding muxes control - input [1:0] rt_fwd_sel, // forwarding muxes control - input [31:0] mem_fwd_val, // forwarding from EX_MEM - input [31:0] wb_fwd_val, // forwarding from WB + input [31:0] A, + input [31:0] B, + input [31:0] sign_extend_offset, + input [4:0] rt, // target register + input [4:0] rd, // destination register + input [5:0] opcode, + input [1:0] rs_fwd_sel, // forwarding muxes control + input [1:0] rt_fwd_sel, // forwarding muxes control + input [31:0] mem_fwd_val, // forwarding from EX_MEM + input [31:0] wb_fwd_val, // forwarding from WB - // outputs - output [4:0] ex_dst_reg, - output [5:0] ex_opcode, + output [4:0] ex_dst_reg, + output [5:0] ex_opcode, - output reg [31:0] EX_MEM_alu_result, - output reg [31:0] EX_MEM_B_value, - output reg [4:0] EX_MEM_dst_reg, - output reg [5:0] EX_MEM_opcode, - output reg EX_MEM_mem_read, - output reg EX_MEM_mem_write, - output reg EX_MEM_wb_reg_write, - output reg EX_MEM_wb_mem_to_reg -); + output reg [31:0] EX_MEM_alu_result, + output reg [31:0] EX_MEM_B_value, + output reg [4:0] EX_MEM_dst_reg, + output reg [5:0] EX_MEM_opcode, + output reg EX_MEM_mem_read, + output reg EX_MEM_mem_write, + output reg EX_MEM_wb_reg_write, + output reg EX_MEM_wb_mem_to_reg ); + wire [5:0] func_field; // func code field in instruction + wire [5:0] func_code; // func code for ALU control + wire [4:0] alu_ctl; // ALU control lines - wire [5:0] func_field; // func code field in instruction - wire [5:0] func_code; // func code for ALU control - wire [4:0] alu_ctl; // ALU control lines - - reg [31:0] alu_a_in; - wire [31:0] alu_b_in; - reg[31:0] b_value; + reg [31:0] alu_a_in; + wire [31:0] alu_b_in; + reg [31:0] b_value; - wire [31:0] alu_result; - wire zero; - + wire [31:0] alu_result; + wire zero; - always @* - begin - case(rs_fwd_sel) - 0: alu_a_in = A; - 1: alu_a_in = mem_fwd_val; - 2: alu_a_in = wb_fwd_val; - endcase + always @* begin + case(rs_fwd_sel) + 0: alu_a_in = A; + 1: alu_a_in = mem_fwd_val; + 2: alu_a_in = wb_fwd_val; + default: alu_a_in = 0; // + endcase end - always @* - begin - case(rt_fwd_sel) - 0: b_value = B; - 1: b_value = mem_fwd_val; - 2: b_value = wb_fwd_val; - endcase + always @* begin + case(rt_fwd_sel) + 0: b_value = B; + 1: b_value = mem_fwd_val; + 2: b_value = wb_fwd_val; + default: b_value = 0; // + endcase end - assign alu_b_in = ex_alu_src_b ? sign_extend_offset : b_value; - assign func_field = sign_extend_offset [5:0]; // looks wierd, but func code is encoded there - assign func_code = ex_imm_command ? {{2'b10},{~opcode[2] & opcode[1] & ~opcode[0]},opcode[2:0]} : func_field; - assign ex_opcode = opcode; - assign ex_dst_reg = ex_dst_reg_sel ? rd : rt; - - - - alu_ctrl aluctl_inst( - .alu_op (ex_alu_op), - .func_code (func_code), - .alu_ctl (alu_ctl) - ); + assign alu_b_in = ex_alu_src_b ? sign_extend_offset : b_value; + assign func_field = sign_extend_offset [5:0]; // looks wierd, but func code is encoded there + assign func_code = ex_imm_command ? {{2'b10},{~opcode[2] & opcode[1] & ~opcode[0]},opcode[2:0]} : func_field; + assign ex_opcode = opcode; + assign ex_dst_reg = ex_dst_reg_sel ? rd : rt; + + alu_ctrl aluctl_inst( + .alu_op (ex_alu_op), + .func_code (func_code), + .alu_ctl (alu_ctl)); - alu alu_inst ( - .alu_ctl (alu_ctl), - .a_in (alu_a_in), - .b_in (alu_b_in), - .result (alu_result), - .zero_flag (zero) - ); - - // EX/MEM Pipeline register - always @(posedge clk) begin - if (rst) - begin - EX_MEM_alu_result <= 0; - EX_MEM_B_value <= 0; - EX_MEM_dst_reg <= 0; - EX_MEM_mem_read <= 0; - EX_MEM_mem_write <= 0; - EX_MEM_wb_reg_write <= 0; - EX_MEM_wb_mem_to_reg <= 0; - end - else - begin - EX_MEM_alu_result <= alu_result; - EX_MEM_B_value <= b_value; - EX_MEM_dst_reg <= ex_dst_reg; - EX_MEM_opcode <= opcode; - EX_MEM_mem_read <= mem_read; - EX_MEM_mem_write <= mem_write; - EX_MEM_wb_reg_write <= wb_reg_write; - EX_MEM_wb_mem_to_reg <= wb_mem_to_reg; - end - end - + alu alu_inst( + .alu_ctl (alu_ctl), + .a_in (alu_a_in), + .b_in (alu_b_in), + .result (alu_result), + .zero_flag (zero)); + // EX/MEM Pipeline register + always @(posedge clk) begin + if (rst) begin + EX_MEM_alu_result <= 0; + EX_MEM_B_value <= 0; + EX_MEM_dst_reg <= 0; + EX_MEM_mem_read <= 0; + EX_MEM_mem_write <= 0; + EX_MEM_wb_reg_write <= 0; + EX_MEM_wb_mem_to_reg <= 0; + end + else begin + EX_MEM_alu_result <= alu_result; + EX_MEM_B_value <= b_value; + EX_MEM_dst_reg <= ex_dst_reg; + EX_MEM_opcode <= opcode; + EX_MEM_mem_read <= mem_read; + EX_MEM_mem_write <= mem_write; + EX_MEM_wb_reg_write <= wb_reg_write; + EX_MEM_wb_mem_to_reg <= wb_mem_to_reg; + end + end + endmodule diff --git a/hdl/forwarding_unit.v b/hdl/forwarding_unit.v index ab98219..4164499 100644 --- a/hdl/forwarding_unit.v +++ b/hdl/forwarding_unit.v @@ -1,138 +1,126 @@ `timescale 1ns / 1ps -module forwarding_unit - ( - input ex_mem_reg_write, - input mem_wb_reg_write, - input [4:0] ex_mem_dst_reg, - input [4:0] mem_wb_dst_reg, - input [4:0] id_ex_rs, - input [4:0] id_ex_rt, - input [4:0] if_id_rs, - input [4:0] if_id_rt, +module forwarding_unit ( + input ex_mem_reg_write, + input mem_wb_reg_write, + input [4:0] ex_mem_dst_reg, + input [4:0] mem_wb_dst_reg, + input [4:0] id_ex_rs, + input [4:0] id_ex_rt, + input [4:0] if_id_rs, + input [4:0] if_id_rt, - output [1:0] if_rs_forward_control, - output [1:0] id_rt_forward_control, - output [1:0] ex_rs_forward_control, - output [1:0] ex_rt_forward_control - ); + output [1:0] if_rs_forward_control, + output [1:0] id_rt_forward_control, + output [1:0] ex_rs_forward_control, + output [1:0] ex_rt_forward_control ); - // tmp signals - wire [3:0] id_fwd_ctrl, ex_fwd_ctrl; + //tmp signals + wire [3:0] id_fwd_ctrl, ex_fwd_ctrl; - // encoding for muxes control signals - // general for both forwarding muxes - // 2'b01 - from EX_MEM pipe reg - // 2'b10 - from MEM_WB pipe reg - // 2'b00 - no forwarding + // encoding for muxes control signals + // general for both forwarding muxes + // 2'b01 - from EX_MEM pipe reg + // 2'b10 - from MEM_WB pipe reg + // 2'b00 - no forwarding - assign if_rs_forward_control = id_fwd_ctrl[0] ? 2'b01 : id_fwd_ctrl[2] ? 2'b10 : 2'b00; - assign id_rt_forward_control = id_fwd_ctrl[1] ? 2'b01 : id_fwd_ctrl[3] ? 2'b10 : 2'b00; - assign ex_rs_forward_control = ex_fwd_ctrl[0] ? 2'b01 : ex_fwd_ctrl[2] ? 2'b10 : 2'b00; - assign ex_rt_forward_control = ex_fwd_ctrl[1] ? 2'b01 : ex_fwd_ctrl[3] ? 2'b10 : 2'b00; + assign if_rs_forward_control = id_fwd_ctrl[0] ? 2'b01 : id_fwd_ctrl[2] ? 2'b10 : 2'b00; + assign id_rt_forward_control = id_fwd_ctrl[1] ? 2'b01 : id_fwd_ctrl[3] ? 2'b10 : 2'b00; + assign ex_rs_forward_control = ex_fwd_ctrl[0] ? 2'b01 : ex_fwd_ctrl[2] ? 2'b10 : 2'b00; + assign ex_rt_forward_control = ex_fwd_ctrl[1] ? 2'b01 : ex_fwd_ctrl[3] ? 2'b10 : 2'b00; - base_forwarding_unit ex_forwarding_inst( - .ex_mem_reg_write(ex_mem_reg_write), - .mem_wb_reg_write(mem_wb_reg_write), - .ex_mem_dst_reg(ex_mem_dst_reg), - .mem_wb_dst_reg(mem_wb_dst_reg), - .rs(id_ex_rs), - .rt(id_ex_rt), - .forward_control(ex_fwd_ctrl) - ); + base_forwarding_unit ex_forwarding_inst( + .ex_mem_reg_write(ex_mem_reg_write), + .mem_wb_reg_write(mem_wb_reg_write), + .ex_mem_dst_reg(ex_mem_dst_reg), + .mem_wb_dst_reg(mem_wb_dst_reg), + .rs(id_ex_rs), + .rt(id_ex_rt), + .forward_control(ex_fwd_ctrl)); - base_forwarding_unit id_forwarding_inst( - .ex_mem_reg_write(ex_mem_reg_write), - .mem_wb_reg_write(mem_wb_reg_write), - .ex_mem_dst_reg(ex_mem_dst_reg), - .mem_wb_dst_reg(mem_wb_dst_reg), - .rs(if_id_rs), - .rt(if_id_rt), - .forward_control(id_fwd_ctrl) - ); - + base_forwarding_unit id_forwarding_inst( + .ex_mem_reg_write(ex_mem_reg_write), + .mem_wb_reg_write(mem_wb_reg_write), + .ex_mem_dst_reg(ex_mem_dst_reg), + .mem_wb_dst_reg(mem_wb_dst_reg), + .rs(if_id_rs), + .rt(if_id_rt), + .forward_control(id_fwd_ctrl)); endmodule - - /* Generic base logic module to implement forwarding + * + * Description of forward_control signal: + * 0000 - no forwarding + * 0001 - forwarding value from EX_MEM for replace rs value on destination stage. + * EX_MEM[Value] -> PIPE_STAGE[rs] + * 0010 - forwarding value from EX_MEM for replace rt value on destination stage. + * EX_MEM[Value] -> PIPE_STAGE[rt] + * 0100 - forwarding value from WB for replace rs value on destination stage. + * WB[Value] -> PIPE_STAGE[rs] + * 1000 - forwarding value from WB for replace rt value on destination stage. + * WB[Value] -> PIPE_STAGE[rt] + * 0011 - forwarding value from EX_MEM for replace rs and rt value on destination stage + * EX_MEM[Value] -> PIPE_STAGE[rs]; EX_MEM[Value] -> PIPE_STAGE[rt] + * 1100 - forwarding value from WB for replace Rs and Rt value on destination stage + * WB[Value] -> PIPE_STAGE[rs]; WB[Value] -> PIPE_STAGE[rt] + * 0110 - forwarding value from EX_MEM for replace rt value on destination stage. + * EX_MEM[Value] -> PIPE_STAGE[rt] + * forwarding value from WB for replace rs value on destination stage. + * WB[Value] -> PIPE_STAGE[rs] + * 1001 - forwarding value from EX_MEM for replace rs value on destination stage. + * EX_MEM[Value] -> PIPE_STAGE[rs] + * forwarding value from WB for replace rt value on destination stage. + * WB[Value] -> PIPE_STAGE[rt] + */ - Description of forward_control signal: -0000 - no forwarding -0001 - forwarding value from EX_MEM for replace rs value on destination stage. - EX_MEM[Value] -> PIPE_STAGE[rs] - -0010 - forwarding value from EX_MEM for replace rt value on destination stage. - EX_MEM[Value] -> PIPE_STAGE[rt] - -0100 - forwarding value from WB for replace rs value on destination stage. - WB[Value] -> PIPE_STAGE[rs] - -1000 - forwarding value from WB for replace rt value on destination stage. - WB[Value] -> PIPE_STAGE[rt] - -0011 - forwarding value from EX_MEM for replace rs and rt value on destination stage - EX_MEM[Value] -> PIPE_STAGE[rs]; EX_MEM[Value] -> PIPE_STAGE[rt] - -1100 - forwarding value from WB for replace Rs and Rt value on destination stage - WB[Value] -> PIPE_STAGE[rs]; WB[Value] -> PIPE_STAGE[rt] - - -0110 - forwarding value from EX_MEM for replace rt value on destination stage. - EX_MEM[Value] -> PIPE_STAGE[rt] - forwarding value from WB for replace rs value on destination stage. - WB[Value] -> PIPE_STAGE[rs] - -1001 - forwarding value from EX_MEM for replace rs value on destination stage. - EX_MEM[Value] -> PIPE_STAGE[rs] - forwarding value from WB for replace rt value on destination stage. - WB[Value] -> PIPE_STAGE[rt] - */ - -module base_forwarding_unit ( - input ex_mem_reg_write, - input mem_wb_reg_write, - input [4:0] ex_mem_dst_reg, - input [4:0] mem_wb_dst_reg, - input [4:0] rs, - input [4:0] rt, +module base_forwarding_unit ( input ex_mem_reg_write, + input mem_wb_reg_write, + input [4:0] ex_mem_dst_reg, + input [4:0] mem_wb_dst_reg, + input [4:0] rs, + input [4:0] rt, - output reg [3:0] forward_control -); + output reg [3:0] forward_control); - // service signals - reg ex_mem_dst_reg_is_not_zero; - reg mem_wb_dst_reg_is_not_zero; + //service signals + reg ex_mem_dst_reg_is_not_zero; + reg mem_wb_dst_reg_is_not_zero; - always @* - begin - - ex_mem_dst_reg_is_not_zero = |ex_mem_dst_reg; - mem_wb_dst_reg_is_not_zero = |mem_wb_dst_reg; - forward_control = 4'h0; + always @* begin + ex_mem_dst_reg_is_not_zero = |ex_mem_dst_reg; + mem_wb_dst_reg_is_not_zero = |mem_wb_dst_reg; + + forward_control = 4'h0; - if (ex_mem_reg_write & ex_mem_dst_reg_is_not_zero) - begin - if (ex_mem_dst_reg == rs) forward_control[0] = 1'b1; - else forward_control[0] = 1'b0; + if (ex_mem_reg_write & ex_mem_dst_reg_is_not_zero) begin + if (ex_mem_dst_reg == rs) + forward_control[0] = 1'b1; + else + forward_control[0] = 1'b0; - if (ex_mem_dst_reg == rt) forward_control[1] = 1'b1; - else forward_control[1] = 1'b0; - end - else forward_control[1:0] = 2'b00; + if (ex_mem_dst_reg == rt) + forward_control[1] = 1'b1; + else + forward_control[1] = 1'b0; + end + else + forward_control[1:0] = 2'b00; - if (mem_wb_reg_write & mem_wb_dst_reg_is_not_zero) - begin - if ((mem_wb_dst_reg == rs) & (ex_mem_dst_reg != rs)) forward_control[2] = 1'b1; - else forward_control[2] = 1'b0; + if (mem_wb_reg_write & mem_wb_dst_reg_is_not_zero) begin + if ((mem_wb_dst_reg == rs) & (ex_mem_dst_reg != rs)) + forward_control[2] = 1'b1; + else + forward_control[2] = 1'b0; - if ((mem_wb_dst_reg == rt) & (ex_mem_dst_reg != rt)) forward_control[3] = 1'b1; - else forward_control[3] = 1'b0; - end - else forward_control[3:2] = 2'b00; - + if ((mem_wb_dst_reg == rt) & (ex_mem_dst_reg != rt)) + forward_control[3] = 1'b1; + else + forward_control[3] = 1'b0; + end + else + forward_control[3:2] = 2'b00; end - - + endmodule diff --git a/hdl/hazard_unit.v b/hdl/hazard_unit.v index 627c162..4fcee51 100644 --- a/hdl/hazard_unit.v +++ b/hdl/hazard_unit.v @@ -1,66 +1,56 @@ `timescale 1ns / 1ps -module hazard_unit( - input clk, - input rst, - input [4:0] ex_dst_reg, - input [4:0] mem_dst_reg, - input [4:0] id_rs, - input [4:0] id_rt, - - input [5:0] mem_opcode, - input [5:0] ex_opcode, - input [5:0] id_opcode, - - input id_rt_is_source, - input ex_reg_write, - input mem_reg_write, - - output pc_write, - output if_id_write_en, - output reg hazard_detected -); - - localparam - LW = 6'b100011, - BEQ=6'b000100; - - - assign pc_write = ~hazard_detected; - assign if_id_write_en = ~hazard_detected; - - reg [1:0] coincidence; +module hazard_unit( //input clk, isn't needed for now + //input rst, isn't needed for now + input [4:0] ex_dst_reg, + input [4:0] mem_dst_reg, + input [4:0] id_rs, + input [4:0] id_rt, + + input [5:0] mem_opcode, + input [5:0] ex_opcode, + input [5:0] id_opcode, + + input id_rt_is_source, + input ex_reg_write, + input mem_reg_write, + + output pc_write, + output if_id_write_en, + output reg hazard_detected ); + + localparam LW = 6'b100011, + BEQ = 6'b000100; + + assign pc_write = ~hazard_detected; + assign if_id_write_en = ~hazard_detected; + + reg [1:0] coincidence; - always @* - begin - coincidence = 0; + always @* begin + coincidence = 0; - if (ex_reg_write && ( (id_rs == ex_dst_reg) | ( (id_rt == ex_dst_reg) && id_rt_is_source))) - coincidence[0] = 1'b1; - else if (mem_reg_write && ( (id_rs == mem_dst_reg) | ( (id_rt == mem_dst_reg) && id_rt_is_source))) - coincidence[1] = 1'b1; + if (ex_reg_write && ( (id_rs == ex_dst_reg) | ( (id_rt == ex_dst_reg) && id_rt_is_source))) + coincidence[0] = 1'b1; + else if (mem_reg_write && ( (id_rs == mem_dst_reg) | ( (id_rt == mem_dst_reg) && id_rt_is_source))) + coincidence[1] = 1'b1; end - - always @* - begin - hazard_detected = 0; + always @* begin + hazard_detected = 0; - if (coincidence [0]) - begin - if ( id_opcode == BEQ && ex_opcode == LW ) - hazard_detected = 1; - else if ( id_opcode == BEQ && ex_opcode != LW) - hazard_detected = 1; - else if ( id_opcode != BEQ && ex_opcode == LW) - hazard_detected = 1; + if (coincidence [0]) begin + if ( id_opcode == BEQ && ex_opcode == LW ) + hazard_detected = 1; + else if ( id_opcode == BEQ && ex_opcode != LW) + hazard_detected = 1; + else if ( id_opcode != BEQ && ex_opcode == LW) + hazard_detected = 1; end - else if (coincidence [1]) - begin - if (id_opcode == BEQ && mem_opcode == LW) - hazard_detected = 1; + else if (coincidence [1]) begin + if (id_opcode == BEQ && mem_opcode == LW) + hazard_detected = 1; end end - endmodule diff --git a/hdl/id_stage.v b/hdl/id_stage.v index 387c420..43a6b03 100644 --- a/hdl/id_stage.v +++ b/hdl/id_stage.v @@ -3,186 +3,167 @@ Instruction decode pipeline stage */ -module id_stage( - input clk, rst, - input reg_write, - input [4:0] wreg_addr, // write register number - input [31:0] wreg_data, // data to write into regfile - input [31:0] instruction, next_i_addr, // instruction fetched, next instruction address +module id_stage( input clk, rst, + input reg_write, + input [4:0] wreg_addr, // write register number + input [31:0] wreg_data, // data to write into regfile + input [31:0] instruction, next_i_addr, // instruction fetched, next instruction address - // inputs to support forwarding - input [1:0] rs_fwd_sel, rt_fwd_sel, // forwarding control signals - input [31:0] mem_fwd_val, wb_fwd_val, // forwarded data values - - input hazard, - // outputs - output wire [4:0] id_rs, - output wire [4:0] id_rt, - output wire [5:0] id_opcode, + //inputs to support forwarding + input [1:0] rs_fwd_sel, rt_fwd_sel, // forwarding control signals + input [31:0] mem_fwd_val, wb_fwd_val, // forwarded data values + input hazard, - output reg [31:0] ID_EX_A, - output reg [31:0] ID_EX_B, - output reg [4:0] ID_EX_rt, - output reg [4:0] ID_EX_rs, - output reg [4:0] ID_EX_rd, - output reg [5:0] ID_EX_opcode, - output reg [31:0] ID_EX_sign_extend_offset, - output reg ID_EX_wb_reg_write, - output reg ID_EX_wb_mem_to_reg, - output reg ID_EX_mem_read, - output reg ID_EX_mem_write, - output reg ID_EX_ex_imm_command, - output reg ID_EX_ex_alu_src_b, - output reg ID_EX_ex_dst_reg_sel, - output reg [1:0] ID_EX_ex_alu_op, + //outputs + output [4:0] id_rs, + output [4:0] id_rt, + output [5:0] id_opcode, + + output reg [31:0] ID_EX_A, + output reg [31:0] ID_EX_B, + output reg [4:0] ID_EX_rt, + output reg [4:0] ID_EX_rs, + output reg [4:0] ID_EX_rd, + output reg [5:0] ID_EX_opcode, + output reg [31:0] ID_EX_sign_extend_offset, + output reg ID_EX_wb_reg_write, + output reg ID_EX_wb_mem_to_reg, + output reg ID_EX_mem_read, + output reg ID_EX_mem_write, + output reg ID_EX_ex_imm_command, + output reg ID_EX_ex_alu_src_b, + output reg ID_EX_ex_dst_reg_sel, + output reg [1:0] ID_EX_ex_alu_op, - output [31:0] branch_addr, jump_addr, // branch and jump adresses - output id_rt_is_source, - output [1:0] if_pc_source - ); - - - - - reg [31:0] A, B; - wire [31:0] a_out; - wire [31:0] b_out; - wire [31:0] sign_extend_offset; + output [31:0] branch_addr, jump_addr, // branch and jump adresses + output id_rt_is_source, + output [1:0] if_pc_source ); + + reg [31:0] A, B; + wire [31:0] a_out; + wire [31:0] b_out; + wire [31:0] sign_extend_offset; - wire ex_imm_command; - wire ex_alu_src_b; - wire ex_dst_reg_sel; - wire [1:0] ex_alu_op; - wire mem_read; - wire mem_write; - wire wb_mem_to_reg; - wire wb_reg_write; - wire is_nop; - wire branch_eq; + wire ex_imm_command; + wire ex_alu_src_b; + wire ex_dst_reg_sel; + wire [1:0] ex_alu_op; + wire mem_read; + wire mem_write; + wire wb_mem_to_reg; + wire wb_reg_write; + wire is_nop; + wire branch_eq; - - - regfile regfile_inst - ( - .clk( clk ), - .rst( rst ), - .raddr1( instruction[25:21] ), - .raddr2( instruction[20:16] ), - .waddr( wreg_addr ), - .wdata( wreg_data ), - .w_en( reg_write ), - .rdata1( a_out ), - .rdata2( b_out ) - ); - - - - // Forwarding muxes - - always @* - begin - A = 0; - case (rs_fwd_sel) - 0: A = a_out; - 1: A = mem_fwd_val; - 2: A = wb_fwd_val; - endcase + regfile regfile_inst ( + .clk( clk ), + .rst( rst ), + .raddr1( instruction[25:21] ), + .raddr2( instruction[20:16] ), + .waddr( wreg_addr ), + .wdata( wreg_data ), + .w_en( reg_write ), + .rdata1( a_out ), + .rdata2( b_out )); + + // Forwarding muxes + + always @* begin + A = 0; + case (rs_fwd_sel) + 0: A = a_out; + 1: A = mem_fwd_val; + 2: A = wb_fwd_val; + endcase end - always @* - begin - B = 0; - case (rt_fwd_sel) - 0: B = b_out; - 1: B = mem_fwd_val; - 2: B = wb_fwd_val; - endcase + always @* begin + B = 0; + case (rt_fwd_sel) + 0: B = b_out; + 1: B = mem_fwd_val; + 2: B = wb_fwd_val; + endcase + end + + assign sign_extend_offset = { { 16{instruction[15]} }, instruction [15:0]}; + assign branch_addr = next_i_addr + ( sign_extend_offset << 2 ); + assign jump_addr = {next_i_addr[31:28], instruction[25:0], 2'b00 }; + assign branch_eq = ( A == B); + + assign id_rs = instruction[25:21]; + assign id_rt = instruction[20:16]; + assign id_opcode = instruction[31:26]; + + assign is_nop = ~|instruction; + + //Control Unit -- Opcode Decoder + + control cunit_instance ( + .opcode( instruction [31:26] ), + .branch_eq( branch_eq ), + .id_rt_is_source(id_rt_is_source), + .if_pc_source(if_pc_source), + .ex_imm_command(ex_imm_command), + .ex_alu_src_b(ex_alu_src_b), + .ex_dst_reg_sel(ex_dst_reg_sel), + .ex_alu_op(ex_alu_op), + .mem_read(mem_read), + .mem_write(mem_write), + .wb_mem_to_reg(wb_mem_to_reg), + .wb_reg_write(wb_reg_write)); + + //ID/EX Pipeline register + + always @(posedge clk) begin + if (rst) begin + ID_EX_A <= 0; + ID_EX_B <= 0; + ID_EX_rt <= 0; + ID_EX_rs <= 0; + ID_EX_rd <= 0; + ID_EX_opcode <= 0; + ID_EX_sign_extend_offset <= 0; + ID_EX_wb_reg_write <= 0; + ID_EX_wb_mem_to_reg <= 0; + ID_EX_mem_read <= 0; + ID_EX_mem_write <= 0; + ID_EX_ex_imm_command <= 0; + ID_EX_ex_alu_src_b <= 0; + ID_EX_ex_dst_reg_sel <= 0; + ID_EX_ex_alu_op <= 0; + end + else begin + ID_EX_A <= A; + ID_EX_B <= B; + ID_EX_rt <= id_rt; + ID_EX_rs <= id_rs; + ID_EX_rd <= instruction[15:11]; + ID_EX_opcode <= id_opcode; + ID_EX_sign_extend_offset <= sign_extend_offset; + + if (is_nop || hazard) begin + ID_EX_wb_reg_write <= 0; + ID_EX_wb_mem_to_reg <= 0; + ID_EX_mem_read <= 0; + ID_EX_mem_write <= 0; + ID_EX_ex_imm_command <= 0; + ID_EX_ex_alu_src_b <= 0; + ID_EX_ex_dst_reg_sel <= 0; + ID_EX_ex_alu_op <= 0; + end + else begin + ID_EX_wb_reg_write <= wb_reg_write; + ID_EX_wb_mem_to_reg <= wb_mem_to_reg; + ID_EX_mem_read <= mem_read; + ID_EX_mem_write <= mem_write; + ID_EX_ex_imm_command <= ex_imm_command; + ID_EX_ex_alu_src_b <= ex_alu_src_b; + ID_EX_ex_dst_reg_sel <= ex_dst_reg_sel; + ID_EX_ex_alu_op <= ex_alu_op; + end + end end - - - assign sign_extend_offset = { { 16{instruction[15]} }, instruction [15:0]}; - assign branch_addr = next_i_addr + ( sign_extend_offset << 2 ); - assign jump_addr = {next_i_addr[31:28], instruction[25:0], 2'b00 }; - assign branch_eq = ( A == B); - - assign id_rs = instruction[25:21]; - assign id_rt = instruction[20:16]; - assign id_opcode = instruction[31:26]; - - assign is_nop = ~|instruction; - - // Control Unit -- Opcode Decoder - - control cunit_instance ( - .opcode( instruction [31:26] ), - .branch_eq( branch_eq ), - .id_rt_is_source(id_rt_is_source), - .if_pc_source(if_pc_source), - .ex_imm_command(ex_imm_command), - .ex_alu_src_b(ex_alu_src_b), - .ex_dst_reg_sel(ex_dst_reg_sel), - .ex_alu_op(ex_alu_op), - .mem_read(mem_read), - .mem_write(mem_write), - .wb_mem_to_reg(wb_mem_to_reg), - .wb_reg_write(wb_reg_write) - ); - - - // ID/EX Pipeline register - - - always @(posedge clk) begin - if (rst) - begin - ID_EX_A <= 0; - ID_EX_B <= 0; - ID_EX_rt <= 0; - ID_EX_rs <= 0; - ID_EX_rd <= 0; - ID_EX_opcode <= 0; - ID_EX_sign_extend_offset <= 0; - ID_EX_wb_reg_write <= 0; - ID_EX_wb_mem_to_reg <= 0; - ID_EX_mem_read <= 0; - ID_EX_mem_write <= 0; - ID_EX_ex_imm_command <= 0; - ID_EX_ex_alu_src_b <= 0; - ID_EX_ex_dst_reg_sel <= 0; - ID_EX_ex_alu_op <= 0; - end - else - begin - ID_EX_A <= A; - ID_EX_B <= B; - ID_EX_rt <= id_rt; - ID_EX_rs <= id_rs; - ID_EX_rd <= instruction[15:11]; - ID_EX_opcode <= id_opcode; - ID_EX_sign_extend_offset <= sign_extend_offset; - if (is_nop || hazard) begin - ID_EX_wb_reg_write <= 0; - ID_EX_wb_mem_to_reg <= 0; - ID_EX_mem_read <= 0; - ID_EX_mem_write <= 0; - ID_EX_ex_imm_command <= 0; - ID_EX_ex_alu_src_b <= 0; - ID_EX_ex_dst_reg_sel <= 0; - ID_EX_ex_alu_op <= 0; - end - else begin - ID_EX_wb_reg_write <= wb_reg_write; - ID_EX_wb_mem_to_reg <= wb_mem_to_reg; - ID_EX_mem_read <= mem_read; - ID_EX_mem_write <= mem_write; - ID_EX_ex_imm_command <= ex_imm_command; - ID_EX_ex_alu_src_b <= ex_alu_src_b; - ID_EX_ex_dst_reg_sel <= ex_dst_reg_sel; - ID_EX_ex_alu_op <= ex_alu_op; - end - end - end - endmodule diff --git a/hdl/if_stage.v b/hdl/if_stage.v index eda165d..ee8818c 100644 --- a/hdl/if_stage.v +++ b/hdl/if_stage.v @@ -4,74 +4,60 @@ Instruction Fetch pipeline stage */ -module if_stage( - input clk, rst, - - input if_id_write_en, - input pc_write, - input [1:0] pc_source, - - output i_read_en, - output [31:0] i_addr, - - input [31:0] i_instr_in, - input [31:0] jump_addr, branch_addr, +module if_stage( input clk, rst, + input if_id_write_en, + input pc_write, + input [1:0] pc_source, - output reg [31:0] IF_ID_next_i_addr, - output reg [31:0] IF_ID_instruction - ); - - - reg [31:0] pc_reg, pc_next; // Program counter (PC) - wire [31:0] next_i_addr; + output i_read_en, + output [31:0] i_addr, + + input [31:0] i_instr_in, + input [31:0] jump_addr, branch_addr, + + output reg [31:0] IF_ID_next_i_addr, + output reg [31:0] IF_ID_instruction ); + + + reg [31:0] pc_reg, pc_next; // Program counter (PC) + wire [31:0] next_i_addr; - // logic - assign next_i_addr = pc_reg + 4; - assign i_read_en = 1; - assign i_addr = pc_reg >> 2; + //logic + assign next_i_addr = pc_reg + 4; + assign i_read_en = 1; + assign i_addr = pc_reg >> 2; - always @* - begin - pc_next = pc_reg; - - case (pc_source) - 2'b00: pc_next = next_i_addr; - 2'b01: pc_next = branch_addr; - 2'b10: pc_next = jump_addr; - endcase + always @* begin + pc_next = pc_reg; + case (pc_source) + 2'b00: pc_next = next_i_addr; + 2'b01: pc_next = branch_addr; + 2'b10: pc_next = jump_addr; + endcase end - always @(posedge clk) - begin - if (rst) - pc_reg <= 0; - else - begin - if (pc_write) - pc_reg <= pc_next; + always @(posedge clk) begin + if (rst) + pc_reg <= 0; + else begin + if (pc_write) + pc_reg <= pc_next; end end - - /* - IF/ID Pipeline register - */ - - always @(posedge clk) begin - if (rst) - begin - IF_ID_next_i_addr <= 0; - IF_ID_instruction <= 0; - end - else - begin - if ( if_id_write_en ) begin - IF_ID_next_i_addr <= pc_reg + 4; - IF_ID_instruction <= i_instr_in; - end - end - end - - + //IF/ID Pipeline register + always @(posedge clk) begin + if (rst) begin + IF_ID_next_i_addr <= 0; + IF_ID_instruction <= 0; + end + else begin + if ( if_id_write_en ) begin + IF_ID_next_i_addr <= pc_reg + 4; + IF_ID_instruction <= i_instr_in; + end + end + end + endmodule diff --git a/hdl/mips_system.v b/hdl/mips_system.v index fa01da1..b829c24 100644 --- a/hdl/mips_system.v +++ b/hdl/mips_system.v @@ -2,54 +2,56 @@ MIPS System: CPU Core + Memory */ -module mips_system - ( - input wire clk, - input wire rst, +module mips_system ( input wire clk, + input wire rst, + + output mem_instr_read, + output [31:0] mem_instr_addr_bus, mem_instr_read_bus, + + output mem_data_write, mem_data_read, + output [31:0] mem_data_addr_bus, mem_data_read_bus, mem_data_write_bus ); - output ext_write_en, - output ext_read_en, - output [31:0] ext_addr, - output [31:0] ext_write_data, - input [31:0] ext_data_in - ) ; - - wire i_read_en; - wire [31:0] i_addr; - wire [31:0] i_instr; - wire d_read_en; - wire d_write_en; - wire [31:0] d_addr; - wire [31:0] d_write_data; - wire [31:0] d_read_data; - - pipeline pipeline_inst - ( - .clk(clk), - .rst(rst), - .i_read_en(i_read_en), - .i_addr(i_addr), - .i_instr_in(i_instr), - .d_read_en(d_read_en), - .d_write_en(d_write_en), - .d_addr(d_addr), - .d_write_data(d_write_data), - .d_data_in(d_read_data) - ); + wire i_read_en; + wire [31:0] i_addr; + wire [31:0] i_instr; + wire d_read_en; + wire d_write_en; + wire [31:0] d_addr; + wire [31:0] d_write_data; + wire [31:0] d_read_data; + + assign mem_instr_read = i_read_en; + assign mem_instr_addr_bus = i_addr; + assign mem_instr_read_bus = i_instr; + + assign mem_data_write = d_write_en; + assign mem_data_read = d_read_en; + + assign mem_data_addr_bus = d_addr; + assign mem_data_read_bus = d_read_data; + assign mem_data_write_bus = d_write_data; + pipeline pipeline_inst ( + .clk(clk), + .rst(rst), + .i_read_en(i_read_en), + .i_addr(i_addr), + .i_instr_in(i_instr), + .d_read_en(d_read_en), + .d_write_en(d_write_en), + .d_addr(d_addr), + .d_write_data(d_write_data), + .d_data_in(d_read_data)); - dp_memory memory_inst - ( - .clk(clk), - .i_read_en(i_read_en), - .i_addr(i_addr), - .i_instr_out(i_instr), - .d_read_en(d_read_en), - .d_write_en(d_write_en), - .d_addr(d_addr), - .d_write_data(d_write_data), - .d_data_out(d_read_data) - ); - + dp_memory memory_inst ( + .clk(clk), + .i_read_en(i_read_en), + .i_addr(i_addr), + .i_instr_out(i_instr), + .d_read_en(d_read_en), + .d_write_en(d_write_en), + .d_addr(d_addr), + .d_write_data(d_write_data), + .d_data_out(d_read_data)); endmodule // mips_system diff --git a/hdl/pipeline.v b/hdl/pipeline.v index 01f94da..918106f 100644 --- a/hdl/pipeline.v +++ b/hdl/pipeline.v @@ -4,247 +4,220 @@ Pipelined CPU */ -module pipeline( - input wire clk, - input wire rst, +module pipeline ( input wire clk, + input wire rst, - output i_read_en, - output [31:0] i_addr, + output i_read_en, + output [31:0] i_addr, - input [31:0] i_instr_in, - - output wire d_read_en, - output wire d_write_en, - output wire [31:0] d_addr, - output wire [31:0] d_write_data, - input wire [31:0] d_data_in - ); + input [31:0] i_instr_in, + output wire d_read_en, + output wire d_write_en, + output wire [31:0] d_addr, + output wire [31:0] d_write_data, + input wire [31:0] d_data_in ); /* Interconnect wires*/ - wire [1:0] pc_source; - wire pc_write; - wire [31:0] jump_addr; - wire [31:0] branch_addr; - wire [31:0] next_i_addr; - wire [31:0] i_fetched; // fetched instrcution from if - wire if_id_write_en; // write enable for IF/ID pipe reg - - wire [31:0] wreg_data; // data to write into regfile - - wire [4:0] ex_dst_reg; - wire [5:0] ex_opcode; - - wire [4:0] id_rs; - wire [4:0] id_rt; - wire [5:0] id_opcode; - - wire ID_EX_wb_reg_write; - wire ID_EX_wb_mem_to_reg; - wire ID_EX_mem_read; - wire ID_EX_mem_write; - wire ID_EX_ex_imm_command; - wire ID_EX_ex_alu_src_b; - wire ID_EX_ex_dst_reg_sel; - wire [1:0] ID_EX_ex_alu_op; - wire [31:0] ID_EX_A; - wire [31:0] ID_EX_B; - wire [31:0] ID_EX_sign_extend_offset; - wire [4:0] ID_EX_rt; // target register - wire [4:0] ID_EX_rd; // destination register - wire [4:0] ID_EX_rs; // source register - wire [5:0] ID_EX_opcode; - - wire [31:0] EX_MEM_alu_result; - wire [31:0] EX_MEM_B_value; - wire [4:0] EX_MEM_dst_reg; - wire [5:0] EX_MEM_opcode; - wire EX_MEM_mem_read; - wire EX_MEM_mem_write; - wire EX_MEM_wb_reg_write; - wire EX_MEM_wb_mem_to_reg; - - wire [4:0] MEM_WB_dst_reg; - wire MEM_WB_reg_write; - wire MEM_WB_mem_to_reg; - wire [31:0] MEM_WB_mem_out; - wire [31:0] MEM_WB_alu_out; - - wire id_rt_is_source; - wire hazard_detected; - - - // forwarding control signals for muxes - wire [1:0] if_rs_forward_control; - wire [1:0] id_rt_forward_control; - wire [1:0] ex_rs_forward_control; - wire [1:0] ex_rt_forward_control; - - - - if_stage ifetch_inst - ( - .clk ( clk ), - .rst ( rst ), - .if_id_write_en ( if_id_write_en ), - .pc_write ( pc_write ), - .pc_source ( pc_source ), - .i_read_en ( i_read_en ), - .i_addr ( i_addr ), - .i_instr_in ( i_instr_in), - .jump_addr ( jump_addr ), - .branch_addr ( branch_addr ), - .IF_ID_instruction ( i_fetched ), - .IF_ID_next_i_addr ( next_i_addr ) - ); - - - hazard_unit hazard_inst - ( - .clk ( clk ), - .rst ( rst ), - .ex_dst_reg ( ex_dst_reg ), - .mem_dst_reg ( EX_MEM_dst_reg ), - .id_rs ( id_rs ), - .id_rt ( id_rt ), - .mem_opcode ( EX_MEM_opcode ), - .ex_opcode ( ex_opcode ), - .id_opcode ( id_opcode ), - .id_rt_is_source ( id_rt_is_source ), - .ex_reg_write ( ID_EX_wb_reg_write ), - .mem_reg_write ( EX_MEM_wb_reg_write ), - .pc_write ( pc_write ), - .if_id_write_en ( if_id_write_en ), - .hazard_detected ( hazard_detected ) - ); - - forwarding_unit forwarding_inst - ( - .ex_mem_reg_write (EX_MEM_wb_reg_write), - .mem_wb_reg_write (MEM_WB_reg_write), - .ex_mem_dst_reg (EX_MEM_dst_reg), - .mem_wb_dst_reg (MEM_WB_dst_reg), - .id_ex_rs (ID_EX_rs), - .id_ex_rt (ID_EX_rt), - .if_id_rs (id_rs), - .if_id_rt (id_rt), - .if_rs_forward_control ( if_rs_forward_control ), - .id_rt_forward_control ( id_rt_forward_control ), - .ex_rs_forward_control ( ex_rs_forward_control ), - .ex_rt_forward_control ( ex_rt_forward_control ) - ); - - - - id_stage idecode_inst - ( - .clk ( clk ), - .rst ( rst ), - .reg_write ( MEM_WB_reg_write ), - .wreg_addr ( MEM_WB_dst_reg ), // write register number - .wreg_data ( wreg_data ), // data to write into regfile - .instruction ( i_fetched ), - .next_i_addr ( next_i_addr ), // instruction fetched, next instruction address - - .rs_fwd_sel ( if_rs_forward_control ), // forwarding control signals - .rt_fwd_sel ( id_rt_forward_control ), // forwarding control signals - .mem_fwd_val ( EX_MEM_alu_result ), // forwarded data values from MEM - .wb_fwd_val ( wreg_data ), // forwarded data values from WB - - .hazard ( hazard_detected ), - .id_rs( id_rs ), - .id_rt( id_rt ), - .id_opcode( id_opcode ), - - .ID_EX_A ( ID_EX_A ), - .ID_EX_B ( ID_EX_B ), - .ID_EX_rt ( ID_EX_rt ), - .ID_EX_rs ( ID_EX_rs ), - .ID_EX_rd ( ID_EX_rd ), - .ID_EX_opcode ( ID_EX_opcode ), - .ID_EX_sign_extend_offset ( ID_EX_sign_extend_offset ), - .ID_EX_wb_reg_write ( ID_EX_wb_reg_write ), - .ID_EX_wb_mem_to_reg ( ID_EX_wb_mem_to_reg ), - .ID_EX_mem_read ( ID_EX_mem_read ), - .ID_EX_mem_write ( ID_EX_mem_write ), - .ID_EX_ex_imm_command ( ID_EX_ex_imm_command ), - .ID_EX_ex_alu_src_b ( ID_EX_ex_alu_src_b ), - .ID_EX_ex_dst_reg_sel ( ID_EX_ex_dst_reg_sel ), - .ID_EX_ex_alu_op ( ID_EX_ex_alu_op ), - - .branch_addr ( branch_addr ), - .jump_addr ( jump_addr ), - .id_rt_is_source ( id_rt_is_source ), - .if_pc_source ( pc_source ) - ); - - - ex_stage execute_inst - ( - .clk ( clk ), - .rst ( rst ), - .wb_reg_write ( ID_EX_wb_reg_write ), - .wb_mem_to_reg ( ID_EX_wb_mem_to_reg ), - .mem_read ( ID_EX_mem_read ), - .mem_write ( ID_EX_mem_write ), - .ex_imm_command ( ID_EX_ex_imm_command ), - .ex_alu_src_b ( ID_EX_ex_alu_src_b ), - .ex_dst_reg_sel ( ID_EX_ex_dst_reg_sel ), - .ex_alu_op ( ID_EX_ex_alu_op ), - .A ( ID_EX_A ), - .B ( ID_EX_B ), - .sign_extend_offset ( ID_EX_sign_extend_offset ), - .rt ( ID_EX_rt ), // target register - .rd ( ID_EX_rd ), // destination register - .opcode ( ID_EX_opcode ), - .rs_fwd_sel ( ex_rs_forward_control ), // forwarding muxes control - .rt_fwd_sel ( ex_rt_forward_control ), // forwarding muxes control - .mem_fwd_val ( EX_MEM_alu_result ), // forwarding from MEM - .wb_fwd_val ( wreg_data ), // forwarding from WB - .ex_dst_reg ( ex_dst_reg ), - .ex_opcode ( ex_opcode ), - .EX_MEM_alu_result ( EX_MEM_alu_result ), - .EX_MEM_B_value ( EX_MEM_B_value ), - .EX_MEM_dst_reg ( EX_MEM_dst_reg ), - .EX_MEM_opcode ( EX_MEM_opcode ), - .EX_MEM_mem_read ( EX_MEM_mem_read ), - .EX_MEM_mem_write ( EX_MEM_mem_write ), - .EX_MEM_wb_reg_write ( EX_MEM_wb_reg_write ), - .EX_MEM_wb_mem_to_reg ( EX_MEM_wb_mem_to_reg ) - ); - - - mem_stage memstage_inst - ( - .clk ( clk ), - .rst ( rst ), - .mem_read ( EX_MEM_mem_read ), - .mem_write ( EX_MEM_mem_write ), - .alu_result ( EX_MEM_alu_result ), - .B ( EX_MEM_B_value ), - .dst_reg ( EX_MEM_dst_reg ), - .wb_reg_write ( EX_MEM_wb_reg_write ), - .wb_mem_to_reg ( EX_MEM_wb_mem_to_reg ), - .MEM_WB_dst_reg ( MEM_WB_dst_reg ), - .MEM_WB_reg_write ( MEM_WB_reg_write ), - .MEM_WB_mem_to_reg ( MEM_WB_mem_to_reg ), - .MEM_WB_mem_out ( MEM_WB_mem_out ), - .MEM_WB_alu_out ( MEM_WB_alu_out ), - .d_read_en ( d_read_en ), - .d_write_en ( d_write_en ), - .d_addr ( d_addr ), - .d_write_data ( d_write_data ), - .d_data_in ( d_data_in ) - ); - - - wb_stage wb_inst - ( - .mem_to_reg ( MEM_WB_mem_to_reg ), - .mem_out ( MEM_WB_mem_out ), - .alu_out ( MEM_WB_alu_out ), - .write_data ( wreg_data ) - ); - + wire [1:0] pc_source; + wire pc_write; + wire [31:0] jump_addr; + wire [31:0] branch_addr; + wire [31:0] next_i_addr; + wire [31:0] i_fetched; // fetched instrcution from if + wire if_id_write_en; // write enable for IF/ID pipe reg + + wire [31:0] wreg_data; // data to write into regfile + + wire [4:0] ex_dst_reg; + wire [5:0] ex_opcode; + + wire [4:0] id_rs; + wire [4:0] id_rt; + wire [5:0] id_opcode; + + wire ID_EX_wb_reg_write; + wire ID_EX_wb_mem_to_reg; + wire ID_EX_mem_read; + wire ID_EX_mem_write; + wire ID_EX_ex_imm_command; + wire ID_EX_ex_alu_src_b; + wire ID_EX_ex_dst_reg_sel; + wire [1:0] ID_EX_ex_alu_op; + wire [31:0] ID_EX_A; + wire [31:0] ID_EX_B; + wire [31:0] ID_EX_sign_extend_offset; + wire [4:0] ID_EX_rt; // target register + wire [4:0] ID_EX_rd; // destination register + wire [4:0] ID_EX_rs; // source register + wire [5:0] ID_EX_opcode; + + wire [31:0] EX_MEM_alu_result; + wire [31:0] EX_MEM_B_value; + wire [4:0] EX_MEM_dst_reg; + wire [5:0] EX_MEM_opcode; + wire EX_MEM_mem_read; + wire EX_MEM_mem_write; + wire EX_MEM_wb_reg_write; + wire EX_MEM_wb_mem_to_reg; + + wire [4:0] MEM_WB_dst_reg; + wire MEM_WB_reg_write; + wire MEM_WB_mem_to_reg; + wire [31:0] MEM_WB_mem_out; + wire [31:0] MEM_WB_alu_out; + + wire id_rt_is_source; + wire hazard_detected; + + // forwarding control signals for muxes + wire [1:0] if_rs_forward_control; + wire [1:0] id_rt_forward_control; + wire [1:0] ex_rs_forward_control; + wire [1:0] ex_rt_forward_control; + + if_stage ifetch_inst( + .clk ( clk ), + .rst ( rst ), + .if_id_write_en ( if_id_write_en ), + .pc_write ( pc_write ), + .pc_source ( pc_source ), + .i_read_en ( i_read_en ), + .i_addr ( i_addr ), + .i_instr_in ( i_instr_in), + .jump_addr ( jump_addr ), + .branch_addr ( branch_addr ), + .IF_ID_instruction ( i_fetched ), + .IF_ID_next_i_addr ( next_i_addr )); + + hazard_unit hazard_inst( +// .clk ( clk ), isn't needed for now +// .rst ( rst ), isn't needed for now + .ex_dst_reg ( ex_dst_reg ), + .mem_dst_reg ( EX_MEM_dst_reg ), + .id_rs ( id_rs ), + .id_rt ( id_rt ), + .mem_opcode ( EX_MEM_opcode ), + .ex_opcode ( ex_opcode ), + .id_opcode ( id_opcode ), + .id_rt_is_source ( id_rt_is_source ), + .ex_reg_write ( ID_EX_wb_reg_write ), + .mem_reg_write ( EX_MEM_wb_reg_write ), + .pc_write ( pc_write ), + .if_id_write_en ( if_id_write_en ), + .hazard_detected ( hazard_detected )); + + forwarding_unit forwarding_inst( + .ex_mem_reg_write (EX_MEM_wb_reg_write), + .mem_wb_reg_write (MEM_WB_reg_write), + .ex_mem_dst_reg (EX_MEM_dst_reg), + .mem_wb_dst_reg (MEM_WB_dst_reg), + .id_ex_rs (ID_EX_rs), + .id_ex_rt (ID_EX_rt), + .if_id_rs (id_rs), + .if_id_rt (id_rt), + .if_rs_forward_control ( if_rs_forward_control ), + .id_rt_forward_control ( id_rt_forward_control ), + .ex_rs_forward_control ( ex_rs_forward_control ), + .ex_rt_forward_control ( ex_rt_forward_control )); + + id_stage idecode_inst( + .clk ( clk ), + .rst ( rst ), + .reg_write ( MEM_WB_reg_write ), + .wreg_addr ( MEM_WB_dst_reg ), // write register number + .wreg_data ( wreg_data ), // data to write into regfile + .instruction ( i_fetched ), + .next_i_addr ( next_i_addr ), // instruction fetched, next instruction address + + .rs_fwd_sel ( if_rs_forward_control ), // forwarding control signals + .rt_fwd_sel ( id_rt_forward_control ), // forwarding control signals + .mem_fwd_val ( EX_MEM_alu_result ), // forwarded data values from MEM + .wb_fwd_val ( wreg_data ), // forwarded data values from WB + + .hazard ( hazard_detected ), + .id_rs( id_rs ), + .id_rt( id_rt ), + .id_opcode( id_opcode ), + + .ID_EX_A ( ID_EX_A ), + .ID_EX_B ( ID_EX_B ), + .ID_EX_rt ( ID_EX_rt ), + .ID_EX_rs ( ID_EX_rs ), + .ID_EX_rd ( ID_EX_rd ), + .ID_EX_opcode ( ID_EX_opcode ), + .ID_EX_sign_extend_offset ( ID_EX_sign_extend_offset ), + .ID_EX_wb_reg_write ( ID_EX_wb_reg_write ), + .ID_EX_wb_mem_to_reg ( ID_EX_wb_mem_to_reg ), + .ID_EX_mem_read ( ID_EX_mem_read ), + .ID_EX_mem_write ( ID_EX_mem_write ), + .ID_EX_ex_imm_command ( ID_EX_ex_imm_command ), + .ID_EX_ex_alu_src_b ( ID_EX_ex_alu_src_b ), + .ID_EX_ex_dst_reg_sel ( ID_EX_ex_dst_reg_sel ), + .ID_EX_ex_alu_op ( ID_EX_ex_alu_op ), + + .branch_addr ( branch_addr ), + .jump_addr ( jump_addr ), + .id_rt_is_source ( id_rt_is_source ), + .if_pc_source ( pc_source )); + + ex_stage execute_inst( + .clk ( clk ), + .rst ( rst ), + .wb_reg_write ( ID_EX_wb_reg_write ), + .wb_mem_to_reg ( ID_EX_wb_mem_to_reg ), + .mem_read ( ID_EX_mem_read ), + .mem_write ( ID_EX_mem_write ), + .ex_imm_command ( ID_EX_ex_imm_command ), + .ex_alu_src_b ( ID_EX_ex_alu_src_b ), + .ex_dst_reg_sel ( ID_EX_ex_dst_reg_sel ), + .ex_alu_op ( ID_EX_ex_alu_op ), + .A ( ID_EX_A ), + .B ( ID_EX_B ), + .sign_extend_offset ( ID_EX_sign_extend_offset ), + .rt ( ID_EX_rt ), // target register + .rd ( ID_EX_rd ), // destination register + .opcode ( ID_EX_opcode ), + .rs_fwd_sel ( ex_rs_forward_control ), // forwarding muxes control + .rt_fwd_sel ( ex_rt_forward_control ), // forwarding muxes control + .mem_fwd_val ( EX_MEM_alu_result ), // forwarding from MEM + .wb_fwd_val ( wreg_data ), // forwarding from WB + .ex_dst_reg ( ex_dst_reg ), + .ex_opcode ( ex_opcode ), + .EX_MEM_alu_result ( EX_MEM_alu_result ), + .EX_MEM_B_value ( EX_MEM_B_value ), + .EX_MEM_dst_reg ( EX_MEM_dst_reg ), + .EX_MEM_opcode ( EX_MEM_opcode ), + .EX_MEM_mem_read ( EX_MEM_mem_read ), + .EX_MEM_mem_write ( EX_MEM_mem_write ), + .EX_MEM_wb_reg_write ( EX_MEM_wb_reg_write ), + .EX_MEM_wb_mem_to_reg ( EX_MEM_wb_mem_to_reg )); + + mem_stage memstage_inst( + .clk ( clk ), + .rst ( rst ), + .mem_read ( EX_MEM_mem_read ), + .mem_write ( EX_MEM_mem_write ), + .alu_result ( EX_MEM_alu_result ), + .B ( EX_MEM_B_value ), + .dst_reg ( EX_MEM_dst_reg ), + .wb_reg_write ( EX_MEM_wb_reg_write ), + .wb_mem_to_reg ( EX_MEM_wb_mem_to_reg ), + .MEM_WB_dst_reg ( MEM_WB_dst_reg ), + .MEM_WB_reg_write ( MEM_WB_reg_write ), + .MEM_WB_mem_to_reg ( MEM_WB_mem_to_reg ), + .MEM_WB_mem_out ( MEM_WB_mem_out ), + .MEM_WB_alu_out ( MEM_WB_alu_out ), + .d_read_en ( d_read_en ), + .d_write_en ( d_write_en ), + .d_addr ( d_addr ), + .d_write_data ( d_write_data ), + .d_data_in ( d_data_in )); + + wb_stage wb_inst( + .mem_to_reg ( MEM_WB_mem_to_reg ), + .mem_out ( MEM_WB_mem_out ), + .alu_out ( MEM_WB_alu_out ), + .write_data ( wreg_data )); endmodule diff --git a/hdl/testbench.v b/hdl/testbench.v index 6100226..a980d65 100644 --- a/hdl/testbench.v +++ b/hdl/testbench.v @@ -2,72 +2,68 @@ module testbench; - - // Inputs - reg clk; - reg rst; - reg [31:0] ext_data_in; - - // Outputs - wire ext_write_en; - wire ext_read_en; - wire [31:0] ext_addr; - wire [31:0] ext_write_data; - - // Instantiate the Unit Under Test (UUT) - mips_system uut ( - .clk(clk), - .rst(rst), - .ext_write_en(ext_write_en), - .ext_read_en(ext_read_en), - .ext_addr(ext_addr), - .ext_write_data(ext_write_data), - .ext_data_in(ext_data_in) - ); - - initial begin - rst = 1; - ext_data_in = 0; + + //Inputs + reg mips_clk; + reg mips_rst; + + //Outputs + wire mem_instr_read; + wire [31:0] mem_instr_addr_bus, mem_instr_read_bus; + + wire mem_data_write, mem_data_read; + wire [31:0] mem_data_addr_bus, mem_data_read_bus, mem_data_write_bus; + + //Instantiate the Unit Under Test (UUT) + mips_system uut ( + .clk(mips_clk), + .rst(mips_rst), + + .mem_instr_read(mem_instr_read), + .mem_instr_addr_bus(mem_instr_addr_bus), + .mem_instr_read_bus(mem_instr_read_bus), + + .mem_data_write(mem_data_write), + .mem_data_read(mem_data_read), + .mem_data_addr_bus(mem_data_addr_bus), + .mem_data_read_bus(mem_data_read_bus), + .mem_data_write_bus(mem_data_write_bus)); + + initial begin + mips_rst = 1; + + // Wait 100 ns for global reset to finish + #100; + mips_rst = 0; - // Wait 100 ns for global reset to finish - #100; - rst = 0; - - end // initial begin - - - initial begin - clk = 0; - forever - #10 clk = !clk; - end - - + end // initial begin + + initial begin + mips_clk = 0; + forever + #10 mips_clk = !mips_clk; + end + integer i; - initial begin - - for (i = 0; i < 1000; i=i+1) - @(posedge clk); - + + initial begin + for (i = 0; i < 1000; i=i+1) + @(posedge mips_clk); - $stop(); - end + $stop(); + end - initial - begin - $display("Trace register $t0"); - @(negedge rst); + initial begin + $display("Trace register $t0"); + + @(negedge mips_rst); - forever - begin - @(posedge clk); - $display("$t0 (REG8) = %x",uut.pipeline_inst.idecode_inst.regfile_inst.rf[8]); - end + forever begin + @(posedge mips_clk); - - - end - + $display("%d ns: $t0 (REG8) = %x", $time, uut.pipeline_inst.idecode_inst.regfile_inst.rf[8]); + end + end endmodule diff --git a/hdl/wb_stage.v b/hdl/wb_stage.v index 37cfc38..66ff2a9 100644 --- a/hdl/wb_stage.v +++ b/hdl/wb_stage.v @@ -1,11 +1,9 @@ `timescale 1ns / 1ps -module wb_stage( - input mem_to_reg, - input [31:0] mem_out, alu_out, - output [31:0] write_data - ); +module wb_stage( input mem_to_reg, + input [31:0] mem_out, alu_out, + output [31:0] write_data ); - assign write_data = mem_to_reg ? mem_out : alu_out; + assign write_data = mem_to_reg ? mem_out : alu_out; endmodule diff --git a/sw/test.axf b/sw/test.axf Binary files differnew file mode 100644 index 0000000..8980798 --- /dev/null +++ b/sw/test.axf diff --git a/sw/test.lst b/sw/test.lst new file mode 100644 index 0000000..2e20878 --- /dev/null +++ b/sw/test.lst @@ -0,0 +1,19 @@ + +test.axf: file format elf32-tradbigmips + + +Disassembly of section .text: + +00000000 <entry>: + 0: 8c080200 lw t0,512(zero) + 4: 8c090200 lw t1,512(zero) + 8: 00000000 nop + c: 01094020 add t0,t0,t1 + 10: 2108000b addi t0,t0,11 + 14: 01094022 sub t0,t0,t1 + 18: 35080010 ori t0,t0,0x10 + 1c: 01094026 xor t0,t0,t1 + 20: 0109402a slt t0,t0,t1 + 24: 01094020 add t0,t0,t1 + 28: 1109fff5 beq t0,t1,0 <entry> + 2c: 00000000 nop diff --git a/sw/test.o b/sw/test.o Binary files differnew file mode 100644 index 0000000..cef51ba --- /dev/null +++ b/sw/test.o diff --git a/sw/test.rom b/sw/test.rom new file mode 100644 index 0000000..3b9dc38 --- /dev/null +++ b/sw/test.rom @@ -0,0 +1,6 @@ +@00000000 +8C080200 8C090200 00000000 01094020 +2108000B 01094022 35080010 01094026 +0109402A 01094020 1109FFF5 00000000 +@00000200 +00000001 0000FFFF diff --git a/sw/test.vh b/sw/test.vh new file mode 100644 index 0000000..926a474 --- /dev/null +++ b/sw/test.vh @@ -0,0 +1,6 @@ +@00000000 +8C 08 02 00 8C 09 02 00 00 00 00 00 01 09 40 20 +21 08 00 0B 01 09 40 22 35 08 00 10 01 09 40 26 +01 09 40 2A 01 09 40 20 11 09 FF F5 00 00 00 00 +@00000200 +00 00 00 01 00 00 FF FF |