diff --git a/litex/soc/cores/cpu/blackparrot/bp_litex/bp2wb_convertor.v b/litex/soc/cores/cpu/blackparrot/bp_litex/bp2wb_convertor.v new file mode 100644 index 000000000..d045f68c5 --- /dev/null +++ b/litex/soc/cores/cpu/blackparrot/bp_litex/bp2wb_convertor.v @@ -0,0 +1,237 @@ +/** + * bp2wb_convertor.v + * DESCRIPTION: THIS MODULE ADAPTS BP MEMORY BUS TO 64-BIT WISHBONE + */ + +module bp2wb_convertor + import bp_common_pkg::*; + import bp_common_aviary_pkg::*; + import bp_cce_pkg::*; + import bp_me_pkg::*; + #(parameter bp_params_e bp_params_p = e_bp_single_core_cfg + `declare_bp_proc_params(bp_params_p) + `declare_bp_me_if_widths(paddr_width_p, cce_block_width_p, lce_id_width_p, lce_assoc_p) + +// , parameter [paddr_width_p-1:0] dram_offset_p = '0 + , localparam num_block_words_lp = cce_block_width_p / 64 + , localparam num_block_bytes_lp = cce_block_width_p / 8 + , localparam num_word_bytes_lp = dword_width_p / 8 + , localparam block_offset_bits_lp = `BSG_SAFE_CLOG2(num_block_bytes_lp) + , localparam word_offset_bits_lp = `BSG_SAFE_CLOG2(num_block_words_lp) + , localparam byte_offset_bits_lp = `BSG_SAFE_CLOG2(num_word_bytes_lp) + , localparam wbone_data_width = 64 + , localparam wbone_addr_ubound = paddr_width_p + , localparam mem_granularity = 64 //TODO: adapt selection bit parametrized + , localparam wbone_addr_lbound = 3 //`BSG_SAFE_CLOG2(wbone_data_width / mem_granularity) //dword granularity + , localparam total_datafetch_cycle_lp = cce_block_width_p / wbone_data_width + , localparam total_datafetch_cycle_width = `BSG_SAFE_CLOG2(total_datafetch_cycle_lp) + , localparam cached_addr_base = 32'h7000_0000//6000_0000 //32'h4000_4000// + ) + ( input clk_i + ,(* mark_debug = "true" *) input reset_i + + // BP side + ,(* mark_debug = "true" *) input [cce_mem_msg_width_lp-1:0] mem_cmd_i + ,(* mark_debug = "true" *) input mem_cmd_v_i + ,(* mark_debug = "true" *) output mem_cmd_ready_o + + , output [cce_mem_msg_width_lp-1:0] mem_resp_o + , (* mark_debug = "true" *) output mem_resp_v_o + , (* mark_debug = "true" *) input mem_resp_yumi_i + + // Wishbone side + , (* mark_debug = "true" *) input [63:0] dat_i + , (* mark_debug = "true" *) output logic [63:0] dat_o + , (* mark_debug = "true" *) input ack_i + , input err_i +// , input rty_i + , (* mark_debug = "true" *) output logic [wbone_addr_ubound-wbone_addr_lbound-1:0] adr_o//TODO: Double check!!! + , (* mark_debug = "true" *) output logic stb_o + , output cyc_o + , output [7:0] sel_o //TODO: double check!!! + , (* mark_debug = "true" *) output we_o + , output [2:0] cti_o //TODO: hardwire in Litex + , output [1:0] bte_o //TODO: hardwire in Litex + + ); + + `declare_bp_me_if(paddr_width_p, cce_block_width_p, lce_id_width_p, lce_assoc_p); + + //locals + (* mark_debug = "true" *) logic [total_datafetch_cycle_width:0] ack_ctr = 0; + (* mark_debug = "true" *) bp_cce_mem_msg_s mem_cmd_cast_i, mem_resp_cast_o, mem_cmd_debug, mem_cmd_debug2; + (* mark_debug = "true" *) logic ready_li, v_li, stb_justgotack; + (* mark_debug = "true" *) logic [cce_block_width_p-1:0] data_lo; + (* mark_debug = "true" *) logic [cce_block_width_p-1:0] data_li; + (* mark_debug = "true" *) wire [paddr_width_p-1:0] mem_cmd_addr_l; + (* mark_debug = "true" *) logic set_stb; + + + //Handshaking between Wishbone and BlackParrot through convertor + //3.1.3:At every rising edge of [CLK_I] the terminating signal(ACK) is sampled. If it + //is asserted, then [STB_O] is negated. + + assign ready_li = ( ack_ctr == 0 ) & !set_stb & !mem_resp_v_o; + assign mem_cmd_ready_o = ready_li;//!stb_o then ready to take! + // assign v_li = (ack_ctr == total_datafetch_cycle_lp-1); + assign mem_resp_v_o = v_li; + assign stb_o = (set_stb) && !stb_justgotack; + assign cyc_o = stb_o; + assign sel_o = 8'b11111111; + assign cti_o = 0; + assign bte_o = 0; + + initial begin + ack_ctr = 0; + end + + +//Flip stb after each ack--->RULE 3.20: +// Every time we get an ACK from WB, increment counter until the counter reaches to total_datafetch_cycle_lp + always_ff @(posedge clk_i) + begin + + if(reset_i) + begin + ack_ctr <= 0; + set_stb <= 0; + v_li <=0; + end + else if (v_li) + begin + if (mem_resp_yumi_i) + begin + v_li <= 0; + ack_ctr <= 0; + end + end + else if (mem_cmd_v_i) + begin + //data_li <= 0; + set_stb <= 1; + v_li <= 0; + stb_justgotack <= 0; + end + + else + begin + if (ack_i)//stb should be negated after ack + begin + stb_justgotack <= 1; + data_li[(ack_ctr*wbone_data_width) +: wbone_data_width] <= dat_i; + if ((ack_ctr == total_datafetch_cycle_lp-1) || (mem_cmd_addr_l < cached_addr_base && mem_cmd_r.header.msg_type == e_cce_mem_uc_wr )) //if uncached store, just one cycle is fine + begin + v_li <=1; + set_stb <= 0; + end + else + ack_ctr <= ack_ctr + 1; + end + else + begin + stb_justgotack <= 0; + v_li <=0; + end + end + end + + //Packet Pass from BP to BP2WB + assign mem_cmd_cast_i = mem_cmd_i; + bp_cce_mem_msg_s mem_cmd_r; + bsg_dff_reset_en + #(.width_p(cce_mem_msg_width_lp)) + mshr_reg + (.clk_i(clk_i) + ,.reset_i(reset_i) + ,.en_i(mem_cmd_v_i)//when + ,.data_i(mem_cmd_i) + ,.data_o(mem_cmd_r) + ); + + //Addr && Data && Command Pass from BP2WB to WB + logic [wbone_addr_lbound-1:0] throw_away; + assign mem_cmd_addr_l = mem_cmd_r.header.addr; + assign data_lo = mem_cmd_r.data; + logic [39:0] mem_cmd_addr_l_zero64; + always_comb begin + if( mem_cmd_addr_l < cached_addr_base ) + begin + adr_o = mem_cmd_addr_l[wbone_addr_ubound-1:wbone_addr_lbound];//no need to change address for uncached stores/loads + dat_o = data_lo[(0*wbone_data_width) +: wbone_data_width];//unchached data is stored in LS 64bits + end + + else + begin + mem_cmd_addr_l_zero64 = mem_cmd_addr_l >> 6 << 6; + {adr_o,throw_away} = mem_cmd_addr_l_zero64 + (ack_ctr*8);//TODO:careful + dat_o = data_lo[(ack_ctr*wbone_data_width) +: wbone_data_width]; + end + end + + assign we_o = (mem_cmd_r.header.msg_type inside {e_cce_mem_uc_wr, e_cce_mem_wr}); + +//Data Pass from BP2WB to BP + +wire [cce_block_width_p-1:0] rd_word_offset = mem_cmd_r.header.addr[3+:3]; +//wire [cce_block_width_p-1:0] rd_byte_offset = mem_cmd_r.addr[0+:3]; +wire [cce_block_width_p-1:0] rd_bit_shift = rd_word_offset*64; // We rely on receiver to adjust bits + +(* mark_debug = "true" *) wire [cce_block_width_p-1:0] data_li_resp = (mem_cmd_r.header.msg_type == e_cce_mem_uc_rd) + ? data_li >> rd_bit_shift + : data_li; + + + +assign mem_resp_cast_o = '{data : data_li_resp + ,header :'{payload : mem_cmd_r.header.payload + ,size : mem_cmd_r.header.size + ,addr : mem_cmd_r.header.addr + ,msg_type: mem_cmd_r.header.msg_type + } + }; + +assign mem_resp_o = mem_resp_cast_o; + +/*********************************************/ +/*DEBUG SECTION*/ + + + +/*wire [3:0] fake_msg_type; +wire [10:0] fake_payload; +wire [2:0] fake_size; +wire [39:0] fake_addr; +assign fake_payload = mem_cmd_r.header.payload; +assign fake_size = mem_cmd_r.header.size; +assign fake_addr = mem_cmd_r.header.addr; +assign fake_msg_type = mem_cmd_r.header.msg_type; +*/ +/*(* mark_debug = "true" *) logic debug_wire; + initial begin + debug_wire = 0; + end + + assign mem_cmd_debug = mem_cmd_i; + +always_ff @(posedge clk_i) +debug_wire <= (ack_i && mem_cmd_debug.header.addr >= 32'h80000000); + + always_ff @(posedge clk_i) + begin + if(mem_cmd_v_i && mem_cmd_debug.header.addr <= 32'h60000000) + begin + debug_wire <= 1; +// $display("addr == %x", mem_cmd_debug.header.addr); + end +/* if (mem_resp_v_o && debug_ctr < 64 && mem_cmd_debug.header.addr >= 32'h80000000) + begin + debug_gotdata[((debug_ctr-1)*512) +: 512] <= data_li_resp; + $display("data == %x", data_li_resp); + end*/ +// end + +wire [3:0] typean; +assign typean = mem_cmd_r.header.msg_type; + +endmodule + diff --git a/litex/soc/cores/cpu/blackparrot/bp_litex/bsg_mem_1rw_sync_mask_write_bit.v b/litex/soc/cores/cpu/blackparrot/bp_litex/bsg_mem_1rw_sync_mask_write_bit.v new file mode 100644 index 000000000..a6fdae9a6 --- /dev/null +++ b/litex/soc/cores/cpu/blackparrot/bp_litex/bsg_mem_1rw_sync_mask_write_bit.v @@ -0,0 +1,55 @@ +/* +* bsg_mem_1rw_sync_mask_write_bit.v +* +* distributed synchronous 1-port ram for xilinx ultrascale or ultrascale plus FPGA +* Write mode: No-change | Read mode: No-change +* Note: +* There are 2 basic BRAM library primitives, RAMB18E2 and RAMB36E2 in Vivado. +* But none of them support bit-wise mask. They have Byte-wide write enable ports though. +* So we use the RAM_STYLE attribute to instruct the tool to infer distributed LUT RAM instead. +* +* To save resources, the code is written to be inferred as Signle-port distributed ram RAM64X1S. +* https://www.xilinx.com/support/documentation/user_guides/ug574-ultrascale-clb.pdf +* +*/ + + +module bsg_mem_1rw_sync_mask_write_bit #( + parameter width_p = "inv" + , parameter els_p = "inv" + , parameter latch_last_read_p=0 + , parameter enable_clock_gating_p=0 + , localparam addr_width_lp = `BSG_SAFE_CLOG2(els_p) +) ( + input clk_i + , input reset_i + , input [ width_p-1:0] data_i + , input [addr_width_lp-1:0] addr_i + , input v_i + , input [ width_p-1:0] w_mask_i + , input w_i + , output [ width_p-1:0] data_o +); + + wire unused = reset_i; + + (* ram_style = "distributed" *) logic [width_p-1:0] mem [els_p-1:0]; + + logic [width_p-1:0] data_r; + always_ff @(posedge clk_i) begin + if (v_i & ~w_i) + data_r <= mem[addr_i]; + end + + assign data_o = data_r; + + for (genvar i=0; i 1) begin + assert (cosim_p == 0) else $error("cosim_p not supported for num_core_p > 1"); + end +end + +logic [num_core_p-1:0] program_finish_lo; +logic cosim_finish_lo; + +bp_cce_mem_msg_s proc_mem_cmd_lo; +logic proc_mem_cmd_v_lo, proc_mem_cmd_ready_li; +bp_cce_mem_msg_s proc_mem_resp_li; +logic proc_mem_resp_v_li, proc_mem_resp_yumi_lo; + +bp_cce_mem_msg_s proc_io_cmd_lo; +logic proc_io_cmd_v_lo, proc_io_cmd_ready_li; +bp_cce_mem_msg_s proc_io_resp_li; +logic proc_io_resp_v_li, proc_io_resp_yumi_lo; + +bp_cce_mem_msg_s io_cmd_lo; +logic io_cmd_v_lo, io_cmd_ready_li; +bp_cce_mem_msg_s io_resp_li; +logic io_resp_v_li, io_resp_yumi_lo; + +bp_cce_mem_msg_s nbf_cmd_lo; +logic nbf_cmd_v_lo, nbf_cmd_yumi_li; +bp_cce_mem_msg_s nbf_resp_li; +logic nbf_resp_v_li, nbf_resp_ready_lo; + +bp_cce_mem_msg_s cfg_cmd_lo; +logic cfg_cmd_v_lo, cfg_cmd_yumi_li; +bp_cce_mem_msg_s cfg_resp_li; +logic cfg_resp_v_li, cfg_resp_ready_lo; + +bp_cce_mem_msg_s load_cmd_lo; +logic load_cmd_v_lo, load_cmd_yumi_li; +bp_cce_mem_msg_s load_resp_li; +logic load_resp_v_li, load_resp_ready_lo; + +bp_softcore +#(.bp_params_p(bp_params_p)) + softcore + (.clk_i(clk_i) + ,.reset_i(reset_i) + + ,.io_cmd_o(proc_io_cmd_lo) + ,.io_cmd_v_o(proc_io_cmd_v_lo) + ,.io_cmd_ready_i(proc_io_cmd_ready_li) + + ,.io_resp_i(proc_io_resp_li) + ,.io_resp_v_i(proc_io_resp_v_li) + ,.io_resp_yumi_o(proc_io_resp_yumi_lo) + + ,.io_cmd_i(load_cmd_lo) + ,.io_cmd_v_i(load_cmd_v_lo) + ,.io_cmd_yumi_o(load_cmd_yumi_li) + + ,.io_resp_o(load_resp_li) + ,.io_resp_v_o(load_resp_v_li) + ,.io_resp_ready_i(load_resp_ready_lo) + + ,.mem_cmd_o(proc_mem_cmd_lo) + ,.mem_cmd_v_o(proc_mem_cmd_v_lo) + ,.mem_cmd_ready_i(proc_mem_cmd_ready_li) + + ,.mem_resp_i(proc_mem_resp_li) + ,.mem_resp_v_i(proc_mem_resp_v_li) + ,.mem_resp_yumi_o(proc_mem_resp_yumi_lo) + ); + + bp2wb_convertor + #(.bp_params_p(bp_params_p)) + bp2wb + (.clk_i(clk_i) + ,.reset_i(reset_i) + ,.mem_cmd_i(proc_mem_cmd_lo) + ,.mem_cmd_v_i(proc_mem_cmd_ready_li & proc_mem_cmd_v_lo) + ,.mem_cmd_ready_o(proc_mem_cmd_ready_li) + + ,.mem_resp_o(proc_mem_resp_li) + ,.mem_resp_v_o(proc_mem_resp_v_li) + ,.mem_resp_yumi_i(proc_mem_resp_yumi_lo) + ,.dat_i(wbm_dat_i) + ,.dat_o(wbm_dat_o) + ,.ack_i(wbm_ack_i) + ,.adr_o(wbm_adr_o) + ,.stb_o(wbm_stb_o) + ,.cyc_o(wbm_cyc_o) + ,.sel_o(wbm_sel_o ) + ,.we_o(wbm_we_o) + ,.cti_o(wbm_cti_o) + ,.bte_o(wbm_bte_o ) + // ,.rty_i(wbm_rty_i) + ,.err_i(wbm_err_i) + ); + + +assign proc_io_cmd_ready_li = 1;//TODO: make sure this is necessary + +logic nbf_done_lo, cfg_done_lo; +if (load_nbf_p) + begin : nbf + bp_nonsynth_nbf_loader + #(.bp_params_p(bp_params_p)) + nbf_loader + (.clk_i(clk_i) + ,.reset_i(reset_i | ~cfg_done_lo) + + ,.lce_id_i(lce_id_width_p'('b10)) + + ,.io_cmd_o(nbf_cmd_lo) + ,.io_cmd_v_o(nbf_cmd_v_lo) + ,.io_cmd_yumi_i(nbf_cmd_yumi_li) + + ,.io_resp_i(nbf_resp_li) + ,.io_resp_v_i(nbf_resp_v_li) + ,.io_resp_ready_o(nbf_resp_ready_lo) + + ,.done_o(nbf_done_lo) + ); + end +else + begin : no_nbf + assign nbf_resp_ready_lo = 1'b1; + assign nbf_cmd_v_lo = '0; + assign nbf_cmd_lo = '0; + + assign nbf_done_lo = 1'b1; + end + +localparam cce_instr_ram_addr_width_lp = `BSG_SAFE_CLOG2(num_cce_instr_ram_els_p); +bp_cce_mmio_cfg_loader + #(.bp_params_p(bp_params_p) + ,.inst_width_p($bits(bp_cce_inst_s)) + ,.inst_ram_addr_width_p(cce_instr_ram_addr_width_lp) + ,.inst_ram_els_p(num_cce_instr_ram_els_p) + ,.skip_ram_init_p(skip_init_p) + ,.clear_freeze_p(!load_nbf_p) + ) + cfg_loader + (.clk_i(clk_i) + ,.reset_i(reset_i) + + ,.lce_id_i(lce_id_width_p'('b10)) + + ,.io_cmd_o(cfg_cmd_lo) + ,.io_cmd_v_o(cfg_cmd_v_lo) + ,.io_cmd_yumi_i(cfg_cmd_yumi_li) + + ,.io_resp_i(cfg_resp_li) + ,.io_resp_v_i(cfg_resp_v_li) + ,.io_resp_ready_o(cfg_resp_ready_lo) + + ,.done_o(cfg_done_lo) + ); + +// CFG and NBF are mutex, so we can just use fixed arbitration here +always_comb + if (~cfg_done_lo) + begin + load_cmd_lo = cfg_cmd_lo; + load_cmd_v_lo = cfg_cmd_v_lo; + + nbf_cmd_yumi_li = '0; + cfg_cmd_yumi_li = load_cmd_yumi_li; + + load_resp_ready_lo = cfg_resp_ready_lo; + + nbf_resp_li = '0; + nbf_resp_v_li = '0; + + cfg_resp_li = load_resp_li; + cfg_resp_v_li = load_resp_v_li; + end + else + begin + load_cmd_lo = nbf_cmd_lo; + load_cmd_v_lo = nbf_cmd_v_lo; + + nbf_cmd_yumi_li = load_cmd_yumi_li; + cfg_cmd_yumi_li = '0; + + load_resp_ready_lo = nbf_resp_ready_lo; + + nbf_resp_li = load_resp_li; + nbf_resp_v_li = load_resp_v_li; + + cfg_resp_li = '0; + cfg_resp_v_li = '0; + end + +/*bp_nonsynth_host + #(.bp_params_p(bp_params_p)) + host + (.clk_i(clk_i) + ,.reset_i(reset_i) + + ,.io_cmd_i(proc_io_cmd_lo) + ,.io_cmd_v_i(proc_io_cmd_v_lo & proc_io_cmd_ready_li) + ,.io_cmd_ready_o(proc_io_cmd_ready_li) + + ,.io_resp_o(proc_io_resp_li) + ,.io_resp_v_o(proc_io_resp_v_li) + ,.io_resp_yumi_i(proc_io_resp_yumi_lo) + + ,.program_finish_o(program_finish_lo) + ); +*/ +/*bind bp_be_top + bp_nonsynth_commit_tracer + #(.bp_params_p(bp_params_p)) + commit_tracer + (.clk_i(clk_i & (ExampleBlackParrotSystem.cmt_trace_p == 1)) + ,.reset_i(reset_i) + ,.freeze_i(be_checker.scheduler.int_regfile.cfg_bus.freeze) + + ,.mhartid_i('0) + + ,.decode_i(be_calculator.reservation_n.decode) + + ,.commit_v_i(be_calculator.commit_pkt.instret) + ,.commit_pc_i(be_calculator.commit_pkt.pc) + ,.commit_instr_i(be_calculator.commit_pkt.instr) + + ,.rd_w_v_i(be_checker.scheduler.wb_pkt.rd_w_v) + ,.rd_addr_i(be_checker.scheduler.wb_pkt.rd_addr) + ,.rd_data_i(be_checker.scheduler.wb_pkt.rd_data) + ); +*/ +/* if (num_core_p == 1) + begin : cosim + bind bp_be_top + bp_nonsynth_cosim + #(.bp_params_p(bp_params_p)) + cosim + (.clk_i(clk_i) + ,.reset_i(reset_i) + ,.freeze_i(be_checker.scheduler.int_regfile.cfg_bus.freeze) + ,.en_i(ExampleBlackParrotSystem.cosim_p == 1) + ,.cosim_instr_i(ExampleBlackParrotSystem.cosim_instr_p) + + ,.mhartid_i(be_checker.scheduler.int_regfile.cfg_bus.core_id) + // Want to pass config file as a parameter, but cannot in Verilator 4.025 + // Parameter-resolved constants must not use dotted references + ,.config_file_i(ExampleBlackParrotSystem.cosim_cfg_file_p) + + ,.decode_i(be_calculator.reservation_n.decode) + + ,.commit_v_i(be_calculator.commit_pkt.instret) + ,.commit_pc_i(be_calculator.commit_pkt.pc) + ,.commit_instr_i(be_calculator.commit_pkt.instr) + + ,.rd_w_v_i(be_checker.scheduler.wb_pkt.rd_w_v) + ,.rd_addr_i(be_checker.scheduler.wb_pkt.rd_addr) + ,.rd_data_i(be_checker.scheduler.wb_pkt.rd_data) + + ,.interrupt_v_i(be_mem.csr.trap_pkt_cast_o._interrupt) + ,.cause_i(be_mem.csr.trap_pkt_cast_o.cause) + + ,.finish_o(ExampleBlackParrotSystem.cosim_finish_lo) + ); + end + else + begin : no_cosim*/ + assign cosim_finish_lo = '0; + // end + +/*bind bp_be_top + bp_be_nonsynth_perf + #(.bp_params_p(bp_params_p)) + perf + (.clk_i(clk_i) + ,.reset_i(reset_i) + ,.freeze_i(be_checker.scheduler.int_regfile.cfg_bus.freeze) + ,.warmup_instr_i(ExampleBlackParrotSystem.warmup_instr_p) + + ,.mhartid_i(be_checker.scheduler.int_regfile.cfg_bus.core_id) + + ,.commit_v_i(be_calculator.commit_pkt.instret) + + ,.program_finish_i(ExampleBlackParrotSystem.program_finish_lo | ExampleBlackParrotSystem.cosim_finish_lo) + ); +*/ +/* bind bp_be_top + bp_nonsynth_watchdog + #(.bp_params_p(bp_params_p) + ,.timeout_cycles_p(100000) + ,.heartbeat_instr_p(100000) + ) + watchdog + (.clk_i(clk_i) + ,.reset_i(reset_i) + ,.freeze_i(be_checker.scheduler.int_regfile.cfg_bus.freeze) + + ,.mhartid_i(be_checker.scheduler.int_regfile.cfg_bus.core_id) + + ,.npc_i(be_checker.director.npc_r) + ,.instret_i(be_calculator.commit_pkt.instret) + ); +*/ +/* bind bp_be_director + bp_be_nonsynth_npc_tracer + #(.bp_params_p(bp_params_p)) + npc_tracer + (.clk_i(clk_i & (ExampleBlackParrotSystem.npc_trace_p == 1)) + ,.reset_i(reset_i) + ,.freeze_i(be_checker.scheduler.int_regfile.cfg_bus.freeze) + + ,.mhartid_i(be_checker.scheduler.int_regfile.cfg_bus.core_id) + + ,.npc_w_v(npc_w_v) + ,.npc_n(npc_n) + ,.npc_r(npc_r) + ,.expected_npc_o(expected_npc_o) + + ,.fe_cmd_i(fe_cmd) + ,.fe_cmd_v(fe_cmd_v) + + ,.commit_pkt_i(commit_pkt) + ); +*/ +/* bind bp_be_dcache + bp_nonsynth_cache_tracer + #(.bp_params_p(bp_params_p) + ,.assoc_p(dcache_assoc_p) + ,.sets_p(dcache_sets_p) + ,.block_width_p(dcache_block_width_p) + ,.trace_file_p("dcache")) + dcache_tracer + (.clk_i(clk_i & (ExampleBlackParrotSystem.dcache_trace_p == 1)) + ,.reset_i(reset_i) + ,.freeze_i(cfg_bus_cast_i.freeze) + + ,.mhartid_i(cfg_bus_cast_i.core_id) + + ,.v_tl_r(v_tl_r) + + ,.v_tv_r(v_tv_r) + ,.addr_tv_r(paddr_tv_r) + ,.lr_miss_tv(lr_miss_tv) + ,.sc_op_tv_r(sc_op_tv_r) + ,.sc_success(sc_success) + + ,.cache_req_v_o(cache_req_v_o) + ,.cache_req_o(cache_req_o) + + ,.cache_req_metadata_o(cache_req_metadata_o) + ,.cache_req_metadata_v_o(cache_req_metadata_v_o) + + ,.cache_req_complete_i(cache_req_complete_i) + + ,.v_o(v_o) + ,.load_data(data_o) + ,.cache_miss_o(dcache_miss_o) + ,.wt_req(wt_req) + ,.store_data(data_tv_r) + + ,.data_mem_pkt_v_i(data_mem_pkt_v_i) + ,.data_mem_pkt_i(data_mem_pkt_i) + ,.data_mem_pkt_yumi_o(data_mem_pkt_yumi_o) + + ,.tag_mem_pkt_v_i(tag_mem_pkt_v_i) + ,.tag_mem_pkt_i(tag_mem_pkt_i) + ,.tag_mem_pkt_yumi_o(tag_mem_pkt_yumi_o) + + ,.stat_mem_pkt_v_i(stat_mem_pkt_v_i) + ,.stat_mem_pkt_i(stat_mem_pkt_i) + ,.stat_mem_pkt_yumi_o(stat_mem_pkt_yumi_o) + ); +*/ +/* bind bp_fe_icache + bp_nonsynth_cache_tracer + #(.bp_params_p(bp_params_p) + ,.assoc_p(icache_assoc_p) + ,.sets_p(icache_sets_p) + ,.block_width_p(icache_block_width_p) + ,.trace_file_p("icache")) + icache_tracer + (.clk_i(clk_i & (ExampleBlackParrotSystem.icache_trace_p == 1)) + ,.reset_i(reset_i) + + ,.freeze_i(cfg_bus_cast_i.freeze) + ,.mhartid_i(cfg_bus_cast_i.core_id) + + ,.v_tl_r(v_tl_r) + + ,.v_tv_r(v_tv_r) + ,.addr_tv_r(addr_tv_r) + ,.lr_miss_tv(1'b0) + ,.sc_op_tv_r(1'b0) + ,.sc_success(1'b0) + + ,.cache_req_v_o(cache_req_v_o) + ,.cache_req_o(cache_req_o) + + ,.cache_req_metadata_o(cache_req_metadata_o) + ,.cache_req_metadata_v_o(cache_req_metadata_v_o) + + ,.cache_req_complete_i(cache_req_complete_i) + + ,.v_o(data_v_o) + ,.load_data(dword_width_p'(data_o)) + ,.cache_miss_o(miss_o) + ,.wt_req() + ,.store_data(dword_width_p'(0)) + + ,.data_mem_pkt_v_i(data_mem_pkt_v_i) + ,.data_mem_pkt_i(data_mem_pkt_i) + ,.data_mem_pkt_yumi_o(data_mem_pkt_yumi_o) + + ,.tag_mem_pkt_v_i(tag_mem_pkt_v_i) + ,.tag_mem_pkt_i(tag_mem_pkt_i) + ,.tag_mem_pkt_yumi_o(tag_mem_pkt_yumi_o) + + ,.stat_mem_pkt_v_i(stat_mem_pkt_v_i) + ,.stat_mem_pkt_i(stat_mem_pkt_i) + ,.stat_mem_pkt_yumi_o(stat_mem_pkt_yumi_o) + ); +*/ +/* bind bp_core_minimal + bp_be_nonsynth_vm_tracer + #(.bp_params_p(bp_params_p)) + vm_tracer + (.clk_i(clk_i & (ExampleBlackParrotSystem.vm_trace_p == 1)) + ,.reset_i(reset_i) + ,.freeze_i(be.be_checker.scheduler.int_regfile.cfg_bus.freeze) + + ,.mhartid_i(be.be_checker.scheduler.int_regfile.cfg_bus.core_id) + + ,.itlb_clear_i(fe.mem.itlb.flush_i) + ,.itlb_fill_v_i(fe.mem.itlb.v_i & fe.mem.itlb.w_i) + ,.itlb_vtag_i(fe.mem.itlb.vtag_i) + ,.itlb_entry_i(fe.mem.itlb.entry_i) + + ,.dtlb_clear_i(be.be_mem.dtlb.flush_i) + ,.dtlb_fill_v_i(be.be_mem.dtlb.v_i & be.be_mem.dtlb.w_i) + ,.dtlb_vtag_i(be.be_mem.dtlb.vtag_i) + ,.dtlb_entry_i(be.be_mem.dtlb.entry_i) + ); +*/ +/* bp_mem_nonsynth_tracer + #(.bp_params_p(bp_params_p)) + bp_mem_tracer + (.clk_i(clk_i & (ExampleBlackParrotSystem.dram_trace_p == 1)) + ,.reset_i(reset_i) + + ,.mem_cmd_i(proc_mem_cmd_lo) + ,.mem_cmd_v_i(proc_mem_cmd_v_lo & proc_mem_cmd_ready_li) + ,.mem_cmd_ready_i(proc_mem_cmd_ready_li) + + ,.mem_resp_i(proc_mem_resp_li) + ,.mem_resp_v_i(proc_mem_resp_v_li) + ,.mem_resp_yumi_i(proc_mem_resp_yumi_lo) + ); +*/ +/* bind bp_core_minimal + bp_nonsynth_core_profiler + #(.bp_params_p(bp_params_p)) + core_profiler + (.clk_i(clk_i & (ExampleBlackParrotSystem.core_profile_p == 1)) + ,.reset_i(reset_i) + ,.freeze_i(be.be_checker.scheduler.int_regfile.cfg_bus.freeze) + + ,.mhartid_i(be.be_checker.scheduler.int_regfile.cfg_bus.core_id) + + ,.fe_wait_stall(fe.pc_gen.is_wait) + ,.fe_queue_stall(~fe.pc_gen.fe_queue_ready_i) + + ,.itlb_miss(fe.mem.itlb_miss_r) + ,.icache_miss(~fe.mem.icache.vaddr_ready_o | fe.pc_gen.icache_miss) + ,.icache_fence(fe.mem.icache.fencei_req) + ,.branch_override(fe.pc_gen.ovr_taken & ~fe.pc_gen.ovr_ret) + ,.ret_override(fe.pc_gen.ovr_ret) + + ,.fe_cmd(fe.pc_gen.fe_cmd_yumi_o & ~fe.pc_gen.attaboy_v) + + ,.mispredict(be.be_checker.director.npc_mismatch_v) + ,.target(be.be_checker.director.isd_status.isd_pc) + + ,.dtlb_miss(be.be_mem.dtlb_miss_r) + ,.dcache_miss(~be.be_mem.dcache.ready_o) + ,.long_haz(be.be_checker.detector.long_haz_v) + ,.exception(be.be_checker.director.trap_pkt.exception) + ,.eret(be.be_checker.director.trap_pkt.eret) + ,._interrupt(be.be_checker.director.trap_pkt._interrupt) + ,.control_haz(be.be_checker.detector.control_haz_v) + ,.data_haz(be.be_checker.detector.data_haz_v) + ,.load_dep((be.be_checker.detector.dep_status_li[0].mem_iwb_v + | be.be_checker.detector.dep_status_li[1].mem_iwb_v + ) & be.be_checker.detector.data_haz_v + ) + ,.mul_dep((be.be_checker.detector.dep_status_li[0].mul_iwb_v + | be.be_checker.detector.dep_status_li[1].mul_iwb_v + | be.be_checker.detector.dep_status_li[2].mul_iwb_v + ) & be.be_checker.detector.data_haz_v + ) + ,.struct_haz(be.be_checker.detector.struct_haz_v) + + ,.reservation(be.be_calculator.reservation_n) + ,.commit_pkt(be.be_calculator.commit_pkt) + ,.trap_pkt(be.be_mem.csr.trap_pkt_o) + ); +*/ +/* bind bp_core_minimal + bp_nonsynth_pc_profiler + #(.bp_params_p(bp_params_p)) + pc_profiler + (.clk_i(clk_i & (ExampleBlackParrotSystem.core_profile_p == 1)) + ,.reset_i(reset_i) + ,.freeze_i(be.be_checker.scheduler.int_regfile.cfg_bus.freeze) + + ,.mhartid_i(be.be_checker.scheduler.int_regfile.cfg_bus.core_id) + + ,.commit_pkt(be.be_calculator.commit_pkt) + + ,.program_finish_i(ExampleBlackParrotSystem.program_finish_lo) + ); +*/ +/* bind bp_be_director + bp_nonsynth_branch_profiler + #(.bp_params_p(bp_params_p)) + pc_profiler + (.clk_i(clk_i & (ExampleBlackParrotSystem.core_profile_p == 1)) + ,.reset_i(reset_i) + ,.freeze_i(cfg_bus_cast_i.freeze) + + ,.mhartid_i(cfg_bus_cast_i.core_id) + + ,.fe_cmd_o(fe_cmd_o) + ,.fe_cmd_v_o(fe_cmd_v_o) + ,.fe_cmd_ready_i(fe_cmd_ready_i) + + ,.commit_v_i(commit_pkt.instret) + + ,.program_finish_i(ExampleBlackParrotSystem.program_finish_lo) + ); +*/ +/* bp_nonsynth_if_verif + #(.bp_params_p(bp_params_p)) + if_verif + (); +*/ + endmodule + diff --git a/litex/soc/cores/cpu/blackparrot/bp_litex/simulation/ExampleBlackParrotSystem.v b/litex/soc/cores/cpu/blackparrot/bp_litex/simulation/ExampleBlackParrotSystem.v new file mode 100644 index 000000000..f2f7718cc --- /dev/null +++ b/litex/soc/cores/cpu/blackparrot/bp_litex/simulation/ExampleBlackParrotSystem.v @@ -0,0 +1,622 @@ +/** + * + * ExampleBlackParrotSystem.v + * + */ + +`include "bsg_noc_links.vh" + +module ExampleBlackParrotSystem + import bp_common_pkg::*; + import bp_common_aviary_pkg::*; + import bp_be_pkg::*; + import bp_common_rv64_pkg::*; + import bp_cce_pkg::*; + import bp_me_pkg::*; + import bp_common_cfg_link_pkg::*; + import bsg_noc_pkg::*; + #(parameter bp_params_e bp_params_p = e_bp_softcore_no_l2_cfg// e_bp_softcore_cfg + `declare_bp_proc_params(bp_params_p) + `declare_bp_fe_be_if_widths(vaddr_width_p, paddr_width_p, asid_width_p, branch_metadata_fwd_width_p) + `declare_bp_me_if_widths(paddr_width_p, cce_block_width_p, lce_id_width_p, lce_assoc_p) + + // Tracing parameters + , parameter calc_trace_p = 0 + , parameter cce_trace_p = 0 + , parameter cmt_trace_p = 1 + , parameter dram_trace_p = 1 + , parameter npc_trace_p = 0 + , parameter icache_trace_p = 0 + , parameter dcache_trace_p = 0 + , parameter vm_trace_p = 0 + , parameter core_profile_p = 0 + , parameter preload_mem_p = 0 + , parameter load_nbf_p = 0 + , parameter skip_init_p = 0 + , parameter cosim_p = 0 + , parameter cosim_cfg_file_p = "prog.cfg" + , parameter cosim_instr_p = 0 + , parameter warmup_instr_p = 0 + , parameter mem_zero_p = 1 + , parameter mem_file_p = "prog.mem" + , parameter mem_cap_in_bytes_p = 2**28 + , parameter [paddr_width_p-1:0] mem_offset_p = dram_base_addr_gp + + // Number of elements in the fake BlackParrot memory + /*, parameter use_max_latency_p = 0 + , parameter use_random_latency_p = 0 + , parameter use_dramsim2_latency_p = 0 + + , parameter max_latency_p = 15 + + , parameter dram_clock_period_in_ps_p = `BP_SIM_CLK_PERIOD + , parameter dram_cfg_p = "dram_ch.ini" + , parameter dram_sys_cfg_p = "dram_sys.ini" + , parameter dram_capacity_p = 16384 + */ + ) + (input clk_i + , input reset_i + //Wishbone interface + , input [63:0] wbm_dat_i + , output [63:0] wbm_dat_o + , input wbm_ack_i + , input wbm_err_i +// , input wbm_rty_i + , output [36:0] wbm_adr_o //TODO parametrize this + , output wbm_stb_o + , output wbm_cyc_o + , output [7:0] wbm_sel_o + , output wbm_we_o + , output [2:0] wbm_cti_o //TODO: + , output [1:0] wbm_bte_o +// , input [3:0] interrupts + ); + +`declare_bp_me_if(paddr_width_p, cce_block_width_p, lce_id_width_p, lce_assoc_p) + +initial begin + if (num_core_p > 1) begin + assert (cosim_p == 0) else $error("cosim_p not supported for num_core_p > 1"); + end +end + +logic [num_core_p-1:0] program_finish_lo; +logic cosim_finish_lo; + +bp_cce_mem_msg_s proc_mem_cmd_lo; +logic proc_mem_cmd_v_lo, proc_mem_cmd_ready_li; +bp_cce_mem_msg_s proc_mem_resp_li; +logic proc_mem_resp_v_li, proc_mem_resp_yumi_lo; + +bp_cce_mem_msg_s proc_io_cmd_lo; +logic proc_io_cmd_v_lo, proc_io_cmd_ready_li; +bp_cce_mem_msg_s proc_io_resp_li; +logic proc_io_resp_v_li, proc_io_resp_yumi_lo; + +bp_cce_mem_msg_s io_cmd_lo; +logic io_cmd_v_lo, io_cmd_ready_li; +bp_cce_mem_msg_s io_resp_li; +logic io_resp_v_li, io_resp_yumi_lo; + +bp_cce_mem_msg_s nbf_cmd_lo; +logic nbf_cmd_v_lo, nbf_cmd_yumi_li; +bp_cce_mem_msg_s nbf_resp_li; +logic nbf_resp_v_li, nbf_resp_ready_lo; + +bp_cce_mem_msg_s cfg_cmd_lo; +logic cfg_cmd_v_lo, cfg_cmd_yumi_li; +bp_cce_mem_msg_s cfg_resp_li; +logic cfg_resp_v_li, cfg_resp_ready_lo; + +bp_cce_mem_msg_s load_cmd_lo; +logic load_cmd_v_lo, load_cmd_yumi_li; +bp_cce_mem_msg_s load_resp_li; +logic load_resp_v_li, load_resp_ready_lo; + +bp_softcore +#(.bp_params_p(bp_params_p)) + softcore + (.clk_i(clk_i) + ,.reset_i(reset_i) + + ,.io_cmd_o(proc_io_cmd_lo) + ,.io_cmd_v_o(proc_io_cmd_v_lo) + ,.io_cmd_ready_i(proc_io_cmd_ready_li) + + ,.io_resp_i(proc_io_resp_li) + ,.io_resp_v_i(proc_io_resp_v_li) + ,.io_resp_yumi_o(proc_io_resp_yumi_lo) + + ,.io_cmd_i(load_cmd_lo) + ,.io_cmd_v_i(load_cmd_v_lo) + ,.io_cmd_yumi_o(load_cmd_yumi_li) + + ,.io_resp_o(load_resp_li) + ,.io_resp_v_o(load_resp_v_li) + ,.io_resp_ready_i(load_resp_ready_lo) + + ,.mem_cmd_o(proc_mem_cmd_lo) + ,.mem_cmd_v_o(proc_mem_cmd_v_lo) + ,.mem_cmd_ready_i(proc_mem_cmd_ready_li) + + ,.mem_resp_i(proc_mem_resp_li) + ,.mem_resp_v_i(proc_mem_resp_v_li) + ,.mem_resp_yumi_o(proc_mem_resp_yumi_lo) + ); + + bp2wb_convertor + #(.bp_params_p(bp_params_p)) + bp2wb + (.clk_i(clk_i) + ,.reset_i(reset_i) + ,.mem_cmd_i(proc_mem_cmd_lo) + ,.mem_cmd_v_i(proc_mem_cmd_ready_li & proc_mem_cmd_v_lo) + ,.mem_cmd_ready_o(proc_mem_cmd_ready_li) + + ,.mem_resp_o(proc_mem_resp_li) + ,.mem_resp_v_o(proc_mem_resp_v_li) + ,.mem_resp_yumi_i(proc_mem_resp_yumi_lo) + ,.dat_i(wbm_dat_i) + ,.dat_o(wbm_dat_o) + ,.ack_i(wbm_ack_i) + ,.adr_o(wbm_adr_o) + ,.stb_o(wbm_stb_o) + ,.cyc_o(wbm_cyc_o) + ,.sel_o(wbm_sel_o ) + ,.we_o(wbm_we_o) + ,.cti_o(wbm_cti_o) + ,.bte_o(wbm_bte_o ) + // ,.rty_i(wbm_rty_i) + ,.err_i(wbm_err_i) + ); + + +assign proc_io_cmd_ready_li = 1;//TODO: make sure this is necessary + +logic nbf_done_lo, cfg_done_lo; +if (load_nbf_p) + begin : nbf + bp_nonsynth_nbf_loader + #(.bp_params_p(bp_params_p)) + nbf_loader + (.clk_i(clk_i) + ,.reset_i(reset_i | ~cfg_done_lo) + + ,.lce_id_i(lce_id_width_p'('b10)) + + ,.io_cmd_o(nbf_cmd_lo) + ,.io_cmd_v_o(nbf_cmd_v_lo) + ,.io_cmd_yumi_i(nbf_cmd_yumi_li) + + ,.io_resp_i(nbf_resp_li) + ,.io_resp_v_i(nbf_resp_v_li) + ,.io_resp_ready_o(nbf_resp_ready_lo) + + ,.done_o(nbf_done_lo) + ); + end +else + begin : no_nbf + assign nbf_resp_ready_lo = 1'b1; + assign nbf_cmd_v_lo = '0; + assign nbf_cmd_lo = '0; + + assign nbf_done_lo = 1'b1; + end + +localparam cce_instr_ram_addr_width_lp = `BSG_SAFE_CLOG2(num_cce_instr_ram_els_p); +bp_cce_mmio_cfg_loader + #(.bp_params_p(bp_params_p) + ,.inst_width_p($bits(bp_cce_inst_s)) + ,.inst_ram_addr_width_p(cce_instr_ram_addr_width_lp) + ,.inst_ram_els_p(num_cce_instr_ram_els_p) + ,.skip_ram_init_p(skip_init_p) + ,.clear_freeze_p(!load_nbf_p) + ,.cce_ucode_filename_p("/tmp/cce_ucode.mem") + ) + cfg_loader + (.clk_i(clk_i) + ,.reset_i(reset_i) + + ,.lce_id_i(lce_id_width_p'('b10)) + + ,.io_cmd_o(cfg_cmd_lo) + ,.io_cmd_v_o(cfg_cmd_v_lo) + ,.io_cmd_yumi_i(cfg_cmd_yumi_li) + + ,.io_resp_i(cfg_resp_li) + ,.io_resp_v_i(cfg_resp_v_li) + ,.io_resp_ready_o(cfg_resp_ready_lo) + + ,.done_o(cfg_done_lo) + ); + +// CFG and NBF are mutex, so we can just use fixed arbitration here +always_comb + if (~cfg_done_lo) + begin + load_cmd_lo = cfg_cmd_lo; + load_cmd_v_lo = cfg_cmd_v_lo; + + nbf_cmd_yumi_li = '0; + cfg_cmd_yumi_li = load_cmd_yumi_li; + + load_resp_ready_lo = cfg_resp_ready_lo; + + nbf_resp_li = '0; + nbf_resp_v_li = '0; + + cfg_resp_li = load_resp_li; + cfg_resp_v_li = load_resp_v_li; + end + else + begin + load_cmd_lo = nbf_cmd_lo; + load_cmd_v_lo = nbf_cmd_v_lo; + + nbf_cmd_yumi_li = load_cmd_yumi_li; + cfg_cmd_yumi_li = '0; + + load_resp_ready_lo = nbf_resp_ready_lo; + + nbf_resp_li = load_resp_li; + nbf_resp_v_li = load_resp_v_li; + + cfg_resp_li = '0; + cfg_resp_v_li = '0; + end + +/*bp_nonsynth_host + #(.bp_params_p(bp_params_p)) + host + (.clk_i(clk_i) + ,.reset_i(reset_i) + + ,.io_cmd_i(proc_io_cmd_lo) + ,.io_cmd_v_i(proc_io_cmd_v_lo & proc_io_cmd_ready_li) + ,.io_cmd_ready_o(proc_io_cmd_ready_li) + + ,.io_resp_o(proc_io_resp_li) + ,.io_resp_v_o(proc_io_resp_v_li) + ,.io_resp_yumi_i(proc_io_resp_yumi_lo) + + ,.program_finish_o(program_finish_lo) + ); +*/ +bind bp_be_top + bp_nonsynth_commit_tracer + #(.bp_params_p(bp_params_p)) + commit_tracer + (.clk_i(clk_i & (ExampleBlackParrotSystem.cmt_trace_p == 1)) + ,.reset_i(reset_i) + ,.freeze_i(be_checker.scheduler.int_regfile.cfg_bus.freeze) + + ,.mhartid_i('0) + + ,.decode_i(be_calculator.reservation_n.decode) + + ,.commit_v_i(be_calculator.commit_pkt.instret) + ,.commit_pc_i(be_calculator.commit_pkt.pc) + ,.commit_instr_i(be_calculator.commit_pkt.instr) + + ,.rd_w_v_i(be_checker.scheduler.wb_pkt.rd_w_v) + ,.rd_addr_i(be_checker.scheduler.wb_pkt.rd_addr) + ,.rd_data_i(be_checker.scheduler.wb_pkt.rd_data) + ); + +/* if (num_core_p == 1) + begin : cosim + bind bp_be_top + bp_nonsynth_cosim + #(.bp_params_p(bp_params_p)) + cosim + (.clk_i(clk_i) + ,.reset_i(reset_i) + ,.freeze_i(be_checker.scheduler.int_regfile.cfg_bus.freeze) + ,.en_i(ExampleBlackParrotSystem.cosim_p == 1) + ,.cosim_instr_i(ExampleBlackParrotSystem.cosim_instr_p) + + ,.mhartid_i(be_checker.scheduler.int_regfile.cfg_bus.core_id) + // Want to pass config file as a parameter, but cannot in Verilator 4.025 + // Parameter-resolved constants must not use dotted references + ,.config_file_i(ExampleBlackParrotSystem.cosim_cfg_file_p) + + ,.decode_i(be_calculator.reservation_n.decode) + + ,.commit_v_i(be_calculator.commit_pkt.instret) + ,.commit_pc_i(be_calculator.commit_pkt.pc) + ,.commit_instr_i(be_calculator.commit_pkt.instr) + + ,.rd_w_v_i(be_checker.scheduler.wb_pkt.rd_w_v) + ,.rd_addr_i(be_checker.scheduler.wb_pkt.rd_addr) + ,.rd_data_i(be_checker.scheduler.wb_pkt.rd_data) + + ,.interrupt_v_i(be_mem.csr.trap_pkt_cast_o._interrupt) + ,.cause_i(be_mem.csr.trap_pkt_cast_o.cause) + + ,.finish_o(ExampleBlackParrotSystem.cosim_finish_lo) + ); + end + else + begin : no_cosim*/ + assign cosim_finish_lo = '0; + // end + +/*bind bp_be_top + bp_be_nonsynth_perf + #(.bp_params_p(bp_params_p)) + perf + (.clk_i(clk_i) + ,.reset_i(reset_i) + ,.freeze_i(be_checker.scheduler.int_regfile.cfg_bus.freeze) + ,.warmup_instr_i(ExampleBlackParrotSystem.warmup_instr_p) + + ,.mhartid_i(be_checker.scheduler.int_regfile.cfg_bus.core_id) + + ,.commit_v_i(be_calculator.commit_pkt.instret) + + ,.program_finish_i(ExampleBlackParrotSystem.program_finish_lo | ExampleBlackParrotSystem.cosim_finish_lo) + ); +*/ +/* bind bp_be_top + bp_nonsynth_watchdog + #(.bp_params_p(bp_params_p) + ,.timeout_cycles_p(100000) + ,.heartbeat_instr_p(100000) + ) + watchdog + (.clk_i(clk_i) + ,.reset_i(reset_i) + ,.freeze_i(be_checker.scheduler.int_regfile.cfg_bus.freeze) + + ,.mhartid_i(be_checker.scheduler.int_regfile.cfg_bus.core_id) + + ,.npc_i(be_checker.director.npc_r) + ,.instret_i(be_calculator.commit_pkt.instret) + ); +*/ +/* bind bp_be_director + bp_be_nonsynth_npc_tracer + #(.bp_params_p(bp_params_p)) + npc_tracer + (.clk_i(clk_i & (ExampleBlackParrotSystem.npc_trace_p == 1)) + ,.reset_i(reset_i) + ,.freeze_i(be_checker.scheduler.int_regfile.cfg_bus.freeze) + + ,.mhartid_i(be_checker.scheduler.int_regfile.cfg_bus.core_id) + + ,.npc_w_v(npc_w_v) + ,.npc_n(npc_n) + ,.npc_r(npc_r) + ,.expected_npc_o(expected_npc_o) + + ,.fe_cmd_i(fe_cmd) + ,.fe_cmd_v(fe_cmd_v) + + ,.commit_pkt_i(commit_pkt) + ); +*/ +/* bind bp_be_dcache + bp_nonsynth_cache_tracer + #(.bp_params_p(bp_params_p) + ,.assoc_p(dcache_assoc_p) + ,.sets_p(dcache_sets_p) + ,.block_width_p(dcache_block_width_p) + ,.trace_file_p("dcache")) + dcache_tracer + (.clk_i(clk_i & (ExampleBlackParrotSystem.dcache_trace_p == 1)) + ,.reset_i(reset_i) + ,.freeze_i(cfg_bus_cast_i.freeze) + + ,.mhartid_i(cfg_bus_cast_i.core_id) + + ,.v_tl_r(v_tl_r) + + ,.v_tv_r(v_tv_r) + ,.addr_tv_r(paddr_tv_r) + ,.lr_miss_tv(lr_miss_tv) + ,.sc_op_tv_r(sc_op_tv_r) + ,.sc_success(sc_success) + + ,.cache_req_v_o(cache_req_v_o) + ,.cache_req_o(cache_req_o) + + ,.cache_req_metadata_o(cache_req_metadata_o) + ,.cache_req_metadata_v_o(cache_req_metadata_v_o) + + ,.cache_req_complete_i(cache_req_complete_i) + + ,.v_o(v_o) + ,.load_data(data_o) + ,.cache_miss_o(dcache_miss_o) + ,.wt_req(wt_req) + ,.store_data(data_tv_r) + + ,.data_mem_pkt_v_i(data_mem_pkt_v_i) + ,.data_mem_pkt_i(data_mem_pkt_i) + ,.data_mem_pkt_yumi_o(data_mem_pkt_yumi_o) + + ,.tag_mem_pkt_v_i(tag_mem_pkt_v_i) + ,.tag_mem_pkt_i(tag_mem_pkt_i) + ,.tag_mem_pkt_yumi_o(tag_mem_pkt_yumi_o) + + ,.stat_mem_pkt_v_i(stat_mem_pkt_v_i) + ,.stat_mem_pkt_i(stat_mem_pkt_i) + ,.stat_mem_pkt_yumi_o(stat_mem_pkt_yumi_o) + ); +*/ +/* bind bp_fe_icache + bp_nonsynth_cache_tracer + #(.bp_params_p(bp_params_p) + ,.assoc_p(icache_assoc_p) + ,.sets_p(icache_sets_p) + ,.block_width_p(icache_block_width_p) + ,.trace_file_p("icache")) + icache_tracer + (.clk_i(clk_i & (ExampleBlackParrotSystem.icache_trace_p == 1)) + ,.reset_i(reset_i) + + ,.freeze_i(cfg_bus_cast_i.freeze) + ,.mhartid_i(cfg_bus_cast_i.core_id) + + ,.v_tl_r(v_tl_r) + + ,.v_tv_r(v_tv_r) + ,.addr_tv_r(addr_tv_r) + ,.lr_miss_tv(1'b0) + ,.sc_op_tv_r(1'b0) + ,.sc_success(1'b0) + + ,.cache_req_v_o(cache_req_v_o) + ,.cache_req_o(cache_req_o) + + ,.cache_req_metadata_o(cache_req_metadata_o) + ,.cache_req_metadata_v_o(cache_req_metadata_v_o) + + ,.cache_req_complete_i(cache_req_complete_i) + + ,.v_o(data_v_o) + ,.load_data(dword_width_p'(data_o)) + ,.cache_miss_o(miss_o) + ,.wt_req() + ,.store_data(dword_width_p'(0)) + + ,.data_mem_pkt_v_i(data_mem_pkt_v_i) + ,.data_mem_pkt_i(data_mem_pkt_i) + ,.data_mem_pkt_yumi_o(data_mem_pkt_yumi_o) + + ,.tag_mem_pkt_v_i(tag_mem_pkt_v_i) + ,.tag_mem_pkt_i(tag_mem_pkt_i) + ,.tag_mem_pkt_yumi_o(tag_mem_pkt_yumi_o) + + ,.stat_mem_pkt_v_i(stat_mem_pkt_v_i) + ,.stat_mem_pkt_i(stat_mem_pkt_i) + ,.stat_mem_pkt_yumi_o(stat_mem_pkt_yumi_o) + ); +*/ +/* bind bp_core_minimal + bp_be_nonsynth_vm_tracer + #(.bp_params_p(bp_params_p)) + vm_tracer + (.clk_i(clk_i & (ExampleBlackParrotSystem.vm_trace_p == 1)) + ,.reset_i(reset_i) + ,.freeze_i(be.be_checker.scheduler.int_regfile.cfg_bus.freeze) + + ,.mhartid_i(be.be_checker.scheduler.int_regfile.cfg_bus.core_id) + + ,.itlb_clear_i(fe.mem.itlb.flush_i) + ,.itlb_fill_v_i(fe.mem.itlb.v_i & fe.mem.itlb.w_i) + ,.itlb_vtag_i(fe.mem.itlb.vtag_i) + ,.itlb_entry_i(fe.mem.itlb.entry_i) + + ,.dtlb_clear_i(be.be_mem.dtlb.flush_i) + ,.dtlb_fill_v_i(be.be_mem.dtlb.v_i & be.be_mem.dtlb.w_i) + ,.dtlb_vtag_i(be.be_mem.dtlb.vtag_i) + ,.dtlb_entry_i(be.be_mem.dtlb.entry_i) + ); +*/ + bp_mem_nonsynth_tracer + #(.bp_params_p(bp_params_p)) + bp_mem_tracer + (.clk_i(clk_i & (ExampleBlackParrotSystem.dram_trace_p == 1)) + ,.reset_i(reset_i) + + ,.mem_cmd_i(proc_mem_cmd_lo) + ,.mem_cmd_v_i(proc_mem_cmd_v_lo & proc_mem_cmd_ready_li) + ,.mem_cmd_ready_i(proc_mem_cmd_ready_li) + + ,.mem_resp_i(proc_mem_resp_li) + ,.mem_resp_v_i(proc_mem_resp_v_li) + ,.mem_resp_yumi_i(proc_mem_resp_yumi_lo) + ); + +/* bind bp_core_minimal + bp_nonsynth_core_profiler + #(.bp_params_p(bp_params_p)) + core_profiler + (.clk_i(clk_i & (ExampleBlackParrotSystem.core_profile_p == 1)) + ,.reset_i(reset_i) + ,.freeze_i(be.be_checker.scheduler.int_regfile.cfg_bus.freeze) + + ,.mhartid_i(be.be_checker.scheduler.int_regfile.cfg_bus.core_id) + + ,.fe_wait_stall(fe.pc_gen.is_wait) + ,.fe_queue_stall(~fe.pc_gen.fe_queue_ready_i) + + ,.itlb_miss(fe.mem.itlb_miss_r) + ,.icache_miss(~fe.mem.icache.vaddr_ready_o | fe.pc_gen.icache_miss) + ,.icache_fence(fe.mem.icache.fencei_req) + ,.branch_override(fe.pc_gen.ovr_taken & ~fe.pc_gen.ovr_ret) + ,.ret_override(fe.pc_gen.ovr_ret) + + ,.fe_cmd(fe.pc_gen.fe_cmd_yumi_o & ~fe.pc_gen.attaboy_v) + + ,.mispredict(be.be_checker.director.npc_mismatch_v) + ,.target(be.be_checker.director.isd_status.isd_pc) + + ,.dtlb_miss(be.be_mem.dtlb_miss_r) + ,.dcache_miss(~be.be_mem.dcache.ready_o) + ,.long_haz(be.be_checker.detector.long_haz_v) + ,.exception(be.be_checker.director.trap_pkt.exception) + ,.eret(be.be_checker.director.trap_pkt.eret) + ,._interrupt(be.be_checker.director.trap_pkt._interrupt) + ,.control_haz(be.be_checker.detector.control_haz_v) + ,.data_haz(be.be_checker.detector.data_haz_v) + ,.load_dep((be.be_checker.detector.dep_status_li[0].mem_iwb_v + | be.be_checker.detector.dep_status_li[1].mem_iwb_v + ) & be.be_checker.detector.data_haz_v + ) + ,.mul_dep((be.be_checker.detector.dep_status_li[0].mul_iwb_v + | be.be_checker.detector.dep_status_li[1].mul_iwb_v + | be.be_checker.detector.dep_status_li[2].mul_iwb_v + ) & be.be_checker.detector.data_haz_v + ) + ,.struct_haz(be.be_checker.detector.struct_haz_v) + + ,.reservation(be.be_calculator.reservation_n) + ,.commit_pkt(be.be_calculator.commit_pkt) + ,.trap_pkt(be.be_mem.csr.trap_pkt_o) + ); +*/ +/* bind bp_core_minimal + bp_nonsynth_pc_profiler + #(.bp_params_p(bp_params_p)) + pc_profiler + (.clk_i(clk_i & (ExampleBlackParrotSystem.core_profile_p == 1)) + ,.reset_i(reset_i) + ,.freeze_i(be.be_checker.scheduler.int_regfile.cfg_bus.freeze) + + ,.mhartid_i(be.be_checker.scheduler.int_regfile.cfg_bus.core_id) + + ,.commit_pkt(be.be_calculator.commit_pkt) + + ,.program_finish_i(ExampleBlackParrotSystem.program_finish_lo) + ); +*/ +/* bind bp_be_director + bp_nonsynth_branch_profiler + #(.bp_params_p(bp_params_p)) + pc_profiler + (.clk_i(clk_i & (ExampleBlackParrotSystem.core_profile_p == 1)) + ,.reset_i(reset_i) + ,.freeze_i(cfg_bus_cast_i.freeze) + + ,.mhartid_i(cfg_bus_cast_i.core_id) + + ,.fe_cmd_o(fe_cmd_o) + ,.fe_cmd_v_o(fe_cmd_v_o) + ,.fe_cmd_ready_i(fe_cmd_ready_i) + + ,.commit_v_i(commit_pkt.instret) + + ,.program_finish_i(ExampleBlackParrotSystem.program_finish_lo) + ); +*/ +/* bp_nonsynth_if_verif + #(.bp_params_p(bp_params_p)) + if_verif + (); +*/ + endmodule + diff --git a/litex/soc/cores/cpu/blackparrot/core.py b/litex/soc/cores/cpu/blackparrot/core.py index b062633ed..d296b612d 100644 --- a/litex/soc/cores/cpu/blackparrot/core.py +++ b/litex/soc/cores/cpu/blackparrot/core.py @@ -42,7 +42,7 @@ CPU_VARIANTS = { } GCC_FLAGS = { - "standard": "-march=rv64ia -mabi=lp64 -O0 ", + "standard": "-march=rv64ima -mabi=lp64 ", } class BlackParrotRV64(CPU): @@ -125,9 +125,9 @@ class BlackParrotRV64(CPU): @staticmethod def add_sources(platform, variant="standard"): - vdir = get_data_mod("cpu", "blackparrot").data_location + vdir = os.path.abspath(os.path.dirname(__file__)) bp_litex_dir = os.path.join(vdir,"bp_litex") - simulation = 0 + simulation = 1 if (simulation == 1): filename= os.path.join(bp_litex_dir,"flist.verilator") else: diff --git a/litex/soc/cores/cpu/blackparrot/setEnvironment.sh b/litex/soc/cores/cpu/blackparrot/setEnvironment.sh index 0f6fa1268..97cb13910 100755 --- a/litex/soc/cores/cpu/blackparrot/setEnvironment.sh +++ b/litex/soc/cores/cpu/blackparrot/setEnvironment.sh @@ -2,8 +2,7 @@ ## Set common environment variables export LITEX=$(git rev-parse --show-toplevel) export BP=$LITEX/../pythondata-cpu-blackparrot/pythondata_cpu_blackparrot/system_verilog -export BP_LITEX_DIR=$BP/bp_litex -export LITEX_SOFTWARE_COMPILER_RT=$LITEX/../pythondata-software-compiler_rt +export BP_LITEX_DIR=$LITEX/litex/soc/cores/cpu/blackparrot/bp_litex #TODO: check if BP exists and warn user export BP_COMMON_DIR=$BP/bp_common @@ -15,10 +14,11 @@ export BP_EXTERNAL_DIR=$BP/external export BASEJUMP_STL_DIR=$BP_EXTERNAL_DIR/basejump_stl export LITEX_FPGA_DIR=$BP_LITEX_DIR/fpga export LITEX_SIMU_DIR=$BP_LITEX_DIR/simulation -export BP_LITEX_SOFTWARE=$BP_LITEX_DIR/software -##SOFTWARE CHANGES## - -#for a reason, provided udivmoddi4.c is not functionally correct when used with either BP or Rocket under IA extension. Another version of udivmoddi4.c is a workaround to run BIOS on these architectures. -cp $BP_LITEX_SOFTWARE/udivmoddi4.c $LITEX_SOFTWARE_COMPILER_RT/pythondata_software_compiler_rt/data/lib/builtins/. +##Minor changes in some of the BP files for memory management +sed -i "s/localparam dram_base_addr_gp = 40'h00_8000_0000;/localparam dram_base_addr_gp = 40'h00_7000_0000;/" $BP_COMMON_DIR/src/include/bp_common_pkg.vh +sed -i "s/localparam bp_pc_entry_point_gp=39'h00_8000_0000/localparam bp_pc_entry_point_gp=39'h00_7000_0000/" $BP_ME_DIR/test/common/bp_cce_mmio_cfg_loader.v +sed -i "s/wire local_cmd_li = (cmd_fifo_selected_lo.header.addr < dram_base_addr_gp);/wire local_cmd_li = (cmd_fifo_selected_lo.header.addr < 32'h5000_0000);/" $BP_TOP_DIR/src/v/bp_softcore.v +## Copy config loader to /tmp +cp $BP_LITEX_DIR/cce_ucode.mem /tmp/. diff --git a/litex/soc/software/bios/Makefile b/litex/soc/software/bios/Makefile index 778757da7..704d0a1d8 100755 --- a/litex/soc/software/bios/Makefile +++ b/litex/soc/software/bios/Makefile @@ -1,10 +1,10 @@ include ../include/generated/variables.mak include $(SOC_DIRECTORY)/software/common.mak -ifeq ($(CPU),blackparrot) -BP_LIBS = -L$(BP_LITEX_SOFTWARE) -BP_FLAGS = -lgcc -endif +#ifeq ($(CPU),blackparrot) +#BP_LIBS = -L$(BP_LITEX_SOFTWARE) +#BP_FLAGS = -lgcc +#endif # Permit TFTP_SERVER_PORT override from shell environment / command line ifdef TFTP_SERVER_PORT CFLAGS += -DTFTP_SERVER_PORT=$(TFTP_SERVER_PORT)