Version 1.6

This commit is contained in:
Joseph Rahmeh 2020-05-15 11:28:59 -07:00
parent 21fe37b5e2
commit 6b1e5ded3a
17 changed files with 630 additions and 218 deletions

View File

@ -1,6 +1,6 @@
# EH1 SweRV RISC-V Core<sup>TM</sup> 1.5 from Western Digital
# EH1 SweRV RISC-V Core<sup>TM</sup> 1.6 from Western Digital
This repository contains the SweRV EH1.5 Core<sup>TM</sup> design RTL
This repository contains the SweRV EH1 ver 1.6 Core<sup>TM</sup> design RTL
## License
@ -191,7 +191,8 @@ cmark_iccm - the same as above, but with code preloaded to iccm - runs on
The `$RV_ROOT/testbench/hex` directory contains precompiled hex files of the tests, ready for simulation in case RISCV SW tools are not installed.
**Building an FPGA speed optimized model:**
Use ``-fpga_optimize=1`` option to ``swerv.config`` to build a model that is removes clock gating logic from flop model so that the FPGA builds can run a higher speeds.
----
Western Digital, the Western Digital logo, G-Technology, SanDisk, Tegile, Upthere, WD, SweRV Core, SweRV ISS,

View File

@ -67,6 +67,8 @@ my $no_prefix = 'RV|TOP|^tec|regwidth|clock_period|assert_on|^datawidth|^physica
my $vlog_use__wh = 1;
my %regions_used = ();
# Cmd Line options#{{{
our %sets;
our %unsets;
@ -388,7 +390,7 @@ our %csr = (#{{{
"mie" => {
"reset" => "0x0",
# Only external, timer, local, and software writeable
"mask" => "0x40000888",
"mask" => "0x70000888",
"exists" => "true",
},
"mip" => {
@ -397,7 +399,7 @@ our %csr = (#{{{
"mask" => "0x0",
# Bits corresponding to error overflow, external, timer and stoftware
# interrupts are modifiable
"poke_mask" => "0x40000888",
"poke_mask" => "0x70000888",
"exists" => "true",
},
"mvendorid" => {
@ -411,7 +413,7 @@ our %csr = (#{{{
"exists" => "true",
},
"mimpid" => {
"reset" => "0x2",
"reset" => "0x3",
"mask" => "0x0",
"exists" => "true",
},
@ -525,6 +527,42 @@ our %csr = (#{{{
"mask" => "0x0",
"exists" => "true",
},
"mitcnt0" => {
"number" => "0x7d2",
"reset" => "0x0",
"mask" => "0xffffffff",
"exists" => "true",
},
"mitbnd0" => {
"number" => "0x7d3",
"reset" => "0xffffffff",
"mask" => "0xffffffff",
"exists" => "true",
},
"mitctl0" => {
"number" => "0x7d4",
"reset" => "0x1",
"mask" => "0x00000007",
"exists" => "true",
},
"mitcnt1" => {
"number" => "0x7d5",
"reset" => "0x0",
"mask" => "0xffffffff",
"exists" => "true",
},
"mitbnd1" => {
"number" => "0x7d6",
"reset" => "0xffffffff",
"mask" => "0xffffffff",
"exists" => "true",
},
"mitctl1" => {
"number" => "0x7d7",
"reset" => "0x1",
"mask" => "0x00000007",
"exists" => "true",
},
"mcpc" => {
"number" => "0x7c2",
"reset" => "0x0",
@ -846,12 +884,13 @@ our %config = (#{{{
"data_access_addr7" => "0x00000000",
"data_access_mask7" => "0xffffffff",
},
"memmap" => {
"serialio" => 'derived, overridable',
"external_data" => 'derived, overridable',
"external_prog" => 'derived, overridable',
"debug_sb_mem" => 'derived, overridable',
"external_data_1" => 'derived, overridable',
"memmap" => { # Testbench only
"serialio" => 'derived, overridable', # Testbench only
"external_data" => 'derived, overridable', # Testbench only
"external_prog" => 'derived, overridable', # Testbench only
"debug_sb_mem" => 'derived, overridable', # Testbench only
"external_data_1" => 'derived, overridable', # Testbench only
"external_mem_hole" => 'derived, overridable', # Testbench only
# "consoleio" => 'derived', # Part of serial io.
},
"bus" => {
@ -1237,44 +1276,55 @@ $config{iccm}{iccm_data_cell} = "ram_$config{iccm}{iccm_rows}x39";
$config{iccm}{"iccm_num_banks_$config{iccm}{iccm_num_banks}"} = "";
$config{iccm}{"iccm_size_$config{iccm}{iccm_size}"} = "";
# Track used regions
$regions_used{hex($config{iccm}{iccm_region})} = 1;
$regions_used{hex($config{dccm}{dccm_region})} = 1;
$regions_used{hex($config{pic}{pic_region})} = 1;
$regions_used{hex($config{reset_vec})>>28} = 1;
# Find an unused region for serial IO
for ($rgn = 15;$rgn >= 0; $rgn--) {
for (my $rgn = 15;$rgn >= 0; $rgn--) {
if (($rgn != hex($config{iccm}{iccm_region})) &&
($rgn != hex($config{dccm}{dccm_region})) &&
($rgn != (hex($config{pic}{pic_region})))) {
$config{memmap}{serialio} = ($rgn << 28) + (22<<18);
$regions_used{$rgn} = 1;
last;
}
}
$config{memmap}{serialio} = sprintf("0x%08x", $config{memmap}{serialio});
# Find an unused region for external data
for ($rgn = 15;$rgn >= 0; $rgn--) {
for (my $rgn = 15;$rgn >= 0; $rgn--) {
if (($rgn != hex($config{iccm}{iccm_region})) &&
($rgn != hex($config{dccm}{dccm_region})) &&
($rgn != (hex($config{memmap}{serialio})>>28)) &&
($rgn != (hex($config{pic}{pic_region})))) {
$config{memmap}{external_data} = ($rgn << 28) + (22<<18);
$regions_used{$rgn} = 1;
last;
}
}
$config{memmap}{external_data} = sprintf("0x%08x", $config{memmap}{external_data});
#
# Find an unused region for external prog
for ($rgn = 15;$rgn >= 0; $rgn--) {
for (my $rgn = 15;$rgn >= 0; $rgn--) {
if (($rgn != hex($config{iccm}{iccm_region})) &&
($rgn != hex($config{dccm}{dccm_region})) &&
($rgn != (hex($config{memmap}{serialio})>>28)) &&
($rgn != (hex($config{memmap}{external_data})>>28)) &&
($rgn != (hex($config{pic}{pic_region})))) {
$config{memmap}{external_prog} = ($rgn << 28);
$regions_used{$rgn} = 1;
last;
}
}
$config{memmap}{external_prog} = sprintf("0x%08x", $config{memmap}{external_prog});
# Unused region for second data
for ($rgn = 15;$rgn >= 0; $rgn--) {
for (my $rgn = 15;$rgn >= 0; $rgn--) {
if (($rgn != hex($config{iccm}{iccm_region})) &&
($rgn != hex($config{dccm}{dccm_region})) &&
($rgn != (hex($config{memmap}{serialio})>>28)) &&
@ -1283,6 +1333,7 @@ for ($rgn = 15;$rgn >= 0; $rgn--) {
($rgn != (hex($config{pic}{pic_region})))
)) {
$config{memmap}{external_data_1} = ($rgn << 28);
$regions_used{$rgn} = 1;
last;
}
}
@ -1293,19 +1344,103 @@ $config{memmap}{external_data_1} = sprintf("0x%08x", $config{memmap}{data_1});
#$config{memmap}{consoleio} = sprintf("0x%x", $config{memmap}{consoleio});
# Find an unused region for debug_sb_memory data
for ($rgn = 15;$rgn >= 0; $rgn--) {
for (my $rgn = 15;$rgn >= 0; $rgn--) {
if (($rgn != hex($config{iccm}{iccm_region})) &&
($rgn != hex($config{dccm}{dccm_region})) &&
($rgn != (hex($config{memmap}{serialio})>>28)) &&
($rgn != (hex($config{memmap}{external_data})>>28)) &&
($rgn != (hex($config{memmap}{external_data_1})>>28)) &&
($rgn != (hex($config{pic}{pic_region})))) {
$config{memmap}{debug_sb_mem} = ($rgn << 28) + (22<<18);
$regions_used{$rgn} = 1;
last;
}
}
$config{memmap}{debug_sb_mem} = sprintf("0x%08x", $config{memmap}{debug_sb_mem});
# Create the memory map hole for random testing
# Only do this if masks are not enabled already
if (hex($config{protection}{data_access_enable0}) > 0 ||
hex($config{protection}{data_access_enable1}) > 0 ||
hex($config{protection}{data_access_enable2}) > 0 ||
hex($config{protection}{data_access_enable3}) > 0 ||
hex($config{protection}{data_access_enable4}) > 0 ||
hex($config{protection}{data_access_enable5}) > 0 ||
hex($config{protection}{data_access_enable6}) > 0 ||
hex($config{protection}{data_access_enable7}) > 0 ||
hex($config{protection}{inst_access_enable0}) > 0 ||
hex($config{protection}{inst_access_enable1}) > 0 ||
hex($config{protection}{inst_access_enable2}) > 0 ||
hex($config{protection}{inst_access_enable3}) > 0 ||
hex($config{protection}{inst_access_enable4}) > 0 ||
hex($config{protection}{inst_access_enable5}) > 0 ||
hex($config{protection}{inst_access_enable6}) > 0 ||
hex($config{protection}{inst_access_enable7}) > 0) {
delete($config{memmap}{external_mem_hole}) ;
} else {
# Unused region to create a memory map hole
for (my $rgn = 15;$rgn >= 0; $rgn--) {
if (!defined($regions_used{$rgn})) {
$config{memmap}{external_mem_hole} = ($rgn << 28);
$regions_used{$rgn} = 1;
last;
}
}
if ($config{memmap}{external_mem_hole} == 0) {
$config{protection}{data_access_addr0} = "0x10000000";
$config{protection}{data_access_mask0} = "0xffffffff";
$config{protection}{data_access_enable0} = "1";
} elsif (($config{memmap}{external_mem_hole}>>28) == 16) {
$config{protection}{data_access_addr0} = "0x00000000";
$config{protection}{data_access_mask0} = "0xefffffff";
$config{protection}{data_access_enable0} = "1";
} else {
my $hreg = $config{memmap}{external_mem_hole}>>28;
$config{protection}{data_access_addr0} = sprintf("0x%x", (($hreg^8)&8)<<28);
$config{protection}{data_access_mask0} = "0x7fffffff";
$config{protection}{data_access_addr1} = sprintf("0x%x", ($hreg&8) << 28 |(($hreg^4)&4)<<28);
$config{protection}{data_access_mask1} = "0x3fffffff";
$config{protection}{data_access_addr2} = sprintf("0x%x", ($hreg&12) <<28 | (($hreg^2)&2) <<28);
$config{protection}{data_access_mask2} = "0x1fffffff";
$config{protection}{data_access_addr3} = sprintf("0x%x", ($hreg&14) << 28 |(($hreg^1)&1)<<28);
$config{protection}{data_access_mask3} = "0x0fffffff";
$config{protection}{data_access_enable0} = "1";
$config{protection}{data_access_enable1} = "1";
$config{protection}{data_access_enable2} = "1";
$config{protection}{data_access_enable3} = "1";
$config{protection}{inst_access_addr0} = sprintf("0x%x", (($hreg^8)&8)<<28);
$config{protection}{inst_access_mask0} = "0x7fffffff";
$config{protection}{inst_access_addr1} = sprintf("0x%x", ($hreg&8) << 28 |(($hreg^4)&4)<<28);
$config{protection}{inst_access_mask1} = "0x3fffffff";
$config{protection}{inst_access_addr2} = sprintf("0x%x", ($hreg&12) <<28 | (($hreg^2)&2) <<28);
$config{protection}{inst_access_mask2} = "0x1fffffff";
$config{protection}{inst_access_addr3} = sprintf("0x%x", ($hreg&14) << 28 |(($hreg^1)&1)<<28);
$config{protection}{inst_access_mask3} = "0x0fffffff";
$config{protection}{inst_access_enable0} = "1";
$config{protection}{inst_access_enable1} = "1";
$config{protection}{inst_access_enable2} = "1";
$config{protection}{inst_access_enable3} = "1";
}
$config{memmap}{external_mem_hole} = sprintf("0x%08x", $config{memmap}{external_mem_hole});
}
#Define 5 unused regions for used in TG
foreach my $unr (reverse(0 .. 15)) {
if (!defined($regions_used{$unr})) {
$config{memmap}{"unused_region$unr"} = sprintf("0x%08x",($unr << 28));
$regions_used{$unr} = 1;
}
}
if ($target eq "baseline") {
$config{reset_vec} = $config{iccm}{iccm_sadr};
$config{testbench}{magellan} = 1;
print "$self: Setting reset_vec = ICCM start address for Baseline\n";
}
# Output bit-width specifiers for these variables
our %widths = (
"dccm_region" => "4",
@ -1666,7 +1801,7 @@ sub collect_mem_protection {
}
if ($mask !~ /^0x0*[137]?f*$/) {
warn("Protection mask ($mask) must have all its one bits to the right of its zero bits\n");
warn("Protection $tag mask ($mask) must have all its one bits to the right of its zero bits\n");
next;
}

View File

@ -161,6 +161,7 @@ module dbg (
logic dmcontrol_wren, dmcontrol_wren_Q;
// command
logic command_wren;
logic [31:0] command_din;
// needed to send the read data back for dmi reads
logic [31:0] dmi_reg_rdata_din;
@ -357,22 +358,19 @@ module dbg (
assign abstractcs_error_sel2 = core_dbg_cmd_done & core_dbg_cmd_fail;
assign abstractcs_error_sel3 = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h17) & (dbg_state != HALTED);
assign abstractcs_error_sel4 = (dmi_reg_addr == 7'h17) & dmi_reg_en & dmi_reg_wr_en &
( ((dmi_reg_wdata[22:20] == 3'b001) & data1_reg[0]) |
((dmi_reg_wdata[22:20] == 3'b010) & (|data1_reg[1:0])) |
dmi_reg_wdata[22] | (dmi_reg_wdata[22:20] == 3'b011)
);
((dmi_reg_wdata[22:20] != 3'b010) | ((dmi_reg_wdata[31:24] == 8'h2) && (|data1_reg[1:0]))); // Only word size is allowed
assign abstractcs_error_sel5 = (dmi_reg_addr == 7'h16) & dmi_reg_en & dmi_reg_wr_en;
assign abstractcs_error_selor = abstractcs_error_sel0 | abstractcs_error_sel1 | abstractcs_error_sel2 | abstractcs_error_sel3 | abstractcs_error_sel4 | abstractcs_error_sel5;
assign abstractcs_error_din[2:0] = ({3{abstractcs_error_sel0}} & 3'b001) | // writing command or abstractcs while a command was executing. Or accessing data0
({3{abstractcs_error_sel1}} & 3'b010) | // writing a non-zero command to cmd field of command
({3{abstractcs_error_sel2}} & 3'b011) | // exception while running command
({3{abstractcs_error_sel3}} & 3'b100) | // writing a comnand when not in the halted state
({3{abstractcs_error_sel4}} & 3'b111) | // unaligned abstract memory command
({3{abstractcs_error_sel5}} & ~dmi_reg_wdata[10:8] & abstractcs_reg[10:8]) | // W1C
({3{~abstractcs_error_selor}} & abstractcs_reg[10:8]); // hold
assign abstractcs_error_din[2:0] = abstractcs_error_sel0 ? 3'b001 : // writing command or abstractcs while a command was executing. Or accessing data0
abstractcs_error_sel1 ? 3'b010 : // writing a illegal command type to cmd field of command
abstractcs_error_sel2 ? 3'b011 : // exception while running command
abstractcs_error_sel3 ? 3'b100 : // writing a comnand when not in the halted state
abstractcs_error_sel4 ? 3'b111 : // unaligned or illegal size abstract memory command
abstractcs_error_sel5 ? (~dmi_reg_wdata[10:8] & abstractcs_reg[10:8]) : //W1C
abstractcs_reg[10:8]; //hold
rvdffs #(1) dmabstractcs_busy_reg (.din(abstractcs_busy_din), .dout(abstractcs_reg[12]), .en(abstractcs_busy_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
rvdff #(3) dmabstractcs_error_reg (.din(abstractcs_error_din[2:0]), .dout(abstractcs_reg[10:8]), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
@ -381,7 +379,8 @@ module dbg (
// command register - implemented all the bits in this register
// command[16] = 1: write, 0: read
assign command_wren = (dmi_reg_addr == 7'h17) & dmi_reg_en & dmi_reg_wr_en & (dbg_state == HALTED);
rvdffe #(32) dmcommand_reg (.*, .din(dmi_reg_wdata[31:0]), .dout(command_reg[31:0]), .en(command_wren), .rst_l(dbg_dm_rst_l));
assign command_din[31:0] = {dmi_reg_wdata[31:24],1'b0,dmi_reg_wdata[22:20],3'b0,dmi_reg_wdata[16:0]};
rvdffe #(32) dmcommand_reg (.*, .din(command_din[31:0]), .dout(command_reg[31:0]), .en(command_wren), .rst_l(dbg_dm_rst_l));
// data0 reg
assign data0_reg_wren0 = (dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h4) & (dbg_state == HALTED));

View File

@ -57,6 +57,12 @@ csr_mcgc = [011111111000]
csr_mcpc = [011111000010]
csr_mfdc = [011111111001]
csr_mgpmc = [011111010000]
csr_mitctl0 = [011111010100]
csr_mitctl1 = [011111010111]
csr_mitb0 = [011111010011]
csr_mitb1 = [011111010110]
csr_mitcnt0 = [011111010010]
csr_mitcnt1 = [011111010101]
csr_perfva = [101100000111]
csr_perfvb = [101100001...]
csr_perfvc = [10110001....]
@ -136,6 +142,12 @@ csr = {
csr_mhpme5
csr_mhpme6
csr_mgpmc
csr_mitctl0
csr_mitctl1
csr_mitb0
csr_mitb1
csr_mitcnt0
csr_mitcnt1
csr_perfva
csr_perfvb
csr_perfvc
@ -215,6 +227,12 @@ csr[ csr_dicawics ] = { csr_dicawics }
csr[ csr_dicad0 ] = { csr_dicad0 }
csr[ csr_dicad1 ] = { csr_dicad1 }
csr[ csr_dicago ] = { csr_dicago }
csr[ csr_mitctl0 ] = { csr_mitctl0 }
csr[ csr_mitctl1 ] = { csr_mitctl1 }
csr[ csr_mitb0 ] = { csr_mitb0 }
csr[ csr_mitb1 ] = { csr_mitb1 }
csr[ csr_mitcnt0 ] = { csr_mitcnt0 }
csr[ csr_mitcnt1 ] = { csr_mitcnt1 }
csr[ csr_perfva ] = { valid_only }
csr[ csr_perfvb ] = { valid_only }

View File

@ -276,8 +276,8 @@ module dec_tlu_ctl
logic mstatus_mie_ns;
logic [30:0] mtvec_ns, mtvec;
logic [15:2] dcsr_ns, dcsr;
logic [3:0] mip_ns, mip;
logic [3:0] mie_ns, mie;
logic [5:0] mip_ns, mip;
logic [5:0] mie_ns, mie;
logic [31:0] mcyclel_ns, mcyclel;
logic [31:0] mcycleh_ns, mcycleh;
logic [31:0] minstretl_ns, minstretl;
@ -319,8 +319,8 @@ module dec_tlu_ctl
logic ebreak_e4, ebreak_to_debug_mode_e4, ecall_e4, illegal_e4, illegal_e4_qual, mret_e4, inst_acc_e4, fence_i_e4,
ic_perr_e4, iccm_sbecc_e4, ebreak_to_debug_mode_wb, kill_ebreak_count_wb, inst_acc_second_e4;
logic ebreak_wb, ecall_wb, illegal_wb, illegal_raw_wb, inst_acc_wb, inst_acc_second_wb, fence_i_wb, ic_perr_wb, iccm_sbecc_wb;
logic ce_int_ready, ext_int_ready, timer_int_ready, mhwakeup_ready,
take_ext_int, take_ce_int, take_timer_int, take_nmi, take_nmi_wb;
logic ce_int_ready, ext_int_ready, timer_int_ready, int_timer0_int_ready, int_timer1_int_ready, mhwakeup_ready,
take_ext_int, take_ce_int, take_timer_int, take_int_timer0_int, take_int_timer1_int, take_nmi, take_nmi_wb, int_timer0_int_possible, int_timer1_int_possible;
logic i0_exception_valid_e4, interrupt_valid, i0_exception_valid_wb, interrupt_valid_wb, exc_or_int_valid, exc_or_int_valid_wb, mdccme_ce_req, miccme_ce_req, mice_ce_req;
logic synchronous_flush_e4;
logic [4:0] exc_cause_e4, exc_cause_wb;
@ -371,9 +371,9 @@ module dec_tlu_ctl
logic [8:0] mcgc;
logic [18:0] mfdc;
logic [13:0] mfdc_int, mfdc_ns;
logic i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, pmu_fw_halt_req_ns, pmu_fw_halt_req_f,
logic i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, pmu_fw_halt_req_ns, pmu_fw_halt_req_f, int_timer_stalled,
fw_halt_req, enter_pmu_fw_halt_req, pmu_fw_tlu_halted, pmu_fw_tlu_halted_f, internal_pmu_fw_halt_mode,
internal_pmu_fw_halt_mode_f;
internal_pmu_fw_halt_mode_f, int_timer0_int_hold, int_timer1_int_hold, int_timer0_int_hold_f, int_timer1_int_hold_f;
logic dcsr_single_step_running_ff;
logic nmi_int_delayed, nmi_int_detected;
logic [3:0] trigger_execute, trigger_data, trigger_store;
@ -382,6 +382,12 @@ module dec_tlu_ctl
mpc_debug_halt_ack_f, mpc_debug_run_ack_f, dbg_run_state_f, dbg_halt_state_ff, mpc_debug_halt_req_sync_pulse,
mpc_debug_run_req_sync_pulse, debug_brkpt_valid, debug_halt_req, debug_resume_req, dec_tlu_mpc_halted_only_ns;
// internal timer, isolated for size reasons
logic [31:0] dec_timer_rddata_d;
logic dec_timer_read_d, dec_timer_t0_pulse, dec_timer_t1_pulse;
dec_timer_ctl int_timers(.*);
// end of internal timers
assign clk_override = dec_tlu_dec_clk_override;
@ -426,12 +432,16 @@ module dec_tlu_ctl
assign nmi_lsu_store_type = (nmi_lsu_detected & lsu_imprecise_error_store_any & ~(nmi_int_detected_f & ~take_nmi_wb)) | (nmi_lsu_store_type_f & ~take_nmi_wb);
`define MSTATUS_MIE 0
`define MIP_MCEIP 3
`define MIP_MCEIP 5
`define MIP_MITIP0 4
`define MIP_MITIP1 3
`define MIP_MEIP 2
`define MIP_MTIP 1
`define MIP_MSIP 0
`define MIE_MCEIE 3
`define MIE_MCEIE 5
`define MIE_MITIE0 4
`define MIE_MITIE1 3
`define MIE_MEIE 2
`define MIE_MTIE 1
`define MIE_MSIE 0
@ -558,7 +568,7 @@ module dec_tlu_ctl
assign dec_tlu_flush_pause_wb = dec_tlu_wr_pause_wb_f & ~interrupt_valid_wb;
// detect end of pause counter and rfpc
assign pause_expired_e4 = ~dec_pause_state & dec_pause_state_f & ~(ext_int_ready | ce_int_ready | timer_int_ready | nmi_int_detected) & ~interrupt_valid_wb & ~debug_halt_req_f & ~pmu_fw_halt_req_f & ~halt_taken_f;
assign pause_expired_e4 = ~dec_pause_state & dec_pause_state_f & ~(ext_int_ready | ce_int_ready | timer_int_ready | int_timer0_int_hold_f | int_timer1_int_hold_f | nmi_int_detected) & ~interrupt_valid_wb & ~debug_halt_req_f & ~pmu_fw_halt_req_f & ~halt_taken_f;
// stall dma fifo if a fence is pending, decode is waiting for lsu to idle before decoding the fence inst.
assign dec_tlu_stall_dma = dec_fence_pending;
@ -688,12 +698,14 @@ module dec_tlu_ctl
assign i_cpu_halt_req_sync_qual = i_cpu_halt_req_sync & ~dec_tlu_debug_mode;
assign i_cpu_run_req_sync_qual = i_cpu_run_req_sync & ~dec_tlu_debug_mode & pmu_fw_tlu_halted_f;
rvdff #(8) exthaltff (.*, .clk(free_clk), .din({i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, cpu_halt_status,
rvdff #(10) exthaltff (.*, .clk(free_clk), .din({i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, cpu_halt_status,
cpu_halt_ack, cpu_run_ack, internal_pmu_fw_halt_mode,
pmu_fw_halt_req_ns, pmu_fw_tlu_halted}),
pmu_fw_halt_req_ns, pmu_fw_tlu_halted,
int_timer0_int_hold, int_timer1_int_hold}),
.dout({i_cpu_halt_req_d1, i_cpu_run_req_d1_raw, o_cpu_halt_status,
o_cpu_halt_ack, o_cpu_run_ack, internal_pmu_fw_halt_mode_f,
pmu_fw_halt_req_f, pmu_fw_tlu_halted_f}));
pmu_fw_halt_req_f, pmu_fw_tlu_halted_f,
int_timer0_int_hold_f, int_timer1_int_hold_f}));
// only happens if we aren't in dgb_halt
assign ext_halt_pulse = i_cpu_halt_req_sync_qual & ~i_cpu_halt_req_d1;
@ -718,7 +730,7 @@ module dec_tlu_ctl
`endif
// high priority interrupts can wakeup from external halt, so can unmasked timer interrupts
assign i_cpu_run_req_d1 = i_cpu_run_req_d1_raw | ((nmi_int_detected | timer_int_ready | (mhwakeup & mhwakeup_ready)) & o_cpu_halt_status);
assign i_cpu_run_req_d1 = i_cpu_run_req_d1_raw | ((nmi_int_detected | timer_int_ready | int_timer0_int_hold_f | int_timer1_int_hold_f | (mhwakeup & mhwakeup_ready)) & o_cpu_halt_status);
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
@ -906,6 +918,8 @@ module dec_tlu_ctl
assign exc_cause_e4[4:0] = ( ({5{take_ext_int}} & 5'h0b) |
({5{take_timer_int}} & 5'h07) |
({5{take_int_timer0_int}} & 5'h1d) |
({5{take_int_timer1_int}} & 5'h1c) |
({5{take_ce_int}} & 5'h1e) |
({5{illegal_e4}} & 5'h02) |
({5{ecall_e4}} & 5'h0b) |
@ -936,6 +950,19 @@ module dec_tlu_ctl
assign ce_int_ready = ~dec_csr_stall_int_ff & mstatus_mie_ns & mip[`MIP_MCEIP] & mie_ns[`MIE_MCEIE];
assign timer_int_ready = ~dec_csr_stall_int_ff & mstatus_mie_ns & mip[`MIP_MTIP] & mie_ns[`MIE_MTIE];
// MIP for internal timers pulses for 1 clock, resets the timer counter. Mip won't hold past the various stall conditions.
assign int_timer0_int_possible = mstatus_mie_ns & mie_ns[`MIE_MITIE0];
assign int_timer0_int_ready = mip[`MIP_MITIP0] & int_timer0_int_possible;
assign int_timer1_int_possible = mstatus_mie_ns & mie_ns[`MIE_MITIE1];
assign int_timer1_int_ready = mip[`MIP_MITIP1] & int_timer1_int_possible;
// Internal timers pulse and reset. If core is PMU/FW halted, the pulse will cause an exit from halt, but won't stick around
// Make it sticky, also for 1 cycle stall conditions.
assign int_timer_stalled = dec_csr_stall_int_ff | synchronous_flush_e4 | exc_or_int_valid_wb | mret_wb | mret_e4;
assign int_timer0_int_hold = (int_timer0_int_ready & (pmu_fw_tlu_halted_f | int_timer_stalled)) | (int_timer0_int_possible & int_timer0_int_hold_f & ~interrupt_valid & ~internal_dbg_halt_mode_f);
assign int_timer1_int_hold = (int_timer1_int_ready & (pmu_fw_tlu_halted_f | int_timer_stalled)) | (int_timer1_int_possible & int_timer1_int_hold_f & ~interrupt_valid & ~internal_dbg_halt_mode_f);
// mispredicts
assign i0_mp_e4 = exu_i0_flush_lower_e4 & ~i0_trigger_hit_e4;
assign i1_mp_e4 = exu_i1_flush_lower_e4 & ~trigger_hit_e4 & ~lsu_i0_rfnpc_dc4;
@ -957,11 +984,13 @@ module dec_tlu_ctl
assign take_ext_int = ext_int_ready & ~block_interrupts;
assign take_ce_int = ce_int_ready & ~ext_int_ready & ~block_interrupts;
assign take_timer_int = timer_int_ready & ~ext_int_ready & ~ce_int_ready & ~block_interrupts;
assign take_int_timer0_int = (int_timer0_int_ready | int_timer0_int_hold_f) & int_timer0_int_possible & ~dec_csr_stall_int_ff & ~timer_int_ready & ~ext_int_ready & ~ce_int_ready & ~block_interrupts;
assign take_int_timer1_int = (int_timer1_int_ready | int_timer1_int_hold_f) & int_timer1_int_possible & ~dec_csr_stall_int_ff & ~(int_timer0_int_ready | int_timer0_int_hold_f) & ~timer_int_ready & ~ext_int_ready & ~ce_int_ready & ~block_interrupts;
assign take_reset = reset_delayed & mpc_reset_run_req;
assign take_nmi = nmi_int_detected & ~internal_pmu_fw_halt_mode & (~internal_dbg_halt_mode | (dcsr_single_step_running_f & dcsr[`DCSR_STEPIE] & ~dec_tlu_i0_valid_e4 & ~dcsr_single_step_done_f)) & ~synchronous_flush_e4 & ~mret_e4 & ~take_reset & ~ebreak_to_debug_mode_e4;
assign interrupt_valid = take_ext_int | take_timer_int | take_nmi | take_ce_int;
assign interrupt_valid = take_ext_int | take_timer_int | take_nmi | take_ce_int | take_int_timer0_int | take_int_timer1_int;
// Compute interrupt path:
@ -1085,6 +1114,8 @@ module dec_tlu_ctl
// MIP (RW)
//
// [30] MCEIP : (RO) M-Mode Correctable Error interrupt pending
// [29] MITIP0 : (RO) M-Mode Internal Timer0 interrupt pending
// [28] MITIP1 : (RO) M-Mode Internal Timer1 interrupt pending
// [11] MEIP : (RO) M-Mode external interrupt pending
// [7] MTIP : (RO) M-Mode timer interrupt pending
// [3] MSIP : (RO) M-Mode software interrupt pending
@ -1092,20 +1123,22 @@ module dec_tlu_ctl
assign ce_int = (mdccme_ce_req | miccme_ce_req | mice_ce_req);
assign mip_ns[3:0] = {ce_int, mexintpend, timer_int_sync, mip[0]};
rvdff #(4) mip_ff (.*, .clk(free_clk), .din(mip_ns[3:0]), .dout(mip[3:0]));
assign mip_ns[5:0] = {ce_int, dec_timer_t0_pulse, dec_timer_t1_pulse, mexintpend, timer_int_sync, mip[0]};
rvdff #(6) mip_ff (.*, .clk(free_clk), .din(mip_ns[5:0]), .dout(mip[5:0]));
// ----------------------------------------------------------------------
// MIE (RW)
// [30] MCEIE : (RO) M-Mode Correctable Error interrupt enable
// [29] MITIE0 : (RO) M-Mode Internal Timer0 interrupt enable
// [28] MITIE1 : (RO) M-Mode Internal Timer1 interrupt enable
// [11] MEIE : (RW) M-Mode external interrupt enable
// [7] MTIE : (RW) M-Mode timer interrupt enable
// [3] MSIE : (RW) M-Mode software interrupt enable
`define MIE 12'h304
assign wr_mie_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MIE);
assign mie_ns[3:0] = wr_mie_wb ? {dec_csr_wrdata_wb[30], dec_csr_wrdata_wb[11], dec_csr_wrdata_wb[7], dec_csr_wrdata_wb[3]} : mie[3:0];
rvdff #(4) mie_ff (.*, .clk(csr_wr_clk), .din(mie_ns[3:0]), .dout(mie[3:0]));
assign mie_ns[5:0] = wr_mie_wb ? {dec_csr_wrdata_wb[30:28], dec_csr_wrdata_wb[11], dec_csr_wrdata_wb[7], dec_csr_wrdata_wb[3]} : mie[5:0];
rvdff #(6) mie_ff (.*, .clk(csr_wr_clk), .din(mie_ns[5:0]), .dout(mie[5:0]));
// ----------------------------------------------------------------------
@ -1949,7 +1982,7 @@ module dec_tlu_ctl
({2{(mhpme_vec[i][5:0] == `MHPME_DMA_DCCM_STALL )}} & {1'b0, dma_dccm_stall_any}) |
({2{(mhpme_vec[i][5:0] == `MHPME_DMA_ICCM_STALL )}} & {1'b0, dma_iccm_stall_any}) |
({2{(mhpme_vec[i][5:0] == `MHPME_EXC_TAKEN )}} & {1'b0, (i0_exception_valid_e4 | trigger_hit_e4 | lsu_exc_valid_e4)}) |
({2{(mhpme_vec[i][5:0] == `MHPME_TIMER_INT_TAKEN )}} & {1'b0, take_timer_int}) |
({2{(mhpme_vec[i][5:0] == `MHPME_TIMER_INT_TAKEN )}} & {1'b0, take_timer_int | take_int_timer0_int | take_int_timer1_int}) |
({2{(mhpme_vec[i][5:0] == `MHPME_EXT_INT_TAKEN )}} & {1'b0, take_ext_int}) |
({2{(mhpme_vec[i][5:0] == `MHPME_FLUSH_LOWER )}} & {1'b0, tlu_flush_lower_e4}) |
({2{(mhpme_vec[i][5:0] == `MHPME_BR_ERROR )}} & {(dec_tlu_br1_error_e4 | dec_tlu_br1_start_error_e4) & rfpc_i1_e4, (dec_tlu_br0_error_e4 | dec_tlu_br0_start_error_e4) & rfpc_i0_e4}) |
@ -1961,7 +1994,7 @@ module dec_tlu_ctl
({2{(mhpme_vec[i][5:0] == `MHPME_IBUS_STALL )}} & {1'b0, ifu_pmu_bus_busy}) |
({2{(mhpme_vec[i][5:0] == `MHPME_DBUS_STALL )}} & {1'b0, lsu_pmu_bus_busy}) |
({2{(mhpme_vec[i][5:0] == `MHPME_INT_DISABLED )}} & {1'b0, ~mstatus[`MSTATUS_MIE]}) |
({2{(mhpme_vec[i][5:0] == `MHPME_INT_STALLED )}} & {1'b0, ~mstatus[`MSTATUS_MIE] & |(mip[3:0] & mie[3:0])})
({2{(mhpme_vec[i][5:0] == `MHPME_INT_STALLED )}} & {1'b0, ~mstatus[`MSTATUS_MIE] & |(mip[5:0] & mie[5:0])})
);
end
@ -2209,7 +2242,7 @@ assign csr_mvendorid = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[7]
assign csr_marchid = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[7]
&dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]);
assign csr_mimpid = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[3]
assign csr_mimpid = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[6]
&dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]);
assign csr_mhartid = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[7]
@ -2219,7 +2252,7 @@ assign csr_mstatus = (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[0]);
assign csr_mtvec = (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[5]
&dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[0]);
&!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[0]);
assign csr_mip = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[2]);
@ -2251,14 +2284,14 @@ assign csr_mepc = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[1]
assign csr_mcause = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
&dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]);
assign csr_mtval = (dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[1]
assign csr_mtval = (!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[1]
&dec_csr_rdaddr_d[0]);
assign csr_mrac = (!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]
&!dec_csr_rdaddr_d[1]);
assign csr_dmst = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[2]
assign csr_dmst = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[2]
&!dec_csr_rdaddr_d[1]);
assign csr_mdseac = (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]
@ -2283,12 +2316,13 @@ assign csr_meicidpl = (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[6]
assign csr_dcsr = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]
&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[0]);
assign csr_mpmc = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]);
assign csr_mpmc = (dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[2]
&dec_csr_rdaddr_d[1]);
assign csr_mcgc = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]
&!dec_csr_rdaddr_d[0]);
assign csr_mcpc = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]
assign csr_mcpc = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[4]
&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]);
assign csr_mfdc = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]
@ -2353,134 +2387,138 @@ assign csr_mhpme6 = (dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]
&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]
&!dec_csr_rdaddr_d[0]);
assign csr_mgpmc = (dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]);
assign csr_mgpmc = (dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]
&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]);
assign csr_micect = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[3]
&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]);
assign csr_miccmect = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[4]
assign csr_miccmect = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[0]);
assign csr_mdccmect = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[4]
assign csr_mdccmect = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]
&dec_csr_rdaddr_d[1]);
assign csr_dicawics = (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[5]
&dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]);
assign csr_dicad0 = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[5]
assign csr_dicad0 = (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[4]
&dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]);
assign csr_dicad1 = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[3]
&dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]);
assign csr_dicago = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[7]
assign csr_dicago = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[3]
&dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]);
assign presync = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]
&dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
&dec_csr_rdaddr_d[4]) | (!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]
&dec_csr_rdaddr_d[1]) | (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[4]
&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]) | (
&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]) | (
!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]
&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]) | (
dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
&dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[7]
&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
&!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]);
&dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]) | (dec_csr_rdaddr_d[11]
&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[1]
&!dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]
&dec_csr_rdaddr_d[1]);
assign postsync = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]
&dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[0]) | (
!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[1]
&dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[0]) | (
!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]
&dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]
&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]) | (!dec_csr_rdaddr_d[7]
&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]) | (
dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
&dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[4]
&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[10]
&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]
&dec_csr_rdaddr_d[1]) | (!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[7]
&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]) | (
!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[2]
&dec_csr_rdaddr_d[0]);
&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]) | (
!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]);
logic legal_csr;
assign legal_csr = (!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]
&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]
&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]) | (
dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[9]
assign legal_csr = (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
&!dec_csr_rdaddr_d[1]) | (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[2]
&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]
&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]
&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]) | (
&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[11]
&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[0]) | (
!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
&dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]
&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
&dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]) | (
dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]
&dec_csr_rdaddr_d[1]) | (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
&dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[2]
&!dec_csr_rdaddr_d[1]) | (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]
&!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[2]) | (
!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]
&!dec_csr_rdaddr_d[2]) | (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]
&!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]
&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]
&!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[3]
&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]) | (dec_csr_rdaddr_d[11]
&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]
&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]
&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[0]) | (
!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
&dec_csr_rdaddr_d[2]) | (dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
&dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | (
dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]
dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]) | (
!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]
&!dec_csr_rdaddr_d[2]) | (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]
&!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[1]
&dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]
&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]
&!dec_csr_rdaddr_d[2]) | (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]
&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]
&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]
&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]
&dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]
&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[11]
&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]
&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]
&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]) | (
!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
&dec_csr_rdaddr_d[1]) | (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[2]) | (!dec_csr_rdaddr_d[11]
&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
&dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]
&!dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[1]) | (!dec_csr_rdaddr_d[11]
&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
&dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[0]) | (
!dec_csr_rdaddr_d[11]&dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]
&dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[11]
&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]
&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[2]) | (
&!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]) | (
!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]&dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
&!dec_csr_rdaddr_d[2]) | (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[5]
&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[1]
&!dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]
&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[11]
&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[1]) | (
!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]
&dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[3]) | (!dec_csr_rdaddr_d[11]
&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
&!dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]
&dec_csr_rdaddr_d[4]) | (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[6]
&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[3]) | (dec_csr_rdaddr_d[11]
&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]
&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]);
&!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[3]) | (
dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
&dec_csr_rdaddr_d[3]) | (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]
&dec_csr_rdaddr_d[9]&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[7]
&!dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]) | (
dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[9]
&dec_csr_rdaddr_d[8]&!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
&dec_csr_rdaddr_d[4]);
assign dec_tlu_presync_d = presync & dec_csr_any_unq_d & ~dec_csr_wen_unq_d;
@ -2495,11 +2533,11 @@ assign dec_csr_legal_d = ( dec_csr_any_unq_d &
assign dec_csr_rddata_d[31:0] = ( ({32{csr_misa}} & 32'h40001104) |
({32{csr_mvendorid}} & 32'h00000045) |
({32{csr_marchid}} & 32'h0000000b) |
({32{csr_mimpid}} & 32'h2) |
({32{csr_mimpid}} & 32'h3) |
({32{csr_mstatus}} & {19'b0, 2'b11, 3'b0, mstatus[1], 3'b0, mstatus[0], 3'b0}) |
({32{csr_mtvec}} & {mtvec[30:1], 1'b0, mtvec[0]}) |
({32{csr_mip}} & {1'b0, mip[3], 18'b0, mip[2], 3'b0, mip[1], 3'b0, mip[0], 3'b0}) |
({32{csr_mie}} & {1'b0, mie[3], 18'b0, mie[2], 3'b0, mie[1], 3'b0, mie[0], 3'b0}) |
({32{csr_mip}} & {1'b0, mip[5:3], 16'b0, mip[2], 3'b0, mip[1], 3'b0, mip[0], 3'b0}) |
({32{csr_mie}} & {1'b0, mie[5:3], 16'b0, mie[2], 3'b0, mie[1], 3'b0, mie[0], 3'b0}) |
({32{csr_mcyclel}} & mcyclel[31:0]) |
({32{csr_mcycleh}} & mcycleh_inc[31:0]) |
({32{csr_minstretl}} & minstretl_read[31:0]) |
@ -2544,7 +2582,8 @@ assign dec_csr_rddata_d[31:0] = ( ({32{csr_misa}} & 32'h40001104) |
({32{csr_mhpme4}} & {26'b0,mhpme4[5:0]}) |
({32{csr_mhpme5}} & {26'b0,mhpme5[5:0]}) |
({32{csr_mhpme6}} & {26'b0,mhpme6[5:0]}) |
({32{csr_mgpmc}} & {31'b0, mgpmc})
({32{csr_mgpmc}} & {31'b0, mgpmc}) |
({32{dec_timer_read_d}} & dec_timer_rddata_d[31:0])
);
@ -2581,3 +2620,169 @@ assign dec_csr_rddata_d[31:0] = ( ({32{csr_misa}} & 32'h40001104) |
endmodule // dec_tlu_ctl
module dec_timer_ctl
(
input logic clk,
input logic free_clk,
input logic rst_l,
input logic dec_csr_wen_wb_mod, // csr write enable at wb
input logic [11:0] dec_csr_rdaddr_d, // read address for csr
input logic [11:0] dec_csr_wraddr_wb, // write address for csr
input logic [31:0] dec_csr_wrdata_wb, // csr write data at wb
input logic dec_pause_state, // Paused
input logic dec_tlu_pmu_fw_halted, // pmu/fw halted
input logic internal_dbg_halt_timers, // debug halted
output logic [31:0] dec_timer_rddata_d, // timer CSR read data
output logic dec_timer_read_d, // timer CSR address match
output logic dec_timer_t0_pulse, // timer0 int
output logic dec_timer_t1_pulse, // timer1 int
input logic scan_mode
);
`define MITCTL_ENABLE 0
`define MITCTL_ENABLE_HALTED 1
`define MITCTL_ENABLE_PAUSED 2
logic [31:0] mitcnt0_ns, mitcnt0, mitcnt1_ns, mitcnt1, mitb0, mitb1, mitb0_b, mitb1_b, mitcnt0_inc, mitcnt1_inc;
logic [2:0] mitctl0_ns, mitctl0, mitctl1_ns, mitctl1;
logic wr_mitcnt0_wb, wr_mitcnt1_wb, wr_mitb0_wb, wr_mitb1_wb, wr_mitctl0_wb, wr_mitctl1_wb;
logic mitcnt0_inc_ok, mitcnt1_inc_ok, mitcnt0_cout_nc, mitcnt1_cout_nc;
logic mit0_match_ns;
logic mit1_match_ns;
logic mitctl0_0_b_ns;
logic mitctl0_0_b;
logic mitctl1_0_b_ns;
logic mitctl1_0_b;
assign mit0_match_ns = (mitcnt0[31:0] >= mitb0[31:0]);
assign mit1_match_ns = (mitcnt1[31:0] >= mitb1[31:0]);
assign dec_timer_t0_pulse = mit0_match_ns;
assign dec_timer_t1_pulse = mit1_match_ns;
// ----------------------------------------------------------------------
// MITCNT0 (RW)
// [31:0] : Internal Timer Counter 0
`define MITCNT0 12'h7d2
assign wr_mitcnt0_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MITCNT0);
assign mitcnt0_inc_ok = mitctl0[`MITCTL_ENABLE] & (~dec_pause_state | mitctl0[`MITCTL_ENABLE_PAUSED]) & (~dec_tlu_pmu_fw_halted | mitctl0[`MITCTL_ENABLE_HALTED]) & ~internal_dbg_halt_timers;
assign {mitcnt0_cout_nc, mitcnt0_inc[31:0]} = mitcnt0[31:0] + {31'b0, 1'b1};
assign mitcnt0_ns[31:0] = mit0_match_ns ? 'b0 : wr_mitcnt0_wb ? dec_csr_wrdata_wb[31:0] : mitcnt0_inc[31:0];
rvdffe #(32) mitcnt0_ff (.*, .en(wr_mitcnt0_wb | mitcnt0_inc_ok | mit0_match_ns), .din(mitcnt0_ns[31:0]), .dout(mitcnt0[31:0]));
// ----------------------------------------------------------------------
// MITCNT1 (RW)
// [31:0] : Internal Timer Counter 0
`define MITCNT1 12'h7d5
assign wr_mitcnt1_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MITCNT1);
assign mitcnt1_inc_ok = mitctl1[`MITCTL_ENABLE] & (~dec_pause_state | mitctl1[`MITCTL_ENABLE_PAUSED]) & (~dec_tlu_pmu_fw_halted | mitctl1[`MITCTL_ENABLE_HALTED]) & ~internal_dbg_halt_timers;
assign {mitcnt1_cout_nc, mitcnt1_inc[31:0]} = mitcnt1[31:0] + {31'b0, 1'b1};
assign mitcnt1_ns[31:0] = mit1_match_ns ? 'b0 : wr_mitcnt1_wb ? dec_csr_wrdata_wb[31:0] : mitcnt1_inc[31:0];
rvdffe #(32) mitcnt1_ff (.*, .en(wr_mitcnt1_wb | mitcnt1_inc_ok | mit1_match_ns), .din(mitcnt1_ns[31:0]), .dout(mitcnt1[31:0]));
// ----------------------------------------------------------------------
// MITB0 (RW)
// [31:0] : Internal Timer Bound 0
`define MITB0 12'h7d3
assign wr_mitb0_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MITB0);
rvdffe #(32) mitb0_ff (.*, .en(wr_mitb0_wb), .din(~dec_csr_wrdata_wb[31:0]), .dout(mitb0_b[31:0]));
assign mitb0[31:0] = ~mitb0_b[31:0];
// ----------------------------------------------------------------------
// MITB1 (RW)
// [31:0] : Internal Timer Bound 1
`define MITB1 12'h7d6
assign wr_mitb1_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MITB1);
rvdffe #(32) mitb1_ff (.*, .en(wr_mitb1_wb), .din(~dec_csr_wrdata_wb[31:0]), .dout(mitb1_b[31:0]));
assign mitb1[31:0] = ~mitb1_b[31:0];
// ----------------------------------------------------------------------
// MITCTL0 (RW) Internal Timer Ctl 0
// [31:3] : Reserved, reads 0x0
// [2] : Enable while PAUSEd
// [1] : Enable while HALTed
// [0] : Enable (resets to 0x1)
`define MITCTL0 12'h7d4
assign wr_mitctl0_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MITCTL0);
assign mitctl0_ns[2:0] = wr_mitctl0_wb ? {dec_csr_wrdata_wb[2:0]} : {mitctl0[2:0]};
assign mitctl0_0_b_ns = ~mitctl0_ns[0];
rvdff #(3) mitctl0_ff (.*, .clk(free_clk), .din({mitctl0_ns[2:1], mitctl0_0_b_ns}), .dout({mitctl0[2:1], mitctl0_0_b}));
assign mitctl0[0] = ~mitctl0_0_b;
// ----------------------------------------------------------------------
// MITCTL1 (RW) Internal Timer Ctl 1
// [31:3] : Reserved, reads 0x0
// [2] : Enable while PAUSEd
// [1] : Enable while HALTed
// [0] : Enable (resets to 0x1)
`define MITCTL1 12'h7d7
assign wr_mitctl1_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MITCTL1);
assign mitctl1_ns[2:0] = wr_mitctl1_wb ? {dec_csr_wrdata_wb[2:0]} : {mitctl1[2:0]};
assign mitctl1_0_b_ns = ~mitctl1_ns[0];
rvdff #(3) mitctl1_ff (.*, .clk(free_clk), .din({mitctl1_ns[2:1], mitctl1_0_b_ns}), .dout({mitctl1[2:1], mitctl1_0_b}));
assign mitctl1[0] = ~mitctl1_0_b;
logic csr_mitctl0;
logic csr_mitctl1;
logic csr_mitb0;
logic csr_mitb1;
logic csr_mitcnt0;
logic csr_mitcnt1;
assign csr_mitctl0 = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[4]
&dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]);
assign csr_mitctl1 = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[2]
&dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]);
assign csr_mitb0 = (dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&dec_csr_rdaddr_d[4]
&!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[0]);
assign csr_mitb1 = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[2]
&dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]);
assign csr_mitcnt0 = (dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]
&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]
&!dec_csr_rdaddr_d[0]);
assign csr_mitcnt1 = (dec_csr_rdaddr_d[6]&dec_csr_rdaddr_d[2]
&!dec_csr_rdaddr_d[1]&dec_csr_rdaddr_d[0]);
assign dec_timer_read_d = csr_mitcnt1 | csr_mitcnt0 | csr_mitb1 | csr_mitb0 | csr_mitctl0 | csr_mitctl1;
assign dec_timer_rddata_d[31:0] = ( ({32{csr_mitcnt0}} & mitcnt0[31:0]) |
({32{csr_mitcnt1}} & mitcnt1[31:0]) |
({32{csr_mitb0}} & mitb0[31:0]) |
({32{csr_mitb1}} & mitb1[31:0]) |
({32{csr_mitctl0}} & {29'b0, mitctl0[2:0]}) |
({32{csr_mitctl1}} & {29'b0, mitctl1[2:0]})
);
endmodule // dec_timer_ctl

View File

@ -387,10 +387,8 @@ module axi4_to_ahb #(parameter TAG = 1) (
(wrbuf_byteen[7:0] == 8'hf) | (wrbuf_byteen[7:0] == 8'hf0) | (wrbuf_byteen[7:0] == 8'hff)));
// Generate the ahb signals
assign ahb_haddr[31:0] = bypass_en ? {master_addr[31:3],buf_cmd_byte_ptr[2:0]} : {buf_addr[31:3],buf_cmd_byte_ptr[2:0]};
// assign ahb_hsize[2:0] = ((buf_state == CMD_RD) | (buf_state == STREAM_RD) | (buf_state == STREAM_ERR_RD) | rd_bypass_idle) ? 3'b011 :
// bypass_en ? {1'b0, ({2{buf_aligned_in}} & buf_size_in[1:0])} :
// {1'b0, ({2{buf_aligned}} & buf_size[1:0])}; // Send the full size for aligned trxn
assign ahb_haddr[31:3] = bypass_en ? master_addr[31:3] : buf_addr[31:3];
assign ahb_haddr[2:0] = {3{(ahb_htrans == 2'b10)}} & buf_cmd_byte_ptr[2:0]; // Trxn should be aligned during IDLE
assign ahb_hsize[2:0] = bypass_en ? {1'b0, ({2{buf_aligned_in}} & buf_size_in[1:0])} :
{1'b0, ({2{buf_aligned}} & buf_size[1:0])}; // Send the full size for aligned trxn
assign ahb_hburst[2:0] = 3'b0;

View File

@ -29,7 +29,7 @@ module ram_32768x39
reg [38:0] ram_core [32767:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -53,7 +53,7 @@ module ram_16384x39
reg [38:0] ram_core [16383:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -76,7 +76,7 @@ module ram_8192x39
reg [38:0] ram_core [8191:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -99,7 +99,7 @@ module ram_4096x39
reg [38:0] ram_core [4095:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -122,7 +122,7 @@ module ram_3072x39
reg [38:0] ram_core [3071:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -147,7 +147,7 @@ module ram_2048x39
reg [38:0] ram_core [2047:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -170,7 +170,7 @@ module ram_1536x39 // need this for the 48KB DCCM option
reg [38:0] ram_core [1535:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -194,7 +194,7 @@ module ram_1024x39
reg [38:0] ram_core [1023:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -217,7 +217,7 @@ module ram_768x39
reg [38:0] ram_core [767:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -241,7 +241,7 @@ module ram_512x39
reg [38:0] ram_core [511:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -265,7 +265,7 @@ module ram_256x39
reg [38:0] ram_core [255:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -289,7 +289,7 @@ module ram_128x39
reg [38:0] ram_core [127:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -316,7 +316,7 @@ module ram_1024x20
reg [19:0] ram_core [1023:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -338,7 +338,7 @@ module ram_512x20
reg [19:0] ram_core [511:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -361,7 +361,7 @@ module ram_256x20
reg [19:0] ram_core [255:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -383,7 +383,7 @@ module ram_128x20
reg [19:0] ram_core [127:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -406,7 +406,7 @@ module ram_64x20
reg [19:0] ram_core [63:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -433,7 +433,7 @@ module ram_4096x34
reg [33:0] ram_core [4095:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -458,7 +458,7 @@ module ram_2048x34
reg [33:0] ram_core [2047:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -483,7 +483,7 @@ module ram_1024x34
reg [33:0] ram_core [1023:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -508,7 +508,7 @@ module ram_512x34
reg [33:0] ram_core [511:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -533,7 +533,7 @@ module ram_256x34
reg [33:0] ram_core [255:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -558,7 +558,7 @@ module ram_128x34
reg [33:0] ram_core [127:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -582,7 +582,7 @@ module ram_64x34
reg [33:0] ram_core [63:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -609,7 +609,7 @@ module ram_4096x42
reg [41:0] ram_core [4095:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -634,7 +634,7 @@ module ram_2048x42
reg [41:0] ram_core [2047:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -658,7 +658,7 @@ module ram_1024x42
reg [41:0] ram_core [1023:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -682,7 +682,7 @@ module ram_512x42
reg [41:0] ram_core [511:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -708,7 +708,7 @@ module ram_256x42
reg [41:0] ram_core [255:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -733,7 +733,7 @@ module ram_128x42
reg [41:0] ram_core [127:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -758,7 +758,7 @@ module ram_64x42
reg [41:0] ram_core [63:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -786,7 +786,7 @@ module ram_1024x21
reg [20:0] ram_core [1023:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -809,7 +809,7 @@ module ram_512x21
reg [20:0] ram_core [511:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -834,7 +834,7 @@ module ram_256x21
reg [20:0] ram_core [255:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -859,7 +859,7 @@ module ram_128x21
reg [20:0] ram_core [127:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -884,7 +884,7 @@ module ram_64x21
reg [20:0] ram_core [63:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -908,7 +908,7 @@ module ram_1024x25
reg [24:0] ram_core [1023:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -934,7 +934,7 @@ module ram_512x25
reg [24:0] ram_core [511:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -960,7 +960,7 @@ module ram_256x25
reg [24:0] ram_core [255:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -986,7 +986,7 @@ module ram_128x25
reg [24:0] ram_core [127:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];
@ -1012,7 +1012,7 @@ module ram_64x25
reg [24:0] ram_core [63:0];
always_ff @(posedge CLK) begin
always @(posedge CLK) begin
if (WE) begin// for active high WE - must be specified by user
ram_core[ADR] <= D; Q <= 'x; end else
Q <= ram_core[ADR];

View File

@ -236,6 +236,8 @@ module lsu_bus_buffer
logic FreezePtrEn;
logic [DEPTH_LOG2-1:0] FreezePtr;
logic [DEPTH_LOG2-1:0] lsu_imprecise_error_store_tag;
logic bus_addr_match_pending;
logic bus_cmd_sent, bus_cmd_ready;
logic bus_wcmd_sent, bus_wdata_sent;
@ -807,7 +809,6 @@ module lsu_bus_buffer
end
// Store imprecise error logic
logic [DEPTH_LOG2-1:0] lsu_imprecise_error_store_tag;
always_comb begin
lsu_imprecise_error_store_any = '0;
lsu_imprecise_error_store_tag = '0;

View File

@ -5,4 +5,4 @@
### Contents
Name | Description
---------------------- | ------------------------------
RISC-V_SweRV_EH1_PRM.pdf | Programmer's Reference Manual V1.5.1 for SweRV EH1 core
RISC-V_SweRV_EH1_PRM.pdf | Programmer's Reference Manual V1.5 for SweRV EH1 core

Binary file not shown.

View File

@ -342,7 +342,7 @@ module tb_top;
commit_count++;
$fwrite (el, "%10d : %6s 0 %h %h %s\n", cycleCnt, $sformatf("#%0d",commit_count),
trace_rv_i_address_ip[31+i*32 -:32], trace_rv_i_insn_ip[31+i*32-:32],
wb_dest[i] !=0 ? $sformatf("r%0d=%h", wb_dest[i], wb_data[i]) : "");
(wb_dest[i] !=0 && wb_valid[i]) ? $sformatf("r%0d=%h", wb_dest[i], wb_data[i]) : "");
end
end
end

View File

@ -32,38 +32,32 @@ double sc_time_stamp () {
int main(int argc, char** argv) {
std::cout << "\nVerilatorTB: Start of sim\n" << std::endl;
// Check for +dumpon and remove it from argv
bool dumpWaves = false;
int newArgc = 0;
for (int i = 0; i < argc; ++i)
if (strcmp(argv[i], "+dumpon") == 0)
dumpWaves = true;
else
argv[newArgc++] = argv[i];
argc = newArgc;
Verilated::commandArgs(argc, argv);
Vtb_top* tb = new Vtb_top;
// init trace dump
Verilated::traceEverOn(true);
VerilatedVcdC* tfp = new VerilatedVcdC;
tb->trace (tfp, 24);
if (dumpWaves)
tfp->open ("sim.vcd");
VerilatedVcdC* tfp = NULL;
#if VM_TRACE
Verilated::traceEverOn(true);
tfp = new VerilatedVcdC;
tb->trace (tfp, 24);
tfp->open ("sim.vcd");
#endif
// Simulate
while(!Verilated::gotFinish()){
if (dumpWaves)
#if VM_TRACE
tfp->dump (main_time);
#endif
main_time += 5;
tb->core_clk = !tb->core_clk;
tb->eval();
}
if (dumpWaves)
#if VM_TRACE
tfp->close();
#endif
std::cout << "\nVerilatorTB: End of sim" << std::endl;
exit(EXIT_SUCCESS);

View File

@ -25,7 +25,7 @@ snapshot = $(target)
# Allow tool override
SWERV_CONFIG = ${RV_ROOT}/configs/swerv.config
IRUN = irun
IRUN = xrun
VCS = vcs
VERILATOR = verilator
VLOG = qverilog
@ -46,6 +46,7 @@ ifdef debug
IRUN_DEBUG = -access +rc
IRUN_DEBUG_RUN = -input ${RV_ROOT}/testbench/input.tcl
VCS_DEBUG = -debug_access
VERILATOR_DEBUG = --trace
RIVIERA_DEBUG = +access +r
endif
@ -87,8 +88,8 @@ verilator-build: ${TBFILES} ${BUILD_DIR}/defines.h test_tb_top.cpp
-I${RV_ROOT}/testbench \
-f ${RV_ROOT}/testbench/flist \
${TBFILES} \
--top-module tb_top -exe test_tb_top.cpp --trace --autoflush
cp ${RV_ROOT}/testbench/test_tb_top.cpp obj_dir/
--top-module tb_top -exe test_tb_top.cpp --autoflush $(VERILATOR_DEBUG)
cp ${RV_ROOT}/testbench/test_tb_top.cpp obj_dir
$(MAKE) -C obj_dir/ -f Vtb_top.mk $(VERILATOR_MAKE_FLAGS)
touch verilator-build
@ -103,7 +104,7 @@ vcs-build: ${TBFILES} ${BUILD_DIR}/defines.h
touch vcs-build
irun-build: ${TBFILES} ${BUILD_DIR}/defines.h
$(IRUN) -64bit -elaborate $(IRUN_DEBUG) -q -sv -sysv -nowarn CUVIHR -nclibdirpath . -nclibdirname swerv.build \
$(IRUN) -64bit -elaborate $(IRUN_DEBUG) -q -sv -sysv -nowarn CUVIHR -xmlibdirpath . -xmlibdirname swerv.build \
-incdir ${RV_ROOT}/design/lib -incdir ${RV_ROOT}/design/include -incdir ${BUILD_DIR} -vlog_ext +.vh+.h\
$(defines) -f ${RV_ROOT}/testbench/flist\
-top tb_top ${TBFILES} -I${RV_ROOT}/testbench \
@ -125,7 +126,7 @@ verilator: program.hex verilator-build
./obj_dir/Vtb_top ${DEBUG_PLUS}
irun: program.hex irun-build
$(IRUN) -64bit -abvglobalfailurelimit 1 +lic_queue -licqueue -status -nclibdirpath . -nclibdirname swerv.build \
$(IRUN) -64bit -abvglobalfailurelimit 1 +lic_queue -licqueue -status -xmlibdirpath . -xmlibdirname swerv.build \
-snapshot ${snapshot} -r ${snapshot} $(IRUN_DEBUG_RUN)
vcs: program.hex vcs-build

View File

@ -1,4 +1,19 @@
#!/usr/bin/perl
# SPDX-License-Identifier: Apache-2.0
# Copyright 2020 Western Digital Corporation or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use Getopt::Long;

View File

@ -1,4 +1,19 @@
#!/usr/bin/perl
# SPDX-License-Identifier: Apache-2.0
# Copyright 2020 Western Digital Corporation or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use Getopt::Long;

View File

@ -1,4 +1,19 @@
#!/usr/bin/perl
# SPDX-License-Identifier: Apache-2.0
# Copyright 2020 Western Digital Corporation or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use Getopt::Long;

View File

@ -1,4 +1,19 @@
#!/usr/bin/perl
# SPDX-License-Identifier: Apache-2.0
# Copyright 2020 Western Digital Corporation or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use Getopt::Long;