Fix some vector length issues in clind and dm, implement haltsum regs in dm_csrs

This commit is contained in:
Michael Schaffner 2018-11-23 14:13:16 +01:00
parent 6b99b47270
commit d0e657aaab
No known key found for this signature in database
GPG key ID: 7AA09AE049819C2C
3 changed files with 58 additions and 32 deletions

View file

@ -21,7 +21,7 @@ module clint #(
parameter int unsigned AXI_DATA_WIDTH = 64,
parameter int unsigned AXI_ID_WIDTH = 10,
parameter int unsigned NR_CORES = 1 // Number of cores therefore also the number of timecmp registers and timer interrupts
)(
) (
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
input logic testmode_i,
@ -35,6 +35,9 @@ module clint #(
localparam logic [15:0] MSIP_BASE = 16'h0;
localparam logic [15:0] MTIMECMP_BASE = 16'h4000;
localparam logic [15:0] MTIME_BASE = 16'hbff8;
localparam AddrSelWidth = (NR_CORES == 1) ? 1 : $clog2(NR_CORES);
// signals from AXI 4 Lite
logic [AXI_ADDR_WIDTH-1:0] address;
logic en;
@ -87,11 +90,11 @@ module clint #(
if (en && we) begin
case (register_address) inside
[MSIP_BASE:MSIP_BASE+8*NR_CORES]: begin
msip_n[$unsigned(address[NR_CORES-1+3:3])] = wdata[0];
msip_n[$unsigned(address[AddrSelWidth-1+3:3])] = wdata[0];
end
[MTIMECMP_BASE:MTIMECMP_BASE+8*NR_CORES]: begin
mtimecmp_n[$unsigned(address[NR_CORES-1+3:3])] = wdata;
mtimecmp_n[$unsigned(address[AddrSelWidth-1+3:3])] = wdata;
end
MTIME_BASE: begin
@ -109,11 +112,11 @@ module clint #(
if (en && !we) begin
case (register_address) inside
[MSIP_BASE:MSIP_BASE+8*NR_CORES]: begin
rdata = msip_q[$unsigned(address[NR_CORES-1+3:3])];
rdata = msip_q[$unsigned(address[AddrSelWidth-1+3:3])];
end
[MTIMECMP_BASE:MTIMECMP_BASE+8*NR_CORES]: begin
rdata = mtimecmp_q[$unsigned(address[NR_CORES-1+3:3])];
rdata = mtimecmp_q[$unsigned(address[AddrSelWidth-1+3:3])];
end
MTIME_BASE: begin

View file

@ -17,7 +17,7 @@
module dm_csrs #(
parameter int NrHarts = -1
)(
) (
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
input logic testmode_i,
@ -89,20 +89,43 @@ module dm_csrs #(
localparam dm::dm_csr_t ProgBufEnd = dm::dm_csr_t'((dm::ProgBuf0 + {4'b0, dm::ProgBufSize}));
logic [31:0] haltsum0, haltsum1, haltsum2, haltsum3;
// TODO(zarubaf) Need an elegant way to calculate haltsums
// remove assertions below when implemented...
assign haltsum0 = '0;
assign haltsum1 = '0;
assign haltsum2 = '0;
assign haltsum3 = '0;
for (genvar i = 0; i < 32; i++) begin
// assign haltsum0[i] = halted_i[i];
// TODO(zarubaf) Implement correct haltsum logic
// assign haltsum0[i] = halted_i[hartsel[19:5]];
// assign haltsum1[i] = (NrHarts > 32) ? &halted_i[hartsel[19:10] +: 32] : 1'b0;
// assign haltsum2[i] = (NrHarts > 1024) ? &halted_i[hartsel[19:15] +: 1024] : 1'b0;
// assign haltsum3[i] = (NrHarts > 32768) ? &halted_i[hartsel[19:19] +: 32768] : 1'b0;
logic [NrHarts/2**5 :0][31:0] halted_reshaped0;
logic [NrHarts/2**10:0][31:0] halted_reshaped1;
logic [NrHarts/2**15:0][31:0] halted_reshaped2;
logic [(NrHarts/2**10+1)*32-1:0] halted_flat1;
logic [(NrHarts/2**15+1)*32-1:0] halted_flat2;
logic [32-1:0] halted_flat3;
// haltsum0
assign halted_reshaped0 = halted_i;
assign haltsum0 = halted_reshaped0[hartsel_o[19:5]];
// haltsum1
always_comb begin : p_reduction1
halted_flat1 = '0;
for (int k=0; k<NrHarts/2**5; k++) begin
halted_flat1[k] = &halted_reshaped0[k];
end
halted_reshaped1 = halted_flat1;
haltsum1 = halted_reshaped1[hartsel_o[19:10]];
end
// haltsum2
always_comb begin : p_reduction2
halted_flat2 = '0;
for (int k=0; k<NrHarts/2**10; k++) begin
halted_flat2[k] = &halted_reshaped1[k];
end
halted_reshaped2 = halted_flat2;
haltsum2 = halted_reshaped2[hartsel_o[19:15]];
end
// haltsum3
always_comb begin : p_reduction3
halted_flat3 = '0;
for (int k=0; k<NrHarts/2**15; k++) begin
halted_flat3[k] = &halted_reshaped2[k];
end
haltsum3 = halted_flat3;
end
dm::dmstatus_t dmstatus;
dm::dmcontrol_t dmcontrol_d, dmcontrol_q;
@ -120,7 +143,7 @@ module dm_csrs #(
// because first data address starts at 0x04
logic [({3'b0, dm::DataCount} + dm::Data0 - 1):(dm::Data0)][31:0] data_d, data_q;
logic [NrHarts-1:0] selected_hart;
logic [HartSelLen-1:0] selected_hart;
// a successful response returns zero
assign dmi_resp_o.resp = dm::DTM_SUCCESS;
@ -149,25 +172,25 @@ module dm_csrs #(
// we do not support halt-on-reset sequence
dmstatus.hasresethaltreq = 1'b0;
// TODO(zarubaf) things need to change here if we implement the array mask
dmstatus.allhavereset = havereset_q[hartsel_o[HartSelLen-1:0]];
dmstatus.anyhavereset = havereset_q[hartsel_o[HartSelLen-1:0]];
dmstatus.allhavereset = havereset_q[selected_hart];
dmstatus.anyhavereset = havereset_q[selected_hart];
dmstatus.allresumeack = resumeack_i[hartsel_o[HartSelLen-1:0]];
dmstatus.anyresumeack = resumeack_i[hartsel_o[HartSelLen-1:0]];
dmstatus.allresumeack = resumeack_i[selected_hart];
dmstatus.anyresumeack = resumeack_i[selected_hart];
dmstatus.allunavail = unavailable_i[hartsel_o[HartSelLen-1:0]];
dmstatus.anyunavail = unavailable_i[hartsel_o[HartSelLen-1:0]];
dmstatus.allunavail = unavailable_i[selected_hart];
dmstatus.anyunavail = unavailable_i[selected_hart];
// as soon as we are out of the legal Hart region tell the debugger
// that there are only non-existent harts
dmstatus.allnonexistent = (hartsel_o > NrHarts[19:0] - 1) ? 1'b1 : 1'b0;
dmstatus.anynonexistent = (hartsel_o > NrHarts[19:0] - 1) ? 1'b1 : 1'b0;
dmstatus.allhalted = halted_i[hartsel_o[HartSelLen-1:0]];
dmstatus.anyhalted = halted_i[hartsel_o[HartSelLen-1:0]];
dmstatus.allhalted = halted_i[selected_hart];
dmstatus.anyhalted = halted_i[selected_hart];
dmstatus.allrunning = ~halted_i[hartsel_o[HartSelLen-1:0]];
dmstatus.anyrunning = ~halted_i[hartsel_o[HartSelLen-1:0]];
dmstatus.allrunning = ~halted_i[selected_hart];
dmstatus.anyrunning = ~halted_i[selected_hart];
// abstractcs
abstractcs = '0;
@ -436,7 +459,7 @@ module dm_csrs #(
// output multiplexer
always_comb begin
selected_hart = hartsel_o[NrHarts-1:0];
selected_hart = hartsel_o[HartSelLen-1:0];
// default assignment
haltreq_o = '0;
resumereq_o = '0;

View file

@ -23,7 +23,7 @@ module dm_top #(
parameter int AxiAddrWidth = -1,
parameter int AxiDataWidth = -1,
parameter int AxiUserWidth = -1
)(
) (
input logic clk_i, // clock
input logic rst_ni, // asynchronous reset active low, connect PoR here, not the system reset
input logic testmode_i,