Commit 8003bae5 authored by twlostow's avatar twlostow

Alpha FIFO support added

git-svn-id: http://svn.ohwr.org/wishbone-gen@13 4537843c-45c2-4d80-8546-c3283569414f
parent 67939682
This is the initial version of wbgen2. Requires Lua 5.1.4+. Enjoy it :) This is the initial version of wbgen2. Requires Lua 5.1.4+. Enjoy it :)
Compilation instructions:
Just type "make" in the main directory of wbgen2. The resulting file will be "wbgen2".
There is still some stuff to do: There is still some stuff to do:
- add FIFOs - add FIFO register support
- add documentation generator - CONSTANT registers
- CONSTANT registers - Verilog primitive library
\ No newline at end of file \ No newline at end of file
...@@ -36,7 +36,6 @@ function cgen_c_field_define(field, reg) ...@@ -36,7 +36,6 @@ function cgen_c_field_define(field, reg)
else else
-- SLV/signed/unsigned fields: emit masks, shifts and access macros -- SLV/signed/unsigned fields: emit masks, shifts and access macros
print(field.offset, field.size);
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));
...@@ -65,6 +64,7 @@ end ...@@ -65,6 +64,7 @@ end
-- iterates all regs and rams and generates appropriate #define-s -- iterates all regs and rams and generates appropriate #define-s
function cgen_c_field_masks() function cgen_c_field_masks()
foreach_reg({TYPE_REG}, function(reg) foreach_reg({TYPE_REG}, function(reg)
dbg("DOCREG: ", reg.name, reg.num_fields);
if(reg.num_fields ~= nil and reg.num_fields > 0) then if(reg.num_fields ~= nil and reg.num_fields > 0) then
emit(""); emit("");
emit("/* definitions for register: "..reg.name.." */"); emit("/* definitions for register: "..reg.name.." */");
......
...@@ -252,7 +252,7 @@ function cgen_build_siglist() ...@@ -252,7 +252,7 @@ function cgen_build_siglist()
table_join(siglist, global_signals); table_join(siglist, global_signals);
for i,v in pairs(siglist) do for i,v in pairs(siglist) do
print("SIGNAL: ", v.name); dbg("SIGNAL: ", v.name);
end end
return siglist; return siglist;
......
...@@ -74,52 +74,64 @@ function htable_frame(tbl, r,c1,c2) ...@@ -74,52 +74,64 @@ function htable_frame(tbl, r,c1,c2)
end end
function htable_emit(tbl) function htable_emit(tbl)
emit("<table cellpadding=0 cellspacing=0 border=0>"); emit("<table cellpadding=0 cellspacing=0 border=0>");
for i = 1, tbl.rows do for i = 1, tbl.rows do
if(tbl.data[i].is_header ~= nil) then
tag = "th";
if(tbl.data[i].is_header ~= nil) then else
tag = "th"; tag = "td";
else end
tag = "td";
end if(tbl.data[i].style ~= nil) then
emit('<tr class="'..tbl.data[i].style..'">');
if(tbl.data[i].style ~= nil) then emit('<tr class="'..tbl.data[i].style..'">'); else emit('<tr>'); end else
for j=1,tbl.cols do emit('<tr>');
local extra = ""; end
for j=1,tbl.cols do
if(tbl.data[i][j].extra ~= nil) then extra = tbl.data[i][j].extra; end local extra = "";
if(tbl.data[i][j].colspan ~= nil) then extra = extra..' colspan='..tbl.data[i][j].colspan..' '; end
if(tbl.data[i][j].extra ~= nil) then
if(tbl.data[i][j].style ~= nil) then emit('<'..tag..' '..extra..' class="'..tbl.data[i][j].style..'">'); else emit('<'..tag..'>'); end extra = tbl.data[i][j].extra;
emit(tbl.data[i][j].text); end
emit('</'..tag..'>');
end if(tbl.data[i][j].colspan ~= nil) then
emit("</tr>"); extra = extra..' colspan='..tbl.data[i][j].colspan..' ';
end end
emit("</table>");
if(tbl.data[i][j].style ~= nil) then
emit('<'..tag..' '..extra..' class="'..tbl.data[i][j].style..'">');
else
emit('<'..tag..' '..extra..'>');
end
emit(tbl.data[i][j].text);
emit('</'..tag..'>');
end
emit("</tr>");
end
emit("</table>");
end end
function has_any_ports(reg) function has_any_ports(reg)
local has = false; local has = false;
if(reg.ports ~= nil) then return true; end if(reg.ports ~= nil) then return true; end
foreach_subfield(reg, function(field) if (field.ports ~= nil) then has = true; end end); foreach_subfield(reg, function(field) if (field.ports ~= nil) then has = true; end end);
return has; return has;
end end
function htable_add_row(tbl, r) function htable_add_row(tbl, r)
if(r>tbl.rows) then if(r>tbl.rows) then
for i=tbl.rows+1,r do for i=tbl.rows+1,r do
tbl.data[i]={}; tbl.data[i]={};
for j=1,tbl.cols do for j=1,tbl.cols do
tbl.data[i][j] = {}; tbl.data[i][j] = {};
tbl.data[i][j].text = ""; tbl.data[i][j].text = "";
end end
end end
tbl.rows=r; tbl.rows=r;
end end
end end
...@@ -189,6 +201,7 @@ function cgen_doc_hdl_symbol() ...@@ -189,6 +201,7 @@ function cgen_doc_hdl_symbol()
foreach_reg(ALL_REG_TYPES, function(reg) foreach_reg(ALL_REG_TYPES, function(reg)
if(has_any_ports(reg)) then if(has_any_ports(reg)) then
dbg("HasAnyPorts: ",reg.name);
table.insert(ports, reg.name); table.insert(ports, reg.name);
if(reg.ports ~= nil) then if(reg.ports ~= nil) then
...@@ -339,7 +352,12 @@ function cgen_doc_memmap() ...@@ -339,7 +352,12 @@ function cgen_doc_memmap()
row[1].style = "td_code"; row[1].style = "td_code";
row[1].text = string.format("0x%x", reg.base); row[1].text = string.format("0x%x", reg.base);
row[2].text = "REG";
if(reg.doc_is_fiforeg == nil) then
row[2].text = "REG";
else
row[2].text = "FIFOREG";
end
row[3].text = hlink("#"..string.upper(reg.c_prefix), reg.name); row[3].text = hlink("#"..string.upper(reg.c_prefix), reg.name);
row[4].style = "td_code"; row[4].style = "td_code";
...@@ -389,7 +407,8 @@ function cgen_doc_fieldtable(reg, bitoffs) ...@@ -389,7 +407,8 @@ function cgen_doc_fieldtable(reg, bitoffs)
local td_width = 70; local td_width = 70;
local tbl; local tbl;
local n= 1; local n= 1;
local cellidx = 1;
tbl= htable_new(2,8); tbl= htable_new(2,8);
...@@ -403,6 +422,7 @@ function cgen_doc_fieldtable(reg, bitoffs) ...@@ -403,6 +422,7 @@ function cgen_doc_fieldtable(reg, bitoffs)
while (bit >= bitoffs) do while (bit >= bitoffs) do
local f = find_field_by_offset(reg, bit); local f = find_field_by_offset(reg, bit);
if(f == nil) then if(f == nil) then
tbl.data[2][n].style = "td_unused"; tbl.data[2][n].style = "td_unused";
tbl.data[2][n].text = "-"; tbl.data[2][n].text = "-";
...@@ -417,7 +437,10 @@ function cgen_doc_fieldtable(reg, bitoffs) ...@@ -417,7 +437,10 @@ function cgen_doc_fieldtable(reg, bitoffs)
end end
local ncells = (bit - fend) + 1; local ncells = (bit - fend) + 1;
if(ncells > 1) then tbl.data[2][n].colspan = ncells; end dbg("ncells: ",ncells,"bit: ", bit, "name: ",f.prefix);
tbl.data[2][n].colspan = ncells;
local prefix; local prefix;
...@@ -427,16 +450,12 @@ function cgen_doc_fieldtable(reg, bitoffs) ...@@ -427,16 +450,12 @@ function cgen_doc_fieldtable(reg, bitoffs)
tbl.data[2][n].style = "td_field"; tbl.data[2][n].style = "td_field";
tbl.data[2][n].text = csel(f.size>1, string.format("%s[%d:%d]", string.upper(prefix), bit-f.offset, fend-f.offset), string.upper(prefix)); tbl.data[2][n].text = csel(f.size>1, string.format("%s[%d:%d]", string.upper(prefix), bit-f.offset, fend-f.offset), string.upper(prefix));
htable_frame(tbl, 2, cellidx); htable_frame(tbl, 2, n);
bit = bit - ncells; bit = bit - ncells;
n=n+ncells; n=n+1;
end end
cellidx = cellidx + 1;
end end
htable_emit(tbl); htable_emit(tbl);
......
...@@ -87,7 +87,7 @@ function cgen_vhdl_entity() ...@@ -87,7 +87,7 @@ function cgen_vhdl_entity()
-- generate code for the port -- generate code for the port
local line = string.format("%-40s : %-6s %s", port.name, port.dir, fieldtype_2_vhdl[port.type]); local line = string.format("%-40s : %-6s %s", port.name, port.dir, fieldtype_2_vhdl[port.type]);
if(port.range > 0) then if(port.range > 1) then
line = line.."("..(port.range-1).." downto 0)"; line = line.."("..(port.range-1).." downto 0)";
end end
...@@ -113,7 +113,7 @@ function cgen_vhdl_entity() ...@@ -113,7 +113,7 @@ function cgen_vhdl_entity()
-- we do it the same way as for the ports. -- we do it the same way as for the ports.
for i,v in pairs (g_siglist) do for i,v in pairs (g_siglist) do
s=string.format("signal %-40s : %-15s", v.name, fieldtype_2_vhdl[v.type]); s=string.format("signal %-40s : %-15s", v.name, fieldtype_2_vhdl[v.type]);
if(v.range > 0) then if(v.range > 0 and v.type ~= BIT) then
s=s..string.format("(%d downto 0)", v.range-1); s=s..string.format("(%d downto 0)", v.range-1);
end end
s=s..";"; s=s..";";
...@@ -310,7 +310,9 @@ function cgen_generate_vhdl_code(tree) ...@@ -310,7 +310,9 @@ function cgen_generate_vhdl_code(tree)
return "open"; return "open";
end end
if(t.h ~= nil and t.l == nil) then --print("gensub: ", t.name);
if (t.h ~= nil and ( t.l == nil or (t.l == t.h))) then
return t.name.."("..t.h..")"; return t.name.."("..t.h..")";
elseif(t.h ~= nil and t.l ~= nil) then elseif(t.h ~= nil and t.l ~= nil) then
return t.name.."("..t.h.." downto "..t.l..")"; return t.name.."("..t.h.." downto "..t.l..")";
...@@ -335,6 +337,9 @@ function cgen_generate_vhdl_code(tree) ...@@ -335,6 +337,9 @@ function cgen_generate_vhdl_code(tree)
-- generates a VHDL type-conversion code for assignment between tsd (destination node) and tss (source node). -- generates a VHDL type-conversion code for assignment between tsd (destination node) and tss (source node).
function gen_vhdl_typecvt(tsd, tss) function gen_vhdl_typecvt(tsd, tss)
-- print("Gen_typecvt:", tsd.name);
-- print("Gen_typecvt:", tss.name, tss.type);
-- types match? Coool, we have nothing to do -- types match? Coool, we have nothing to do
if(tsd.type == tss.type) then if(tsd.type == tss.type) then
return(gen_subrange(tss)); return(gen_subrange(tss));
...@@ -358,7 +363,7 @@ function cgen_generate_vhdl_code(tree) ...@@ -358,7 +363,7 @@ function cgen_generate_vhdl_code(tree)
elseif (tss.type == BIT) then elseif (tss.type == BIT) then
if(tsd.type == SLV) then if(tsd.type == SLV) then
return(gen_subrange(tss.name)); return(gen_subrange(tss));
else die ("unsupported assignment: "..tsd.name.." "..tss.name); end else die ("unsupported assignment: "..tsd.name.." "..tss.name); end
elseif (tss.type == SIGNED or tss.type == UNSIGNED) then elseif (tss.type == SIGNED or tss.type == UNSIGNED) then
...@@ -366,7 +371,7 @@ function cgen_generate_vhdl_code(tree) ...@@ -366,7 +371,7 @@ function cgen_generate_vhdl_code(tree)
-- dest: slv <= src: signed/unsigned -- dest: slv <= src: signed/unsigned
if(tsd.type == SLV) then if(tsd.type == SLV) then
return("std_logic_vector("..gen_subrange(tss)..")"); return("std_logic_vector("..gen_subrange(tss)..")");
else die ("unsupported assignment: "..tsd.name.." "..tss.name); end else die ("unsupported assignment: "..tsd.name.." "..tss.name); end
elseif (tss.type == SLV) then elseif (tss.type == SLV) then
...@@ -376,8 +381,11 @@ function cgen_generate_vhdl_code(tree) ...@@ -376,8 +381,11 @@ function cgen_generate_vhdl_code(tree)
elseif (tsd.type == UNSIGNED) then elseif (tsd.type == UNSIGNED) then
-- print(tss); -- print(tss);
return("unsigned("..gen_subrange(tss)..")"); return("unsigned("..gen_subrange(tss)..")");
else die ("unsupported assignment: "..tsd.name.." "..tss.name); end elseif (tsd.type == BIT) then
return gen_subrange(tss);
else
die ("unsupported assignment: "..tsd.name.." "..tss.name); end
else die ("unsupported assignment: "..tsd.name.." "..tss.name); end else die ("unsupported assignment: "..tsd.name.." "..tss.name); end
end end
...@@ -387,6 +395,8 @@ function cgen_generate_vhdl_code(tree) ...@@ -387,6 +395,8 @@ function cgen_generate_vhdl_code(tree)
local tsd = node_typesize(node.dst); local tsd = node_typesize(node.dst);
local tss = node_typesize(node.src); local tss = node_typesize(node.src);
-- print(tsd.name);
-- source node is an expression? - recurse it -- source node is an expression? - recurse it
if(tss.type == EXPRESSION) then if(tss.type == EXPRESSION) then
emiti(); emiti();
...@@ -396,7 +406,6 @@ function cgen_generate_vhdl_code(tree) ...@@ -396,7 +406,6 @@ function cgen_generate_vhdl_code(tree)
emitx(";\n"); emitx(";\n");
else else
-- not an expression? - assign the destination with proper type casting. -- not an expression? - assign the destination with proper type casting.
-- print(gen_subrange(tsd));
emit(gen_subrange(tsd).." <= "..gen_vhdl_typecvt(tsd, tss)..";"); emit(gen_subrange(tsd).." <= "..gen_vhdl_typecvt(tsd, tss)..";");
end end
end end
...@@ -473,7 +482,7 @@ function cgen_generate_vhdl_code(tree) ...@@ -473,7 +482,7 @@ function cgen_generate_vhdl_code(tree)
-- --
function cgen_vhdl_comment(node) function cgen_vhdl_comment(node)
print("COMMENT: "..node.str); -- print("COMMENT: "..node.str);
emitx("-- "..node.str.."\n"); emitx("-- "..node.str.."\n");
end end
...@@ -608,7 +617,7 @@ function cgen_generate_vhdl_code(tree) ...@@ -608,7 +617,7 @@ function cgen_generate_vhdl_code(tree)
["openpin"] = cgen_vhdl_openpin; ["openpin"] = cgen_vhdl_openpin;
}; };
-- print(node); -- print(node);
for i,v in pairs(node) do for i,v in pairs(node) do
-- no type? probably just a block of code. recurse it deeper. -- no type? probably just a block of code. recurse it deeper.
......
-- -*- Mode: LUA; tab-width: 2 -*-
peripheral {
name ="FIFO test";
prefix="ft";
hdl_entity="wb_test_fifos";
fifo_reg {
size = 256;
direction = CORE_TO_BUS;
prefix = "tsf";
name = "Timestamp FIFO";
description = "This FIFO holds the TX packet timestamps gathered from all switch endpoints";
flags_bus = {FIFO_FULL, FIFO_EMPTY, FIFO_COUNT};
flags_dev = {FIFO_FULL, FIFO_EMPTY, FIFO_COUNT};
field {
name = "Timestamp value taken on rising clock edge (full word)";
prefix = "val_r";
type = SLV;
size = 28;
};
field {
name = "Timestamp value taken on falling clock edge (few LSBs)";
prefix = "val_f";
type = SLV;
size = 4;
};
field {
name ="Physical port ID";
prefix = "pid";
type = SLV;
size = 5;
align= 16;
};
field {
name = "Frame ID";
prefix = "fid";
type = SLV;
size = 16;
align = 16;
};
};
fifo_reg {
size = 32;
direction = BUS_TO_CORE;
prefix = "memacc";
name = "Memory Access FIFO";
flags_bus = {FIFO_FULL, FIFO_EMPTY, FIFO_COUNT};
flags_dev = {FIFO_FULL, FIFO_EMPTY, FIFO_COUNT};
field {
name = "Memory address/data select";
description = "0: current entry contains memory address value (auto-incremented at each write)\
1: current entry contains data word to be written to memory at previously set address";
prefix = "ad_sel";
type = BIT;
};
field {
name = "Memory address/data value";
description = "Value of data word to be written (when ad_sel = 1) or new memory address (when ad_sel = 0)";
prefix = "ad";
type = SLV;
size = 32;
};
};
};
\ No newline at end of file
set input_wb_file "fifotest.wb"
set test_module "wb_test_fifos"
set target "classic"
set lang "vhdl"
set library_files {
"../../lib/wbgen2_pkg.vhd"
"../../lib/altera/wbgen2_fifo_sync.vhd"
};
mkdir -p output
vlib work
vlib wbgen2
foreach file $library_files { vcom -work wbgen2 $file }
if { $lang == "vhdl" } {
set target_filename [format "./output/%s.vhd" $test_module ]
set target_wb "+define+WB_USE_CLASSIC"
set wbgen_opt "-target classic"
} else {
set target_filename [format "./output/%s.v" $test_module ]
set target_wb "+define+WB_USE_PIPELINED"
set wbgen_opt "-target pipelined"
}
puts $target_filename
../../wbgen2 -V $target_filename -K ./output/vlog_constants.v -C ./output/regdefs.h -D ./output/docs.html -l $lang $input_wb_file
if { $lang == "verilog" } {
vlog -work work -work wbgen2 $target_filename
} else {
vcom -work work $target_filename
}
vlog ./testbench.v
vsim work.main
radix -hexadecimal
do wave.do
run 1000us
wave zoomfull
`timescale 1ns/1ps
`include "output/vlog_constants.v"
`include "../common/wishbone_test_master.v"
`define FIFO_FULL 16
`define FIFO_EMPTY 17
module main;
reg tsf_wr_req = 0;
wire tsf_wr_full;
wire tsf_wr_empty;
wire [7:0] tsf_wr_usedw;
reg [27:0] tsf_val_r;
reg [3:0] tsf_val_f;
reg [4:0] tsf_pid;
reg [15:0] tsf_fid;
reg memacc_rd_req = 0;
wire memacc_rd_full;
wire memacc_rd_empty;
wire [4:0] memacc_rd_usedw;
wire memacc_ad_sel ;
wire [31:0] memacc_ad ;
WB_TEST_MASTER WB();
wire clk = WB.wb_clk;
wire rst = WB.wb_rst;
wb_test_fifos
dut (
.rst_n_i (WB.wb_rst),
.wb_clk_i (WB.wb_clk),
.wb_addr_i (WB.wb_addr[2:0]),
.wb_data_i (WB.wb_data_o),
.wb_data_o (WB.wb_data_i),
.wb_cyc_i (WB.wb_cyc),
.wb_sel_i (WB.wb_bwsel),
.wb_stb_i (WB.wb_stb),
.wb_we_i (WB.wb_we),
.wb_ack_o (WB.wb_ack),
.ft_tsf_wr_req_i (tsf_wr_req),
.ft_tsf_wr_full_o (tsf_wr_full),
.ft_tsf_wr_empty_o (tsf_wr_empty),
.ft_tsf_wr_usedw_o (tsf_wr_usedw),
.ft_tsf_val_r_i (tsf_val_r),
.ft_tsf_val_f_i (tsf_val_f),
.ft_tsf_pid_i (tsf_pid),
.ft_tsf_fid_i (tsf_fid),
.ft_memacc_rd_req_i (memacc_rd_req),
.ft_memacc_rd_full_o (memacc_rd_full),
.ft_memacc_rd_empty_o (memacc_rd_empty),
.ft_memacc_rd_usedw_o (memacc_rd_usedw),
.ft_memacc_ad_sel_o (memacc_ad_sel),
.ft_memacc_ad_o (memacc_ad)
);
reg [31:0] memacc_prev_addr = 'hffffffff;
task wait_fifo_flag(input [31:0] cr_addr, input [31:0] flag, input value);
begin: fifo_full_body
reg [31:0] cr_val;
WB.read32(cr_addr, cr_val);
while(cr_val[flag] != value)
WB.read32(cr_addr, cr_val);
end
endtask
// writes from the host side to MEMACC fifo
task memacc_write( input [31:0] address,
input [31:0] data);
begin
if(memacc_prev_addr + 1 != address)
begin
wait_fifo_flag(`ADDR_FT_MEMACC_CSR, `FIFO_FULL, 0);
WB.write32(`ADDR_FT_MEMACC_R0, 0);
WB.write32(`ADDR_FT_MEMACC_R1, address);
end
wait_fifo_flag(`ADDR_FT_MEMACC_CSR, `FIFO_FULL, 0);
WB.write32(`ADDR_FT_MEMACC_R0, 1);
WB.write32(`ADDR_FT_MEMACC_R1, data);
memacc_prev_addr = address;
end
endtask // UNMATCHED !!
task ts_fifo_write
(
input [27:0] value_r,
input [3:0] value_f,
input [4:0] pid,
input [15:0] fid);
begin
while(tsf_wr_full) @(posedge clk);
tsf_val_r <= value_r;
tsf_val_f <= value_f;
tsf_pid <= pid;
tsf_fid <= fid;
tsf_wr_req = 1;
@(posedge clk);
tsf_wr_req = 0;
end
endtask // ts_fifo_write
task ts_fifo_read ( output [27:0] value_r,
output [3:0] value_f,
output [4:0] pid,
output [15:0] fid);
begin : TS_FIFO_READ_BODY
reg [31:0] rval;
wait_fifo_flag(`ADDR_FT_TSF_CSR, `FIFO_EMPTY, 0);
WB.read32(`ADDR_FT_TSF_R0, rval);
value_f = rval[31:28];
value_r = rval[27:0];
WB.read32(`ADDR_FT_TSF_R1, rval);
fid = rval[31:16];
pid = rval[4:0];
end
endtask // ts_fifo_read
integer i;
integer rd_val_f, rd_val_r, rd_pid, rd_fid;
initial begin
wait (WB.ready);
WB.monitor_bus(0);
WB.verbose(0);
for(i=0;i<100;i=i+1) memacc_write(i, 3*i);
for(i=0;i<300;i=i+1) begin
ts_fifo_read(rd_val_r, rd_val_f, rd_pid, rd_fid);
$display("TS FIFO READ: val_f %d val_r %d pid %d fid %d", rd_val_f, rd_val_r, rd_pid, rd_fid);
end
end
// MEMACC FIFO data sink
always @(memacc_rd_empty)
memacc_rd_req <= ~memacc_rd_empty;
reg memacc_rd_d0 = 0;
reg [31:0] memacc_addr = 0;
always @(posedge clk) begin
memacc_rd_d0 <= memacc_rd_req;
if(memacc_rd_d0) begin
if(!memacc_ad_sel) begin
$display("MEMACC_SetAddress: %x", memacc_ad);
memacc_addr <= memacc_ad;
end else begin
$display("MEMACC_Write: addr %x data %x", memacc_addr, memacc_ad);
memacc_addr <= memacc_addr + 1;
end
end
end
// write some data to the timestamping FIFO
integer j;
initial begin
wait(WB.ready);
for(j=0;j<300;j=j+1)
ts_fifo_write(j, j+10, j+20, j+30);
end
endmodule
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -format Logic /main/tsf_wr_req
add wave -noupdate -format Logic /main/tsf_wr_full
add wave -noupdate -format Logic /main/tsf_wr_empty
add wave -noupdate -format Literal /main/tsf_wr_usedw
add wave -noupdate -format Literal /main/tsf_val_r
add wave -noupdate -format Literal /main/tsf_val_f
add wave -noupdate -format Literal /main/tsf_pid
add wave -noupdate -format Literal /main/tsf_fid
add wave -noupdate -format Logic /main/memacc_rd_req
add wave -noupdate -format Logic /main/memacc_rd_full
add wave -noupdate -format Logic /main/memacc_rd_empty
add wave -noupdate -format Literal /main/memacc_rd_usedw
add wave -noupdate -format Logic /main/memacc_ad_sel
add wave -noupdate -format Literal /main/memacc_ad
add wave -noupdate -format Logic /main/clk
add wave -noupdate -format Logic /main/rst
add wave -noupdate -format Logic /main/dut/ft_memacc_inst/wr_req_i
add wave -noupdate -format Literal /main/dut/ft_tsf_inst/rd_data_o
add wave -noupdate -format Logic /main/dut/ft_tsf_inst/rd_req_i
add wave -noupdate -format Logic /main/dut/ft_tsf_inst/rd_empty_o
add wave -noupdate -format Logic /main/dut/ft_tsf_inst/rd_full_o
add wave -noupdate -format Literal /main/dut/ft_tsf_inst/rd_usedw_o
add wave -noupdate -format Logic /main/dut/ft_tsf_rdreq_int
add wave -noupdate -format Logic /main/dut/ft_tsf_rdreq_int_d0
add wave -noupdate -format Literal /main/WB/wb_addr
add wave -noupdate -format Literal /main/WB/wb_data_o
add wave -noupdate -format Literal /main/WB/wb_bwsel
add wave -noupdate -format Literal /main/WB/wb_data_i
add wave -noupdate -format Logic /main/WB/wb_ack
add wave -noupdate -format Logic /main/WB/wb_cyc
add wave -noupdate -format Logic /main/WB/wb_stb
add wave -noupdate -format Logic /main/WB/wb_we
add wave -noupdate -format Logic /main/WB/wb_rst
add wave -noupdate -format Logic /main/WB/wb_clk
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {61000000 ps} 0}
configure wave -namecolwidth 288
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 0
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
update
WaveRestoreZoom {57718750 ps} {64281250 ps}
...@@ -23,9 +23,14 @@ entity wbgen2_fifo_sync is ...@@ -23,9 +23,14 @@ entity wbgen2_fifo_sync is
rd_data_o : out std_logic_vector(g_width-1 downto 0); rd_data_o : out std_logic_vector(g_width-1 downto 0);
rd_req_i : in std_logic; rd_req_i : in std_logic;
empty_o : out std_logic; wr_empty_o : out std_logic;
full_o : out std_logic; wr_full_o : out std_logic;
usedw_o : out std_logic_vector(g_usedw_size-1 downto 0) wr_usedw_o : out std_logic_vector(g_usedw_size -1 downto 0);
rd_empty_o : out std_logic;
rd_full_o : out std_logic;
rd_usedw_o : out std_logic_vector(g_usedw_size -1 downto 0)
); );
end wbgen2_fifo_sync; end wbgen2_fifo_sync;
...@@ -46,7 +51,7 @@ architecture rtl of wbgen2_fifo_sync is ...@@ -46,7 +51,7 @@ architecture rtl of wbgen2_fifo_sync is
use_eab : string use_eab : string
); );
port ( port (
usedw : out std_logic_vector (7 downto 0); usedw : out std_logic_vector (g_usedw_size-1 downto 0);
rdreq : in std_logic; rdreq : in std_logic;
empty : out std_logic; empty : out std_logic;
clock : in std_logic; clock : in std_logic;
...@@ -57,6 +62,10 @@ architecture rtl of wbgen2_fifo_sync is ...@@ -57,6 +62,10 @@ architecture rtl of wbgen2_fifo_sync is
); );
end component; end component;
signal empty_int, full_int : std_logic;
signal usedw_int : std_logic_vector(g_usedw_size -1 downto 0);
begin begin
scfifo_component : scfifo scfifo_component : scfifo
...@@ -77,10 +86,19 @@ begin ...@@ -77,10 +86,19 @@ begin
clock => clk_i, clock => clk_i,
wrreq => wr_req_i, wrreq => wr_req_i,
data => wr_data_i, data => wr_data_i,
usedw => usedw_o, usedw => usedw_int,
empty => empty_o, empty => empty_int,
q => rd_data_o, q => rd_data_o,
full => full_o full => full_int
); );
rd_empty_o <= empty_int;
rd_full_o <= full_int;
rd_usedw_o <= usedw_int;
wr_empty_o <= empty_int;
wr_full_o <= full_int;
wr_usedw_o <= usedw_int;
end rtl; end rtl;
...@@ -30,25 +30,6 @@ package wbgen2_pkg is ...@@ -30,25 +30,6 @@ package wbgen2_pkg is
wr_b_i : in std_logic); wr_b_i : in std_logic);
end component; end component;
component wbgen2_fifo_async
generic (
g_size : integer;
g_width : integer;
g_usedw_size : integer);
port (
rd_clk_i : in std_logic;
rd_req_i : in std_logic;
rd_data_o : out std_logic_vector(g_width-1 downto 0);
rd_empty_o : out std_logic;
rd_full_o : out std_logic;
rd_usedw_o : out std_logic_vector(g_usedw_size -1 downto 0);
wr_clk_i : in std_logic;
wr_req_i : in std_logic;
wr_data_i : in std_logic_vector(g_width-1 downto 0);
wr_empty_o : out std_logic;
wr_full_o : out std_logic;
wr_usedw_o : out std_logic_vector(g_usedw_size -1 downto 0));
end component;
component wbgen2_eic component wbgen2_eic
generic ( generic (
...@@ -99,5 +80,45 @@ package wbgen2_pkg is ...@@ -99,5 +80,45 @@ package wbgen2_pkg is
reg_isr_wr_stb_i : in std_logic; reg_isr_wr_stb_i : in std_logic;
wb_irq_o : out std_logic); wb_irq_o : out std_logic);
end component; end component;
component wbgen2_fifo_async
generic (
g_size : integer;
g_width : integer;
g_usedw_size : integer);
port (
rd_clk_i : in std_logic;
rd_req_i : in std_logic;
rd_data_o : out std_logic_vector(g_width-1 downto 0);
rd_empty_o : out std_logic;
rd_full_o : out std_logic;
rd_usedw_o : out std_logic_vector(g_usedw_size -1 downto 0);
wr_clk_i : in std_logic;
wr_req_i : in std_logic;
wr_data_i : in std_logic_vector(g_width-1 downto 0);
wr_empty_o : out std_logic;
wr_full_o : out std_logic;
wr_usedw_o : out std_logic_vector(g_usedw_size -1 downto 0));
end component;
component wbgen2_fifo_sync
generic (
g_width : integer;
g_size : integer;
g_usedw_size : integer);
port (
clk_i : in std_logic;
wr_data_i : in std_logic_vector(g_width-1 downto 0);
wr_req_i : in std_logic;
rd_data_o : out std_logic_vector(g_width-1 downto 0);
rd_req_i : in std_logic;
wr_empty_o : out std_logic;
wr_full_o : out std_logic;
wr_usedw_o : out std_logic_vector(g_usedw_size -1 downto 0);
rd_empty_o : out std_logic;
rd_full_o : out std_logic;
rd_usedw_o : out std_logic_vector(g_usedw_size -1 downto 0));
end component;
end wbgen2_pkg; end wbgen2_pkg;
...@@ -112,8 +112,11 @@ function gen_bus_logic_wishbone() ...@@ -112,8 +112,11 @@ function gen_bus_logic_wishbone()
padcode padcode
}); }; }); };
table_join(rwcode, { va(vi("ack_sreg", math.max(acklen-1, 0)), 1); } );
table_join(rwcode, { va("ack_in_progress", 1); }); if(not (reg.dont_emit_ack_code == true)) then -- we don't want the main generator to mess with ACK line for this register
table_join(rwcode, { va(vi("ack_sreg", math.max(acklen-1, 0)), 1); } );
table_join(rwcode, { va("ack_in_progress", 1); });
end
if(regbank_address_bits > 0) then if(regbank_address_bits > 0) then
rwcode = { vcase(reg.base, rwcode); }; rwcode = { vcase(reg.base, rwcode); };
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
-- some constants -- -- some constants --
-- DEBUG MACROS
VERBOSE_DEBUG = 0;
-- bus properties -- bus properties
DATA_BUS_WIDTH = 32; DATA_BUS_WIDTH = 32;
SYNC_CHAIN_LENGTH = 3; SYNC_CHAIN_LENGTH = 3;
...@@ -76,6 +79,10 @@ function enum(x) x['__type']=TYPE_ENUM; return x; end ...@@ -76,6 +79,10 @@ function enum(x) x['__type']=TYPE_ENUM; return x; end
function irq(x) x['__type']=TYPE_IRQ; return x; end function irq(x) x['__type']=TYPE_IRQ; return x; end
function dbg(...)
if(VERBOSE_DEBUG) then print(arg); end
end
-- function chceks if argument p is nil and if it is, throws fatal error message s -- function chceks if argument p is nil and if it is, throws fatal error message s
function chk_nil(p,s) function chk_nil(p,s)
if(p == nil) then if(p == nil) then
...@@ -190,25 +197,49 @@ end ...@@ -190,25 +197,49 @@ end
function calc_field_offset(field, reg) function calc_field_offset(field, reg)
-- align the field offset next to the current offset in the reg -- align the field offset next to the current offset in the reg
local ofs = reg.current_offset; local ofs = reg.current_offset;
ofs = align(field, ofs);
-- FIFOs can span multiple I/O registers.
if (reg.__type == TYPE_FIFO) then
local ofs_new = align(field, ofs);
if((ofs_new % DATA_BUS_WIDTH) + field.size > DATA_BUS_WIDTH) then
field.align = DATA_BUS_WIDTH;
ofs = align(field, ofs);
else
ofs = ofs_new;
end
reg.current_offset = ofs + field.size;
field.offset = ofs;
else
ofs = align(field, ofs);
-- update the current offset -- update the current offset
reg.current_offset = ofs + field.size; reg.current_offset = ofs + field.size;
field.offset = ofs; field.offset = ofs;
field.offset_unaligned = reg.current_offset_unaligned; end
reg.current_offset_unaligned = reg.current_offset_unaligned + field.size;
-- update the "unaligned" offset - for FIFOs
field.offset_unaligned = reg.current_offset_unaligned;
reg.current_offset_unaligned = reg.current_offset_unaligned + field.size;
-- calculate the number of fields in the register
if(reg.num_fields == nil) then reg.num_fields = 0; end
reg.num_fields = reg.num_fields + 1;
-- oops, we have too many fields (the total size exceeds the data bus width) -- oops, we have too many fields (the total size exceeds the data bus width)
if( reg.__type == TYPE_REG and reg.current_offset > DATA_BUS_WIDTH ) then if( reg.__type == TYPE_REG and reg.current_offset > DATA_BUS_WIDTH ) then
die ("Total size of register '"..reg.name.."' ("..reg.current_offset..") exceeds data bus width ("..DATA_BUS_WIDTH..")"); die ("Total size of register '"..reg.name.."' ("..reg.current_offset..") exceeds data bus width ("..DATA_BUS_WIDTH..")");
end end
end
-- calculate the number of fields in the register
function calc_num_fields(field, reg)
if(reg.num_fields == nil) then reg.num_fields = 0; end
reg.num_fields = reg.num_fields + 1;
end end
-- commits a suicide with error message "s" -- commits a suicide with error message "s"
...@@ -467,3 +498,20 @@ end ...@@ -467,3 +498,20 @@ end
function deepcopy(object)
local lookup_table = {}
local function _copy(object)
if type(object) ~= "table" then
return object
elseif lookup_table[object] then
return lookup_table[object]
end
local new_table = {}
lookup_table[object] = new_table
for index, value in pairs(object) do
new_table[_copy(index)] = _copy(value)
end
return setmetatable(new_table, getmetatable(object))
end
return _copy(object)
end
...@@ -12,6 +12,9 @@ function fifo_wire_core_ports(fifo) ...@@ -12,6 +12,9 @@ function fifo_wire_core_ports(fifo)
csel(fifo.direction == BUS_TO_CORE, "FIFO read request", "FIFO write request" )) csel(fifo.direction == BUS_TO_CORE, "FIFO read request", "FIFO write request" ))
}; };
-- wire the read/write request port
table_join(fifo.maps, { vpm (fifo.rdwr.."_req_i", prefix.."_"..fifo.rdwr.."_req_i") });
-- add full/empty/usedw ports -- add full/empty/usedw ports
if inset(FIFO_FULL, fifo.flags_dev) then if inset(FIFO_FULL, fifo.flags_dev) then
table_join(ports, { port (BIT, 0, "out", prefix.."_"..fifo.rdwr.."_full_o", "FIFO full flag") }); table_join(ports, { port (BIT, 0, "out", prefix.."_"..fifo.rdwr.."_full_o", "FIFO full flag") });
...@@ -24,9 +27,9 @@ function fifo_wire_core_ports(fifo) ...@@ -24,9 +27,9 @@ function fifo_wire_core_ports(fifo)
end end
if inset(FIFO_COUNT, fifo.flags_dev) then if inset(FIFO_COUNT, fifo.flags_dev) then
table_join(ports, { port (SLV, fifo.usedw_size, "out", prefix.."_"..fifo.rdwr.."_count_o", table_join(ports, { port (SLV, fifo.usedw_size, "out", prefix.."_"..fifo.rdwr.."_usedw_o",
"FIFO number of used words") }); "FIFO number of used words") });
table_join(fifo.maps, { vpm (fifo.rdwr.."_count_o", prefix.."_"..fifo.rdwr.."_count_o")}); table_join(fifo.maps, { vpm (fifo.rdwr.."_usedw_o", prefix.."_"..fifo.rdwr.."_usedw_o")});
end end
foreach_subfield(fifo, foreach_subfield(fifo,
...@@ -35,16 +38,19 @@ function fifo_wire_core_ports(fifo) ...@@ -35,16 +38,19 @@ function fifo_wire_core_ports(fifo)
total_size = total_size + field.size; total_size = total_size + field.size;
if(fifo.direction == BUS_TO_CORE) then -- bus -> core fifo if(fifo.direction == BUS_TO_CORE) then -- bus -> core fifo
-- generate an output port for the field
table_join(ports, {port (field.type, field.size, "out", field_pfx.."_o")}); table_join(ports, {port (field.type, field.size, "out", field_pfx.."_o")});
-- assign the output to the FIFO output port -- assign the output to the FIFO output port
-- table_join(fifo.extra_code, { table_join(fifo.extra_code, {
-- va(field_pfx.."_o", va(field_pfx.."_o",
-- vi(prefix.."_out_int", field.offset_unaligned + field.size -1, vi(prefix.."_out_int", field.offset_unaligned + field.size -1,
--- field.current_unaligned)) }); field.offset_unaligned)) });
else -- core -> bus fifo else
-- generate an input port for the field
table_join(ports, {port (field.type, field.size, "in", field_pfx.."_i")}); table_join(ports, {port (field.type, field.size, "in", field_pfx.."_i")});
-- core -> bus fifo: wire the inputs to FIFO data input
table_join(fifo.extra_code, { table_join(fifo.extra_code, {
va( va(
vi(prefix.."_in_int", field.offset_unaligned + field.size -1, vi(prefix.."_in_int", field.offset_unaligned + field.size -1,
...@@ -54,6 +60,8 @@ function fifo_wire_core_ports(fifo) ...@@ -54,6 +60,8 @@ function fifo_wire_core_ports(fifo)
end); end);
table_join(fifo.ports, ports); table_join(fifo.ports, ports);
fifo.total_size = total_size; fifo.total_size = total_size;
...@@ -66,6 +74,7 @@ function fifo_wire_bus_ports(fifo) ...@@ -66,6 +74,7 @@ function fifo_wire_bus_ports(fifo)
local fifo_dregs = {}; local fifo_dregs = {};
local i; local i;
local r;
for i=0, n_regs -1 do for i=0, n_regs -1 do
local minofs = i * DATA_BUS_WIDTH; local minofs = i * DATA_BUS_WIDTH;
...@@ -80,14 +89,18 @@ function fifo_wire_bus_ports(fifo) ...@@ -80,14 +89,18 @@ function fifo_wire_bus_ports(fifo)
fifo_dregs[i].extra_code = {}; fifo_dregs[i].extra_code = {};
fifo_dregs[i].ackgen_code= {}; fifo_dregs[i].ackgen_code= {};
print("DREG ", i); -- print("DREG ", i);
-- allocate the registers.
foreach_subfield(fifo, foreach_subfield(fifo,
function(field) function(field)
if(field.offset >= minofs and field.offset + field.size - 1 <= maxofs) then if(field.offset >= minofs and field.offset + field.size - 1 <= maxofs) then
table.insert(fifo_dregs[i], field); table.insert(fifo_dregs[i], field);
field.offset = field.offset - minofs; field.offset = field.offset - minofs;
print("FIELD: ", field.name, " OFS: ", field.offset, "SIZE: ",field.size); dbg("FIELD: ", field.name, " OFS: ", field.offset, "SIZE: ",field.size);
end end
end); end);
...@@ -101,6 +114,7 @@ function fifo_wire_bus_ports(fifo) ...@@ -101,6 +114,7 @@ function fifo_wire_bus_ports(fifo)
r.ack_len = 2; r.ack_len = 2;
r.ports = {}; r.ports = {};
r.signals = {}; r.signals = {};
r.doc_is_fiforeg = true;
if(fifo.direction == BUS_TO_CORE) then if(fifo.direction == BUS_TO_CORE) then
r.name = "FIFO '"..fifo.name.."' data input register "..i; r.name = "FIFO '"..fifo.name.."' data input register "..i;
...@@ -128,26 +142,81 @@ function fifo_wire_bus_ports(fifo) ...@@ -128,26 +142,81 @@ function fifo_wire_bus_ports(fifo)
field.access_dev = READ_ONLY; field.access_dev = READ_ONLY;
else else
field.read_code = {
va(
vi("rddata_reg", -- src
field.offset + field.size - 1,
field.offset),
vi(fifo.full_prefix.."_out_int", -- dst
field.offset_unaligned + field.size - 1,
field.offset_unaligned))
};
field.access_bus = READ_ONLY;
field.access_dev = WRITE_ONLY;
end end
end); end);
print(r.hdl_prefix, r.c_prefix, prefix);
table.insert(periph, r); table.insert(periph, r);
end end
print("lastreg: " ,r.name); dbg("lastreg: " ,r.name);
-- last register: -- last register:
if(fifo.direction == BUS_TO_CORE) then -- Last FIFO I/O register if(fifo.direction == BUS_TO_CORE) then -- Last FIFO I/O register
table_join(r.write_code, { va(fifo.full_prefix.."_wrreq_int", 1) }); table_join(r.write_code, { va(fifo.full_prefix.."_wrreq_int", 1) });
table_join(r.ackgen_code, { va(fifo.full_prefix.."_wrreq_int", 0) }); table_join(r.ackgen_code, { va(fifo.full_prefix.."_wrreq_int", 0) });
table_join(r.reset_code_main, { va(fifo.full_prefix.."_wrreq_int", 0) }); table_join(r.reset_code_main, { va(fifo.full_prefix.."_wrreq_int", 0) });
else
local r = fifo_dregs[0];
-- local old_readcode = deepcopy(r.read_code);
-- generate a delay for read request signal
table_join(r.extra_code, { vsyncprocess("bus_clock_int", "rst_n_i", {
vreset(0, {
va(fifo.full_prefix.."_rdreq_int_d0", 0)
});
vposedge ( {
va(fifo.full_prefix.."_rdreq_int_d0",fifo.full_prefix.."_rdreq_int")
});
}) });
local fields_readcode = {};
foreach_subfield(r,
function(field)
table_join(fields_readcode, field.read_code);
field.read_code = nil;
end);
table_join(r.reset_code_main, { va(fifo.full_prefix.."_rdreq_int", 0) });
r.read_code = {
vif(vequal(fifo.full_prefix.."_rdreq_int_d0", 0), {
va(fifo.full_prefix.."_rdreq_int", vnot(fifo.full_prefix.."_rdreq_int"));
}, { -- else
fields_readcode;
va("ack_in_progress", 1);
va(vi("ack_sreg", 0), 1);
})
};
r.dont_emit_ack_code = true;
end end
-- add full/empty/usedw control register -- add full/empty/usedw control register
local csr = { local csr = {
...@@ -178,8 +247,8 @@ function fifo_wire_bus_ports(fifo) ...@@ -178,8 +247,8 @@ function fifo_wire_bus_ports(fifo)
local sig = fifo.full_prefix.."_"..field_prefix.."_int"; local sig = fifo.full_prefix.."_"..field_prefix.."_int";
-- wire the FULL signal to appropriate FIFO output -- wire the FULL/EMPTY/USEDW signals to appropriate FIFO outputs
table_join(fifo.maps, { vpm (fifo.rdwr.."_"..field_prefix.."_o", sig)}); table_join(fifo.maps, { vpm (fifo.nrdwr.."_"..field_prefix.."_o", sig)});
table_join(f.signals, { signal (type, size, sig) }); table_join(f.signals, { signal (type, size, sig) });
if(type == BIT) then if(type == BIT) then
table_join(f.read_code, { va(vi("rddata_reg", f.offset), sig) }); table_join(f.read_code, { va(vi("rddata_reg", f.offset), sig) });
...@@ -188,7 +257,7 @@ function fifo_wire_bus_ports(fifo) ...@@ -188,7 +257,7 @@ function fifo_wire_bus_ports(fifo)
end end
table.insert(csr, f); table.insert(csr, f);
else else
table_join(fifo.maps, { vpm (fifo.rdwr.."_full_o", vopenpin())}); table_join(fifo.maps, { vpm (fifo.nrdwr.."_"..field_prefix.."_o", vopenpin())});
end end
end end
...@@ -209,7 +278,7 @@ function fifo_wire_bus_ports(fifo) ...@@ -209,7 +278,7 @@ function fifo_wire_bus_ports(fifo)
17); 17);
gen_fifo_csr_field(FIFO_COUNT, gen_fifo_csr_field(FIFO_COUNT,
"count", "usedw",
"FIFO counter", "FIFO counter",
"Number of data records currently being stored in FIFO '"..fifo.name.."'", "Number of data records currently being stored in FIFO '"..fifo.name.."'",
fifo.usedw_size, fifo.usedw_size,
...@@ -217,12 +286,15 @@ function fifo_wire_bus_ports(fifo) ...@@ -217,12 +286,15 @@ function fifo_wire_bus_ports(fifo)
0); 0);
-- add the FIFO CSR register to the peripheral
if(type(fifo.flags_bus) == "table") then if(type(fifo.flags_bus) == "table") then
table.insert(periph, csr); table.insert(periph, csr);
end end
-- wire the bus-side read/write request port
table_join(fifo.maps, { vpm (fifo.nrdwr.."_req_i", fifo.full_prefix.."_"..fifo.nrdwr.."req_int") });
end end
...@@ -230,7 +302,7 @@ end ...@@ -230,7 +302,7 @@ end
function gen_code_fifo(fifo) function gen_code_fifo(fifo)
local prefix = string.lower(periph.hdl_prefix.."_"..fifo.hdl_prefix); local prefix = string.lower(periph.hdl_prefix.."_"..fifo.hdl_prefix);
print("GenCodeFIFO"); dbg("GenCodeFIFO");
fifo.full_prefix = prefix; fifo.full_prefix = prefix;
fifo.ports= {}; fifo.ports= {};
...@@ -240,8 +312,10 @@ function gen_code_fifo(fifo) ...@@ -240,8 +312,10 @@ function gen_code_fifo(fifo)
if(fifo.direction == BUS_TO_CORE) then if(fifo.direction == BUS_TO_CORE) then
fifo.rdwr = "rd"; fifo.rdwr = "rd";
fifo.nrdwr = "wr";
else else
fifo.rdwr = "wr"; fifo.rdwr = "wr";
fifo.nrdwr = "rd";
end end
...@@ -255,10 +329,42 @@ function gen_code_fifo(fifo) ...@@ -255,10 +329,42 @@ function gen_code_fifo(fifo)
if(fifo.direction == BUS_TO_CORE) then if(fifo.direction == BUS_TO_CORE) then
table_join(fifo.signals, { signal (BIT, 0, fifo.full_prefix.."_wrreq_int") }); table_join(fifo.signals, { signal (BIT, 0, fifo.full_prefix.."_wrreq_int") });
else else
table_join(fifo.signals, { signal (BIT, 0, fifo.full_prefix.."_rdreq_int") });
table_join(fifo.signals, { signal (BIT, 0, fifo.full_prefix.."_rdreq_int_d0") });
end
if(fifo.clock == nil) then
table_join(fifo.maps, { vpm ("clk_i", "bus_clock_int"); });
elseif (fifo.directrion == BUS_TO_CORE) then
table_join(fifo.maps, { vpm ("rd_clk_i", fifo.clock);
vpm ("wr_clk_i", "bus_clock_int") });
elseif (fifo.direction == CORE_TO_BUS) then
table_join(fifo.maps, { vpm ("wr_clk_i", fifo.clock);
vpm ("rd_clk_i", "bus_clock_int") });
end end
-- wire the data I/O
table_join(fifo.maps, {
vpm ("wr_data_i", fifo.full_prefix.."_in_int");
vpm ("rd_data_o", fifo.full_prefix.."_out_int") ;
-- and the generics
vgm ("g_size", fifo.size);
vgm ("g_width", fifo.total_size);
vgm ("g_usedw_size", log2up(fifo.size))
});
table_join(fifo.extra_code, {
vinstance(fifo.full_prefix.."_INST", "wbgen2_fifo_sync", fifo.maps);
});
end end
...@@ -138,6 +138,10 @@ foreach_field(calc_field_offset); ...@@ -138,6 +138,10 @@ foreach_field(calc_field_offset);
foreach_reg({TYPE_FIFO}, gen_code_fifo); foreach_reg({TYPE_FIFO}, gen_code_fifo);
foreach_field(calc_num_fields);
foreach_reg({TYPE_REG, TYPE_RAM, TYPE_FIFO}, calc_address_sizes); foreach_reg({TYPE_REG, TYPE_RAM, TYPE_FIFO}, calc_address_sizes);
assign_addresses(); assign_addresses();
......
...@@ -675,7 +675,7 @@ function gen_abstract_code(reg) ...@@ -675,7 +675,7 @@ function gen_abstract_code(reg)
reg.full_hdl_prefix = string.lower(periph.hdl_prefix.."_"..reg.hdl_prefix); reg.full_hdl_prefix = string.lower(periph.hdl_prefix.."_"..reg.hdl_prefix);
if(reg.no_std_regbank == true) then if(reg.no_std_regbank == true) then
print("reg: ",reg.name," - no std regbank"); dbg("reg: ",reg.name," - no std regbank");
return; return;
end end
......
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