📄 generate_ddr_sim_model.pl
字号:
lhs => $dqs,
rhs => "dqs_temp",
sim_delay => $rtl_board_delay,
}),
e_assign->new
({
lhs => $dq,
rhs => "dq_temp",
sim_delay => $rtl_board_delay,
}),
);
$module->add_contents
(
e_process->new
({
comment => "Pipelining registers for burst counting",
contents =>
[
e_assign->news
(
# ["write_valid" => "write_cmd"],
["write_valid_r" => "write_valid"],
["read_valid_r" => "read_valid"],
["write_valid_r2" => "write_valid_r"],
["write_valid_r3" => "write_valid_r2"],
["write_to_ram_r" => "write_to_ram"],
["read_valid_r2" => "read_valid_r"],
["read_valid_r3" => "read_valid_r2"],
["read_valid_r4" => "read_valid_r3"],
),
],
}),
);
if ($local_burst_length == 4)
{
# Memory BL8, local bl4 support
$module->add_contents
(
e_assign->new(["write_to_ram" => "write_valid || write_valid_r || write_valid_r2 || write_valid_r3"]),
e_assign->new(["dq_valid" => "read_valid_r || read_valid_r2 || read_valid_r3 || read_valid_r4"]),
);
}
elsif ($local_burst_length == 2) {
# Memory BL4, local bl2 support
$module->add_contents
(
e_assign->new(["write_to_ram" => "write_valid || write_valid_r"]),
e_assign->new(["dq_valid" => "read_valid_r || read_valid_r2"]),
);
}
else {
# No burst support
$module->add_contents
(
e_assign->new(["write_to_ram" => "write_valid"]),
e_assign->new(["dq_valid" => "read_valid_r"]),
);
};
$module->add_contents
(
# e_process->new
# ({
# comment => " ",
# contents =>
# [
# e_assign->news
# (
# ["dq_valid" => "read_valid"],
# ),
# ],
# }),
e_assign->new(["dqs_valid" => "dq_valid || dqs_valid_temp"]),
e_process->new
({
comment => " ",
clock_level => "0",
contents =>
[
e_assign->news
(
["dqs_valid_temp" => "read_valid"],
),
],
}),
# -- rising edge capture
# process (ddr_dqs(0))
# begin
# --
# if rising_edge(ddr_dqs(0)) then
# dq_captured(7 DOWNTO 0) <= ddr_dq(7 DOWNTO 0);
# dm_captured(0 DOWNTO 0) <= ddr_dm(0 DOWNTO 0);
# end if;
# end process;
e_process->new
({
comment => "capture first half of write data with rising edge of DQS, for simulation use only 1 DQS pin",
clock => $default_pin_prefix."dqs[0]",
contents =>
[
e_assign->news
(
["dq_captured[".($dq_width-1).":0]" => $default_pin_prefix."dq[".($dq_width-1).":0]"],
["dm_captured[".($dm_width-1).":0]" => $default_pin_prefix."dm[".($dm_width-1).":0]"],
),
]
}),
# -- falling edge capture
# process (ddr_dqs(0))
# begin
# --
# if falling_edge(ddr_dqs(0)) then
# dq_captured(23 DOWNTO 16) <= ddr_dq(7 DOWNTO 0);
# dm_captured(2 DOWNTO 2) <= ddr_dm(0 DOWNTO 0);
# end if;
# end process;
e_process->new
({
comment => "capture second half of write data with falling edge of DQS, for simulation use only 1 DQS pin",
clock => $default_pin_prefix."dqs[0]",
clock_level => 0,
contents =>
[
e_assign->news
(
["dq_captured[".($dq_width*2-1).":".($dq_width)."]" => $default_pin_prefix."dq[".($dq_width-1).":0]"],
["dm_captured[".($dm_width*2-1).":".($dm_width)."]" => $default_pin_prefix."dm[".($dm_width-1).":0]"],
),
]
}),
);
$module->add_contents
(
# there will always be at least DM[0]
e_process->new
({
comment => "Support for incomplete writes, do a read-modify-write with mem_bytes and the write data",
contents => [
e_if->new
({
# condition => "write_valid",
condition => "write_to_ram",
then => [e_assign->news (["rmw_temp[7:0]","dm_captured[0] ? mem_bytes[7 : 0] : dq_captured[7 : 0]"],),],
}),
],
}),
);
# now do the rest of DM pins
if ($mem_mask_width > 1) {
for (1 .. ($mem_mask_width-1))
{
$byte_lane = $_;
$lanes{$byte_lane} = (($byte_lane*8)+7).":".($byte_lane*8);
$module->add_contents
(
e_process->new
({
contents => [
e_if->new
({
# condition => "write_valid",
condition => "write_to_ram",
then => [e_assign->news (["rmw_temp[$lanes{$byte_lane}]" => "dm_captured[$byte_lane] ? "."mem_bytes[$lanes{$byte_lane}] : "."dq_captured[$lanes{$byte_lane}]"],),],
}),
],
}),
);
} # for (0 to ($dm_width-1))
} # if dm_width > 1
# ["rmw_temp[15:8]","dm_captured[1] ? mem_bytes[15 : 8] : dq_captured[15 : 8]"],
# ["rmw_temp[23:16]","dm_captured[2] ? mem_bytes[23 : 16] : dq_captured[23 : 16]"],
# ["rmw_temp[31:24]","dm_captured[3] ? mem_bytes[31 : 24] : dq_captured[31 : 24]"],
$module->add_contents
(
# e_assign->new(["mem_bytes" => "(rmw_address == wr_addr_delayed) ? rmw_temp : read_data"]),
e_assign->new(["mem_bytes" => "(rmw_address == wr_addr_delayed_r) ? rmw_temp : read_data"]),
# e_assign->new(["rmw_address", "(write_valid) ? wr_addr_delayed : read_addr_delayed"]),
e_assign->new(["rmw_address", "(write_to_ram) ? wr_addr_delayed : read_addr_delayed"]),
e_signal->news
(
{name => "read_addr", width => $read_addr_width, never_export => 1},
{name => "read_valid",width => 1, never_export => 1},
),
e_mux->new
({
comment=> "use index to select which pipeline stage drives addr",
type => "selecto",
selecto=> "index",
lhs => "read_addr_delayed",
table =>
[
0 => "rd_addr_pipe_0",
1 => "rd_addr_pipe_1",
2 => "rd_addr_pipe_2",
3 => "rd_addr_pipe_3",
4 => "rd_addr_pipe_4",
5 => "rd_addr_pipe_5",
],
}),
e_mux->new
({
comment=> "use index to select which pipeline stage drives valid",
type => "selecto",
selecto=> "index",
lhs => "read_valid",
table =>
[
0 => "rd_valid_pipe[0]",
1 => "rd_valid_pipe[1]",
2 => "rd_valid_pipe[2]",
3 => "rd_valid_pipe[3]",
4 => "rd_valid_pipe[4]",
5 => "rd_valid_pipe[5]",
],
}),
e_mux->new
({
comment=> "DDR2 has variable write latency too, so use index to select which pipeline stage drives valid",
type => "selecto",
selecto=> "index",
lhs => "write_valid",
table =>
[
0 => "wr_valid_pipe[0]",
1 => "wr_valid_pipe[1]",
2 => "wr_valid_pipe[2]",
3 => "wr_valid_pipe[3]",
4 => "wr_valid_pipe[4]",
5 => "wr_valid_pipe[5]",
],
}),
e_mux->new
({
comment=> "DDR2 has variable write latency too, so use index to select which pipeline stage drives addr",
type => "selecto",
selecto=> "index",
lhs => "wr_addr_delayed",
table =>
[
0 => "wr_addr_pipe_0",
1 => "wr_addr_pipe_1",
2 => "wr_addr_pipe_2",
3 => "wr_addr_pipe_3",
4 => "wr_addr_pipe_4",
5 => "wr_addr_pipe_5",
],
}),
);
print "# Finished creating memory model\n";
# Produce some output.
# print "\&make_sodimm: sim_model_base = $sim_model_base\n";
# print "\&make_sodimm: about to generate output...\n";
# $project->_verbose(1);
$project->output();
} else {
print "# Skipping creation of memory model because do_generation = $do_generation\n";
}
} # &make_sodimm
&make_ddr_sim_model(@ARGV);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -