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 @@ ...@@ -19,7 +19,7 @@
-- --
function cgen_c_field_define(field, reg) function cgen_c_field_define(field, reg)
local prefix; local prefix;
-- anonymous field?
if(field.c_prefix == nil) then if(field.c_prefix == nil) then
return ; return ;
else else
...@@ -30,18 +30,18 @@ function cgen_c_field_define(field, reg) ...@@ -30,18 +30,18 @@ function cgen_c_field_define(field, reg)
emit(""); emit("");
emit("/* definitions for field: "..field.name.." in reg: "..reg.name.." */"); 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 if(field.type == BIT or field.type == MONOSTABLE) then
emit(string.format("%-45s %s", "#define "..prefix, "WBGEN2_GEN_MASK("..field.offset..", 1)")); emit(string.format("%-45s %s", "#define "..prefix, "WBGEN2_GEN_MASK("..field.offset..", 1)"));
else 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 %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 %d", "#define "..prefix.."_SHIFT", field.offset));
emit(string.format("%-45s %s", "#define "..prefix.."_W(value)", "WBGEN2_GEN_WRITE(value, "..field.offset..", "..field.size..")")); 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 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..")")); emit(string.format("%-45s %s", "#define "..prefix.."_R(reg)", "WBGEN2_SIGN_EXTEND(WBGEN2_GEN_READ(reg, "..field.offset..", "..field.size.."), "..field.size..")"));
else else
...@@ -129,7 +129,7 @@ function cgen_c_struct() ...@@ -129,7 +129,7 @@ function cgen_c_struct()
end end
end end
-- emit the structure definition... -- emit the structure definition...
emit(""); emit("");
emit("PACKED struct "..string.upper(periph.c_prefix).."_WB {"); emit("PACKED struct "..string.upper(periph.c_prefix).."_WB {");
indent_right(); indent_right();
...@@ -137,7 +137,7 @@ function cgen_c_struct() ...@@ -137,7 +137,7 @@ function cgen_c_struct()
-- emit struct entires for REGs -- emit struct entires for REGs
foreach_reg({TYPE_REG}, function(reg) 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); pad_struct(reg.base);
emit(string.format("/* [0x%x]: REG "..reg.name.." */", reg.base * DATA_BUS_WIDTH / 8)); emit(string.format("/* [0x%x]: REG "..reg.name.." */", reg.base * DATA_BUS_WIDTH / 8));
...@@ -181,13 +181,27 @@ function cgen_c_struct() ...@@ -181,13 +181,27 @@ function cgen_c_struct()
end 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. -- main C code generator function. Takes the peripheral definition and generates C code.
function cgen_generate_c_header_code() function cgen_generate_c_header_code()
cgen_new_snippet(); cgen_new_snippet();
cgen_c_fileheader(); cgen_c_fileheader();
cgen_c_field_masks(); cgen_c_field_masks();
if(options.c_regs_style == "struct") then
cgen_c_struct(); cgen_c_struct();
else
cgen_c_defines();
end
emit("#endif"); emit("#endif");
cgen_write_current_snippet(); cgen_write_current_snippet();
......
...@@ -49,6 +49,7 @@ PASS_THROUGH = 0x40; ...@@ -49,6 +49,7 @@ PASS_THROUGH = 0x40;
INTEGER = 0x80; INTEGER = 0x80;
EXPRESSION = 0x100; EXPRESSION = 0x100;
UNDEFINED = 0x200; UNDEFINED = 0x200;
CONSTANT = 0x400;
-- reg LOAD types -- reg LOAD types
LOAD_INT = 1; LOAD_INT = 1;
...@@ -308,6 +309,7 @@ function fix_access(field, reg) ...@@ -308,6 +309,7 @@ function fix_access(field, reg)
default_access(field, MONOSTABLE, WRITE_ONLY, READ_ONLY); default_access(field, MONOSTABLE, WRITE_ONLY, READ_ONLY);
default_access(field, ENUM, READ_WRITE, READ_ONLY); default_access(field, ENUM, READ_WRITE, READ_ONLY);
default_access(field, PASS_THROUGH, WRITE_ONLY, READ_ONLY); default_access(field, PASS_THROUGH, WRITE_ONLY, READ_ONLY);
default_access(field, CONSTANT, READ_ONLY, WRITE_ONLY);
if(field.access ~= nil) then if(field.access ~= nil) then
return; return;
......
...@@ -25,6 +25,7 @@ options.reset_type = "asynchronous"; ...@@ -25,6 +25,7 @@ options.reset_type = "asynchronous";
options.target_interconnect = "wb-classic"; options.target_interconnect = "wb-classic";
options.register_data_output = false; options.register_data_output = false;
options.lang = "vhdl"; options.lang = "vhdl";
options.c_reg_style = "struct";
require "alt_getopt" require "alt_getopt"
...@@ -37,6 +38,8 @@ local commands_string = [[options: ...@@ -37,6 +38,8 @@ local commands_string = [[options:
-h, --help Show this help text -h, --help Show this help text
-l, --lang=LANG Set the output Hardware Description Language (HDL) to LANG -l, --lang=LANG Set the output Hardware Description Language (HDL) to LANG
Valid values for LANG: {vhdl,verilog} 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) -K, --constco=FILE Populate FILE with Verilog output (mainly constants)
-v, --version Show version information -v, --version Show version information
-V, --vo=FILE Write the slave's generated HDL code to FILE -V, --vo=FILE Write the slave's generated HDL code to FILE
...@@ -62,11 +65,12 @@ function parse_args(arg) ...@@ -62,11 +65,12 @@ function parse_args(arg)
constco = "K", constco = "K",
lang = "l", lang = "l",
vo = "V", vo = "V",
cstyle = "s"
} }
local optarg local optarg
local optind 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 for key,value in pairs (optarg) do
if key == "h" then if key == "h" then
usage_complete() usage_complete()
...@@ -91,6 +95,12 @@ function parse_args(arg) ...@@ -91,6 +95,12 @@ function parse_args(arg)
die("Unknown HDL: "..options.lang); die("Unknown HDL: "..options.lang);
end 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 elseif key == "V" then
options.output_hdl_file = value options.output_hdl_file = value
end end
......
...@@ -622,6 +622,18 @@ function gen_hdl_code_passthrough(field, reg) ...@@ -622,6 +622,18 @@ function gen_hdl_code_passthrough(field, reg)
end 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 -- generates code which loads data unused bits of data output register with Xs
function fill_unused_bits(target, reg) function fill_unused_bits(target, reg)
local t={}; local t={};
...@@ -629,7 +641,7 @@ function fill_unused_bits(target, reg) ...@@ -629,7 +641,7 @@ function fill_unused_bits(target, reg)
local all_wo = true; local all_wo = true;
foreach_subfield(reg, function(field, reg) 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 for i=field.offset, (field.offset+field.size-1) do t[i] = 1; end
elseif(field.type == BIT or field.type == MONOSTABLE) then elseif(field.type == BIT or field.type == MONOSTABLE) then
t[field.offset] = 1; t[field.offset] = 1;
...@@ -666,7 +678,10 @@ function gen_hdl_code_reg_field(field, reg) ...@@ -666,7 +678,10 @@ function gen_hdl_code_reg_field(field, reg)
gen_hdl_code_slv(field, reg); gen_hdl_code_slv(field, reg);
elseif(field.type == PASS_THROUGH) then elseif(field.type == PASS_THROUGH) then
gen_hdl_code_passthrough(field, reg); gen_hdl_code_passthrough(field, reg);
elseif(field.type == CONSTANT) then
gen_hdl_code_constant(field, reg);
end end
end end
-- generates VHDL for single register -- 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