Commit dcd6b1f9 authored by twlostow's avatar twlostow

Added CONSTANT registers & #define REGISTER_ADDRESS macros in C code generator

git-svn-id: http://svn.ohwr.org/wishbone-gen@17 4537843c-45c2-4d80-8546-c3283569414f
parent 69763cad
......@@ -19,7 +19,7 @@
--
function cgen_c_field_define(field, reg)
local prefix;
-- anonymous field?
if(field.c_prefix == nil) then
return ;
else
......@@ -30,18 +30,18 @@ function cgen_c_field_define(field, reg)
emit("");
emit("/* definitions for field: "..field.name.." in reg: "..reg.name.." */");
-- for bit-type fields, emit only masks
-- for bit-type fields, emit only masks
if(field.type == BIT or field.type == MONOSTABLE) then
emit(string.format("%-45s %s", "#define "..prefix, "WBGEN2_GEN_MASK("..field.offset..", 1)"));
else
-- SLV/signed/unsigned fields: emit masks, shifts and access macros
-- SLV/signed/unsigned fields: emit masks, shifts and access macros
emit(string.format("%-45s %s", "#define "..prefix.."_MASK", "WBGEN2_GEN_MASK("..field.offset..", "..field.size..")"));
emit(string.format("%-45s %d", "#define "..prefix.."_SHIFT", field.offset));
emit(string.format("%-45s %s", "#define "..prefix.."_W(value)", "WBGEN2_GEN_WRITE(value, "..field.offset..", "..field.size..")"));
-- if the field is signed, generate read operation with sign-extension
-- if the field is signed, generate read operation with sign-extension
if(field.type == SIGNED) then
emit(string.format("%-45s %s", "#define "..prefix.."_R(reg)", "WBGEN2_SIGN_EXTEND(WBGEN2_GEN_READ(reg, "..field.offset..", "..field.size.."), "..field.size..")"));
else
......@@ -129,7 +129,7 @@ function cgen_c_struct()
end
end
-- emit the structure definition...
-- emit the structure definition...
emit("");
emit("PACKED struct "..string.upper(periph.c_prefix).."_WB {");
indent_right();
......@@ -137,7 +137,7 @@ function cgen_c_struct()
-- emit struct entires for REGs
foreach_reg({TYPE_REG}, function(reg)
-- print(reg.name, reg.prefix, reg.c_prefix, reg.hdl_prefix);
-- print(reg.name, reg.prefix, reg.c_prefix, reg.hdl_prefix);
pad_struct(reg.base);
emit(string.format("/* [0x%x]: REG "..reg.name.." */", reg.base * DATA_BUS_WIDTH / 8));
......@@ -181,13 +181,27 @@ function cgen_c_struct()
end
function cgen_c_defines()
foreach_reg({TYPE_REG}, function(reg)
emit(string.format("/* [0x%x]: REG "..reg.name.." */", reg.base * DATA_BUS_WIDTH / 8));
emit("#define "..string.upper(periph.c_prefix).."_REG_"..string.upper(reg.c_prefix).." "..string.format("0x%08x", reg.base * DATA_BUS_WIDTH/8));
end);
end
-- main C code generator function. Takes the peripheral definition and generates C code.
function cgen_generate_c_header_code()
cgen_new_snippet();
cgen_c_fileheader();
cgen_c_field_masks();
if(options.c_regs_style == "struct") then
cgen_c_struct();
else
cgen_c_defines();
end
emit("#endif");
cgen_write_current_snippet();
......
......@@ -49,6 +49,7 @@ PASS_THROUGH = 0x40;
INTEGER = 0x80;
EXPRESSION = 0x100;
UNDEFINED = 0x200;
CONSTANT = 0x400;
-- reg LOAD types
LOAD_INT = 1;
......@@ -308,6 +309,7 @@ function fix_access(field, reg)
default_access(field, MONOSTABLE, WRITE_ONLY, READ_ONLY);
default_access(field, ENUM, READ_WRITE, READ_ONLY);
default_access(field, PASS_THROUGH, WRITE_ONLY, READ_ONLY);
default_access(field, CONSTANT, READ_ONLY, WRITE_ONLY);
if(field.access ~= nil) then
return;
......
......@@ -25,6 +25,7 @@ options.reset_type = "asynchronous";
options.target_interconnect = "wb-classic";
options.register_data_output = false;
options.lang = "vhdl";
options.c_reg_style = "struct";
require "alt_getopt"
......@@ -37,6 +38,8 @@ local commands_string = [[options:
-h, --help Show this help text
-l, --lang=LANG Set the output Hardware Description Language (HDL) to LANG
Valid values for LANG: {vhdl,verilog}
-s, --cstyle=STYLE Set the style of register bank in generated C headers
Valid values for STYLE: {struct, defines}
-K, --constco=FILE Populate FILE with Verilog output (mainly constants)
-v, --version Show version information
-V, --vo=FILE Write the slave's generated HDL code to FILE
......@@ -62,11 +65,12 @@ function parse_args(arg)
constco = "K",
lang = "l",
vo = "V",
cstyle = "s"
}
local optarg
local optind
optarg,optind = alt_getopt.get_opts (arg, "hvC:D:K:l:V:", long_opts)
optarg,optind = alt_getopt.get_opts (arg, "hvC:D:K:l:V:s:", long_opts)
for key,value in pairs (optarg) do
if key == "h" then
usage_complete()
......@@ -91,6 +95,12 @@ function parse_args(arg)
die("Unknown HDL: "..options.lang);
end
elseif key == "s" then
options.c_reg_style = value;
if (options.c_reg_style ~= "struct" and options.c_reg_style ~= "defines") then
die("Unknown C RegBank style: "..options.c_reg_style);
end
elseif key == "V" then
options.output_hdl_file = value
end
......
......@@ -622,6 +622,18 @@ function gen_hdl_code_passthrough(field, reg)
end
function gen_hdl_code_constant(field, reg)
local prefix = gen_hdl_field_prefix(field, reg);
if(field.value == nil) then
die("No value defined for CONSTANT field '"..field.name.."'.");
end
field.ports = {};
field.acklen = 1;
field.read_code = { va(vir("rddata_reg", field), field.value ); };
end
-- generates code which loads data unused bits of data output register with Xs
function fill_unused_bits(target, reg)
local t={};
......@@ -629,7 +641,7 @@ function fill_unused_bits(target, reg)
local all_wo = true;
foreach_subfield(reg, function(field, reg)
if(field.type == SLV or field.type == SIGNED or field.type == UNSIGNED) then
if(field.type == SLV or field.type == SIGNED or field.type == UNSIGNED or field.type == CONSTANT) then
for i=field.offset, (field.offset+field.size-1) do t[i] = 1; end
elseif(field.type == BIT or field.type == MONOSTABLE) then
t[field.offset] = 1;
......@@ -666,7 +678,10 @@ function gen_hdl_code_reg_field(field, reg)
gen_hdl_code_slv(field, reg);
elseif(field.type == PASS_THROUGH) then
gen_hdl_code_passthrough(field, reg);
elseif(field.type == CONSTANT) then
gen_hdl_code_constant(field, reg);
end
end
-- generates VHDL for single register
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment