-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
output_buf module create #146
Conversation
Just create the output buffer module.
At this point, the buildkite check will definitely fail because the output buffer is a direct instantiation of tsmcN16 std cell logic gate. |
|
||
|
||
// output buffer control | ||
logic [7:0] ctl_buf_n; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@CansWang thanks for adding these debug signals. Here's how to integrate them into the JTAG interface:
- Open
dragonphy2/md/tx_intf.md
and create entries for both signals. The packed dimension for both is7:0
and the unpacked dimension can be left blank. (This is where you get to specify the default values) - Open
dragonphy2/vlog/chip_src/jtag/jtag.sv
and wire fromrjtag_intf_i
(which contains all JTAG signals) totdbg_intf_i
(which contains only TX signals). This is where the TX-related wiring is done:
dragonphy2/vlog/chip_src/jtag/jtag.sv
Lines 317 to 346 in e10cc10
// Transmitter assign tdbg_intf_i.en_gf = rjtag_intf_i.tx_en_gf; assign tdbg_intf_i.en_arb_pi = rjtag_intf_i.tx_en_arb_pi; assign tdbg_intf_i.en_delay_pi = rjtag_intf_i.tx_en_delay_pi; assign tdbg_intf_i.en_ext_Qperi = rjtag_intf_i.tx_en_ext_Qperi; assign tdbg_intf_i.en_pm_pi = rjtag_intf_i.tx_en_pm_pi; assign tdbg_intf_i.en_cal_pi = rjtag_intf_i.tx_en_cal_pi; assign tdbg_intf_i.ext_Qperi = rjtag_intf_i.tx_ext_Qperi; assign tdbg_intf_i.sel_pm_sign_pi = rjtag_intf_i.tx_sel_pm_sign_pi; assign tdbg_intf_i.del_inc = rjtag_intf_i.tx_del_inc; assign tdbg_intf_i.enb_unit_pi = rjtag_intf_i.tx_enb_unit_pi; assign tdbg_intf_i.ctl_dcdl_slice = rjtag_intf_i.tx_ctl_dcdl_slice; assign tdbg_intf_i.ctl_dcdl_sw = rjtag_intf_i.tx_ctl_dcdl_sw; assign tdbg_intf_i.ctl_dcdl_clk_encoder = rjtag_intf_i.tx_ctl_dcdl_clk_encoder; assign tdbg_intf_i.disable_state = rjtag_intf_i.tx_disable_state; assign tdbg_intf_i.en_clk_sw = rjtag_intf_i.tx_en_clk_sw; assign tdbg_intf_i.en_meas_pi = rjtag_intf_i.tx_en_meas_pi; assign tdbg_intf_i.sel_meas_pi = rjtag_intf_i.tx_sel_meas_pi; assign tdbg_intf_i.en_inbuf = rjtag_intf_i.tx_en_inbuf; assign tdbg_intf_i.sel_clk_source = rjtag_intf_i.tx_sel_clk_source; assign tdbg_intf_i.bypass_inbuf_div = rjtag_intf_i.tx_bypass_inbuf_div; assign tdbg_intf_i.bypass_inbuf_div2 = rjtag_intf_i.tx_bypass_inbuf_div2; assign tdbg_intf_i.inbuf_ndiv = rjtag_intf_i.tx_inbuf_ndiv; assign tdbg_intf_i.en_inbuf_meas = rjtag_intf_i.tx_en_inbuf_meas; assign tdbg_intf_i.sel_del_out_pi = rjtag_intf_i.tx_sel_del_out_pi; assign tdbg_intf_i.en_del_out_pi = rjtag_intf_i.tx_en_del_out_pi; assign rjtag_intf_i.tx_pm_out_pi = tdbg_intf_i.pm_out_pi; assign rjtag_intf_i.tx_cal_out_pi = tdbg_intf_i.cal_out_pi; assign rjtag_intf_i.tx_Qperi = tdbg_intf_i.Qperi; assign rjtag_intf_i.tx_max_sel_mux = tdbg_intf_i.max_sel_mux;
@@ -0,0 +1,60 @@ | |||
module output_buf_tx #( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a behavioral model for the output buffer? That should get tests passing again. You can do this by creating a file vlog/cpu_models/tx_16t1/output_buf_tx.sv
and just have it wire from DINN
to DOUTN
and from DINP
to DOUTP
. (We can add more detail later). The dependency system should automatically figure out to use that model for CPU-based simulations.
Once that simulation is working, please copy the file to vlog/fpga_models/tx_16t1/output_buf_tx.sv
so that it can be used in FPGA emulation. (I may update it later, but this should at least get tests passing again)
|
||
|
||
// Termination | ||
`ifndef VIVADO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need the ifndef
/endif
in this case because we're replacing the output buffer with a model for FPGA emulation
// instantiate BUFTD + | ||
genvar i; | ||
generate | ||
for (i=0; i<8; i=i+1) begin: iBUF |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please call label this generate block with something like iBUFP
and the other one with something like iBUFN
; otherwise it will be hard to tell which buffers are P
and which are N
(might need to know this for PnR scripts)
genvar i; | ||
generate | ||
for (i=0; i<8; i=i+1) begin: iBUF | ||
BUFTD4BWP16P90 tri_buf ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the tristate buffer, can you try this procedure?
- Instantiate it as something like
tx_tri_buf
(i.e., generic gate name) - Create an implementation of
tx_tri_buf
indragonphy2/vlog/chip_src_tsmc16/tx_16t1/tx_tri_buf
. That implementation should instantiate the gateBUFTD4BWP16P90
. In other words, it is a wrapper for the process-specific gate. - Then, create an implementation of
tx_tri_buf
indragonphy2/vlog/chip_src_freepdk45/tx_16t1/tx_tri_buf
. That implementation should instantiate an equivalent cell from FreePDK45 -- the options areTBUF_Xn
, wheren
is1
,2
,4
,8
, or16
. Note that for the FreePDK45 cells, the input is calledA
, the output enable is calledEN
, and the output is calledZ
. The reason that we need the FreePDK45 version is because that is what our regression server uses for synthesis tests. - Finally, update our dependency management system so that it uses the right view for TSMC16 vs. FreePDK45. Open
dragonphy2/dragonphy/views.py
and edit this section:
Lines 155 to 166 in e10cc10
if process == 'freepdk-45nm': override['sram'] = 'chip_src_freepdk45' override['sram_small'] = 'chip_src_freepdk45' skip.add('sram_144_1024_freepdk45') skip.add('sram_64_256_freepdk45') elif process == 'tsmc16': override['sram'] = 'chip_src_tsmc16' override['sram_small'] = 'chip_src_tsmc16' skip.add('TS1N16FFCLLSBLVTC1024X144M4SW') skip.add('TS1N16FFCLLSBLVTC256X64M4SW') else: raise Exception(f'Unknown process: {process}')
In the freepdk-45nm
section, add
override['tx_tri_buf'] = 'chip_src_freepdk45'
skip.add('TBUF_Xn') # use your value of n (1, 2, 4, 8, or 16)
Similarly, in the tsmc16
section, add
override['tx_tri_buf'] = 'chip_src_tsmc16'
skip.add('BUFTD4BWP16P90')
@@ -25,7 +24,7 @@ generate // Instantiate 4 hr_4t1_mux_top to form 16:4 mux | |||
endgenerate | |||
|
|||
// Clock divider, divide-by-two |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very minor comment -- please delete obsolete code rather than commenting it out
@CansWang one last comment -- it looks like this branch is out-of-date with the master branch; would you mind updating it? Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
No description provided.