Skip to content

Commit

Permalink
SV: Improve toplevel generation
Browse files Browse the repository at this point in the history
  • Loading branch information
Alasdair committed Dec 6, 2024
1 parent 293655b commit e319b40
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 8 deletions.
35 changes: 34 additions & 1 deletion lib/sv/sail_modules.sv
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ endfunction
import "DPI-C" function bit[7:0] sail_read_byte(logic [63:0] addr);

import "DPI-C" function bit sail_read_tag(logic [63:0] addr);

import "DPI-C" function void sail_write_byte(logic [63:0] addr, logic [7:0] b);
`else
logic [7:0] sail_memory [logic [63:0]];

Expand All @@ -115,6 +117,14 @@ typedef struct {

typedef sail_write sail_memory_writes [$];

function automatic void sail_flush_writes(sail_memory_writes writes);
foreach (writes[i]) begin
`ifdef SAIL_DPI_MEMORY
sail_write_byte(writes[i].paddr, writes[i].data);
`endif
end
endfunction

function automatic sail_bits emulator_read_mem(logic [63:0] addrsize, sail_bits addr, sail_int n);
logic [63:0] paddr;
logic [SAIL_BITS_WIDTH-1:0] buffer;
Expand Down Expand Up @@ -163,6 +173,25 @@ module emulator_write_mem
output sail_unit ret,
output sail_memory_writes out_writes
);
always_comb begin
logic [63:0] paddr;
logic [SAIL_BITS_WIDTH-1:0] buffer;
logic [SAIL_INDEX_WIDTH-2:0] i;
sail_memory_writes tmp;

buffer = value.bits;
paddr = addr.bits[63:0];
tmp = in_writes;

for (i = n[SAIL_INDEX_WIDTH-2:0]; i > 0; i = i - 1) begin
sail_write b;
b.paddr = paddr + (64'(i) - 1);
b.data = buffer[7 + ((i - 1) * 8) -: 8];
tmp.push_back(b);
end

out_writes = tmp;
end
endmodule

module emulator_write_mem_exclusive
Expand All @@ -187,7 +216,11 @@ module emulator_write_tag
endmodule

function automatic string sail_string_of_bits(sail_bits bv);
return "";
string hexstr;
string trimmed;
hexstr = $sformatf("%x", bv.bits);
trimmed = hexstr.substr(SAIL_BITS_WIDTH / 4 - (bv.size / 4), SAIL_BITS_WIDTH / 4 - 1).toupper();
return {"0x", trimmed};
endfunction

`endif
2 changes: 1 addition & 1 deletion src/bin/dune
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@
(%{workspace_root}/lib/reverse_endianness.sail
as
lib/reverse_endianness.sail)
(%{workspace_root}/lib/rts.c as lib/rts.c)
(%{workspace_root}/lib/sv/sail_modules.sv as lib/sv/sail_modules.sv)
(%{workspace_root}/lib/rts.h as lib/rts.h)
(%{workspace_root}/lib/sail.c as lib/sail.c)
(%{workspace_root}/lib/sail.h as lib/sail.h)
Expand Down
53 changes: 47 additions & 6 deletions src/sail_sv_backend/jib_sv.ml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,16 @@ module AttributeParser (Info : ATTRIBUTE_INFO) = struct
| Some (AD_aux (_, l)) -> raise (key_type_error ~expected:"boolean" key l)
)

let get_string ~default key obj_opt =
match obj_opt with
| None -> default
| Some obj -> (
match List.assoc_opt key obj with
| None -> default
| Some (AD_aux (AD_string s, _)) -> s
| Some (AD_aux (_, l)) -> raise (key_type_error ~expected:"string" key l)
)

let get_types ~arity obj_opt =
let* types = Option.bind obj_opt (List.assoc_opt "types") in
let ctyps =
Expand Down Expand Up @@ -170,6 +180,20 @@ module AttributeParser (Info : ATTRIBUTE_INFO) = struct
| None -> Some ctyp
| Some _ -> raise (Reporting.err_general l "return_type field should not have positional argument")

let get_string_set ~default key obj_opt =
let add_to_set set = function
| AD_aux (AD_string s, _) -> StringSet.add s set
| AD_aux (_, l) -> raise (key_type_error ~expected:"string" key l)
in
match obj_opt with
| None -> default
| Some obj -> (
match List.assoc_opt key obj with
| None -> default
| Some (AD_aux (AD_list xs, _)) -> List.fold_left add_to_set StringSet.empty xs
| Some (AD_aux (_, l)) -> raise (key_type_error ~expected:"boolean" key l)
)

let get_dpi sets obj_opt =
let* dpi = Option.bind obj_opt (List.assoc_opt "dpi") in
match dpi with
Expand Down Expand Up @@ -2130,6 +2154,11 @@ module Make (Config : CONFIG) = struct
let clk = Attr.get_bool ~default:false "clk" attr in
(* Type conversions for the module input signals derived from function arguments. *)
let arg_conversions = Attr.get_types ~arity:(List.length arg_ctyps) attr in
(* Registers that are exposed as output ports *)
let exposed = Attr.get_string_set ~default:StringSet.empty "expose" attr in
(* Text used to bracket output *)
let prefix = Attr.get_string ~default:"SAIL START\\n" "prefix" attr in
let suffix = Attr.get_string ~default:"SAIL END\\n" "suffix" attr in

let register_resets, register_inputs, register_outputs =
Bindings.fold
Expand All @@ -2141,6 +2170,11 @@ module Make (Config : CONFIG) = struct
)
spec_info.registers ([], [], [])
in
let exposed_registers =
Bindings.fold
(fun reg ctyp ports -> if StringSet.mem (string_of_id reg) exposed then (reg, ctyp) :: ports else ports)
spec_info.registers []
in
let memory_writes =
[
SVD_var (Name (mk_id "empty_memory_writes", -1), CT_memory_writes);
Expand Down Expand Up @@ -2211,16 +2245,23 @@ module Make (Config : CONFIG) = struct
( if footprint.need_stdout then
[
mk_statement
(svs_raw "$write({\"SAIL START\\n\", out_stdout, \"SAIL END\\n\"})"
(svs_raw
(Printf.sprintf "$write({\"%s\", out_stdout, \"%s\"})" prefix suffix)
~inputs:[Name (mk_id "out_stdout", -1)]
);
]
else []
)
@
if footprint.need_stderr then
[mk_statement (svs_raw "$write(out_stderr)" ~inputs:[Name (mk_id "out_stderr", -1)])]
else []
@ ( if footprint.need_stderr then
[mk_statement (svs_raw "$write(out_stderr)" ~inputs:[Name (mk_id "out_stderr", -1)])]
else []
)
@ List.map
(fun (reg, _) ->
mk_statement (SVS_continuous_assign (SVP_id (Name (reg, -1)), Var (Name (prepend_id "out_" reg, -1))))
)
exposed_registers
@ [mk_statement (svs_raw "sail_flush_writes(out_memory_writes)" ~inputs:[Name (mk_id "out_memory_writes", -1)])]
in
if clk then (
let reset_regs, inout_regs =
Expand Down Expand Up @@ -2293,7 +2334,7 @@ module Make (Config : CONFIG) = struct
[mk_port (name (mk_id "clk")) CT_bit; mk_port (name (mk_id "reset")) CT_bit] @ arg_ports @ register_resets
else arg_ports
);
output_ports;
output_ports = output_ports @ List.map (fun (reg, ctyp) -> mk_port (Name (reg, -1)) ctyp) exposed_registers;
defs = List.map mk_def defs;
}

Expand Down

0 comments on commit e319b40

Please sign in to comment.