6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 23, 2024 2:22 pm

All times are UTC




Post new topic Reply to topic  [ 66 posts ]  Go to page Previous  1, 2, 3, 4, 5
Author Message
PostPosted: Sat Mar 22, 2014 11:46 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
In Verilog, is there a way to pass a Parameter value from a top_level project into the lower modules?

Or at this point must it become a register?

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 23, 2014 12:39 am 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
EEyE:

I am sure that there must be a more effective way than the way that I use, but for me, it is a reliable method.

In a lower level module, I use the parameter keyword to define various parameters that allow me to define desired configurations. In the top most module, I define a similar parameter, and pass that down through all of the instantiated sub-modules to the desired sub-modules.

The defparam keyword may also be used. It can be used to reach all the way to the desired sub-module using the hierarchical path name of the sub-module. It can be used from the top-level module.

The following three code segments illustrate the method that I use for passing parameters from the top-level module to sub-modules. The first code segment is the parameters in my Dual Core M65C02 top level module, the second is instantiation of one of the UART sub-modules, and the third is the definition of the UART sub-module.

Code:
module M65C02Duo #(
    parameter pIRQ_Vector      = 16'hFFFE,  // Maskable Interrupt Vector
    parameter pBRK_Vector      = 16'hFFFE,  // BRK Instruction Trap Vector
    parameter pRST_Vector      = 16'hFFFC,  // Reset Vector
    parameter pNMI_Vector      = 16'hFFFA,  // Non-Maskable Interrupt Vector

    parameter pStkPtr_Rst      = 8'hFF,     // Stk Ptr Value after Reset
    parameter pInt_Hndlr       = 9'h021,    // _Int microroutine address

    parameter p_uP_AddrWidth   = 8'd9,
    parameter p_uP_Width       = 8'd36,
    parameter p_uP_Init        = "Src/M65C02_uPgm_V3b.coe",
   
    parameter pDEC_AddrWidth   = 8'd8,
    parameter pDEC_Width       = 8'd36,
    parameter pDEC_Init        = "Src/M65C02_IDEC_v3.coe",

    parameter pMMU_A_Init      = "Src/M65C02_MMU_CPU0.coe", // MMU Init. File
    parameter pMMU_B_Init      = "Src/M65C02_MMU_CPU1.coe", // MMU Init. File
   
    parameter pRAM_A_AddrWidth = 8'd14,     // 16384 x 8 Block RAM
    parameter pROM_A_AddrWidth = 8'd11,     //  2048 x 8 Block RAM
    parameter pRAM_B_AddrWidth = 8'd13,     //  8192 x 8 Block RAM
    parameter pROM_B_AddrWidth = 8'd11,     //  2048 x 8 Block RAM
    parameter pBus_Width       = 8'd8,      // Bus Width = 8 bits
    parameter pRAM_A_Init      = "Src/65C02_ft.txt",    // Functional Test Pgm
    parameter pROM_A_Init      = "Src/Mon6502_sbc25.txt",   // (0xFFFC)=0x0400
    parameter pRAM_B_Init      = "Src/M65C02_Tst6.txt",     // Here: JMP Here
    parameter pROM_B_Init      = "Src/Mon6502_sbc25.txt",   // (0xFFFC)=0x0400
   
    parameter pFrequency       = 29491200,  // (14.7456 MHz * 2)

    parameter pDefault_LCR_A   = 8'h40, // ~BRRE, RTSo, 232 w/o HS, 8N1
    parameter pDefault_IER_A   = 8'h00, // No interrupts enabled
    parameter pBaudrate_A      = 115200,
    parameter pRTOChrDlyCnt_A  = 3,     // RTO asserted on Rx idle 3 char times
    parameter pTF_Depth_A      = 0,     // Tx FIFO Depth = (2**(0+4))=16
    parameter pRF_Depth_A      = 0,     // Rx FIFO Depth = (2**(0+4))=16
    parameter pTF_Init_A       = "Src/UART_TF_16.coe",
    parameter pRF_Init_A       = "Src/UART_RF_16.coe",
   
    parameter pDefault_LCR_B   = 8'h40, // ~BRRE, RTSo, 232 w/o HS, 8N1
    parameter pDefault_IER_B   = 8'h00, // No interrupts enabled
    parameter pBaudrate_B      = 115200,
    parameter pRTOChrDlyCnt_B  = 3,     // RTO asserted on Rx idle 3 char times
    parameter pTF_Depth_B      = 0,     // Tx FIFO Depth = (2**(0+4))=16
    parameter pRF_Depth_B      = 0,     // Rx FIFO Depth = (2**(0+4))=16
    parameter pTF_Init_B       = "Src/UART_TF_16.coe",
    parameter pRF_Init_B       = "Src/UART_RF_16.coe",

    parameter pDefault_CR      = 8'h30,  // Rate=1/16, Mode=0, Dir=MSB, Sel=0
    parameter pSPI_FIFO_Depth  = 8'd4,   // Depth = (1 << 4) = 16
    parameter pSPI_FIFO_Init   = "Src/SPI_FIFO_Init_16.coe"
)(
    input   nRst,               // System Reset Input
    input   ClkIn,              // System Clk Input
   
    output  nRstO,              // Internal System Reset Output (OC w/ PU)

    //  M65C02 Clock Outputs

    output  Phi2O,              // Clock Phase 2 Output
    output  Phi1O,              // Clock Phase 1 Output - complement of Phi2O
   
    //  M65C02 External Bus Enable

    input   BE_In,              // Bus Enable: tri-states address, data, control
   
    //  M65C02 Special Interface Signals
   
    //input   nSO,                // Set oVerflow: currently unimplemented
    output  nWAI,               // Driven low by Wait instruction (ASIC-only)

    //  M65C02 External Interrupt Bus
   
    input   nNMI,               // Non-Maskable Interrupt Request: edge sense
    input   nIRQ,               // Maskable Interrupt Request: level sense
    output  nVP,                // Vector Pull: asserted to indicate ISR taken
   
    //  M65C02 Memory Interface Bus

    output  Sync,               // Synchronize: asserted during opcode fetch
    output  nML,                // Memory Lock: asserted during RMW instructions

    output  [3:0] nCE,          // Chip Enable for External RAM/ROM Memory
    output  RnW,                // Read/nWrite cycle control output signal
    output  nOE,                // External Asynchronous Bus
    output  nWE,                // External Asynchronous Bus Write Strobe
    inout   Rdy,                // Bus cycle Ready, drive low to extend cycle
    output  [ 3:0] XA,          // Extended Address Output for External Memory
    output  [15:0] A,           // External Memory Address Bus
    inout   [ 7:0] DB,          // External, Bidirectional Data Bus
   
    //  M65C02 Asynchronous Serial Port Interface
   
    output  reg TxD_A,          // Port A: Transmit Serial Data (Common 232/485)
    input   RxD_A,              // Port A: Receive Serial Data (AND Rx232/Rx485)
    output  reg nRTS_A,         // Port A: Ready To Send Flow Control Output
    input   nCTS_A,             // Port A: Clear To Send Flow Control Input
   
    output  reg DE_A,           // Port A: RS485 Drive Enable
   
    output  reg TxD_B,          // Port B: Transmit Serial Data (Common 232/485)
    input   RxD_B,              // Port B: Receive Serial Data (AND Rx232/Rx485)
    output  reg nRTS_B,         // Port B: Ready To Send Flow Control Output
    input   nCTS_B,             // Port B: Clear To Send Flow Control Input
   
    output  reg DE_B,           // Port B: RS485 Drive Enable

    //  M65C02 SPI Port Interface
   
    output  [1:0] nCSO,         // SPI I/F Chip Select
    output  SCK,                // SPI I/F Serial Clock
    output  MOSI,               // SPI I/F Master Out/Slave In Serial Data
    input   MISO,               // SPI I/F Master In/Slave Out Serial Data

    //  Non-65C02 Special Interface Signals

    output  nCore,              // nCSO[2]: 0 (On) - Core 1; 1 (Off) - Core 0
    input   nWP                 // Internal Boot/Monitor RAM write protect
);

The instantiation of one of the UARTs in the top-level module
Code:
UART    #(
            .pFrequency(pFrequency),
            .pDefault_LCR(pDefault_LCR_A),
            .pDefault_IER(pDefault_IER_A),
            .pBaudrate(pBaudrate_A),
            .pRTOChrDlyCnt(pRTOChrDlyCnt_A),
            .pTF_Depth(pTF_Depth_A),
            .pRF_Depth(pRF_Depth_A),
            .pTF_Init(pTF_Init_A),
            .pRF_Init(pRF_Init_A)
        ) COM_A (
            .Rst(Rst),
            .Clk(Clk),
           
            .IRQ(COM_A_IRQ),
           
            .Sel(COM_A_CE),
            .Reg(PA_A[1:0]),
            .RE(Rd_A),
            .WE(Wr_A),
            .DI(DO_A),
            .DO(COM_A_DO),
           
            .TxD_232(TxD_232_A),
            .RxD_232(rRxD_A),
            .xRTS(RTS_A),
            .xCTS(CTS_A),
           
            .TxD_485(TxD_485_A),
            .RxD_485(rRxD_A),
            .xDE(iDE_A),

            .TxIdle(),
            .RxIdle()
        );

The definition of the UART module. Some parameters are passed down to other instantiated sub-modules such as the transmit and receive FIFO modules.
Code:
module UART #(
    // Default UART Settings
   
    parameter pDefault_LCR = 8'h80,     // RTSo, Tx Enable, 232 w/o HS, 8N1
    parameter pDefault_IER = 8'h00,     // All interrupts disabled
   
    //  Default UART Baud Rate Settings
   
    parameter pFrequency = 29491200,    // 29.4912 MHz
    parameter pBaudrate  = 115200,      // 115200 bps
   
    // Default Receive Time Out Character Delay Count

    parameter pRTOChrDlyCnt = 3,        // Default Number of Characters for RTO

    // FIFO Configuration Parameters

    parameter pTF_Depth = 0,            // Tx FIFO Depth: 2**(TF_Depth + 4)
    parameter pRF_Depth = 0,            // Rx FIFO Depth: 2**(RF_Depth + 4)
    parameter pTF_Init  = "Src/UART_TF_16.coe", // Tx FIFO Memory Initialization
    parameter pRF_Init  = "Src/UART_RF_16.coe"  // Rx FIFO Memory Initialization
)(
    input   Rst,                        // System Reset
    input   Clk,                        // System Clock
   
    //  External Interrupt Request
   
    output  reg IRQ,                    // Interrupt Request
   
    //  Parallel Interface
   
    input   Sel,                        // UART Select
    input   [1:0] Reg,                  // UART Register Select
    input   RE,                         // UART Read Strobe
    input   WE,                         // UART Write Strobe
    input   [7:0] DI,                   // UART Data Input Bus
    output  wor [7:0] DO,               // UART Data Output Bus
   
    //  External UART Interface
   
    output  TxD_232,                    // RS-232 Mode TxD
    input   RxD_232,                    // RS-232 Mode RxD
    output  reg xRTS,                   // RS-232 Mode RTS (Ready-To-Receive)
    input   xCTS,                       // RS-232 Mode CTS (Okay-To-Send)
   
    output  TxD_485,                    // RS-485 Mode TxD
    input   RxD_485,                    // RS-485 Mode RxD
    output  xDE,                        // RS-485 Mode Transceiver Drive Enable

    //  TxSM/RxSM Status
   
    output  TxIdle,                     // UART TxSM Idle Status Output
    output  RxIdle                      // UART RxSM Idle Status Output
);


Hope this helps. I find that determining the parameterization that should be applied to a particular IP module is difficult. Too much parameterization leads to code that is hard to read, and an insufficient amount leads to code difficult to adapt without error prone edits to multiple applications. I generally develop the module first, and then I add parameterization.

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 30, 2014 2:09 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
Thanks Michael, that does help to a degree. In my situation I have 'wires' in the top_level that use the parameter values as well, so when I try applying what you did in your example to my case, I get an error "such&such is not a constant".

You seem to pass the parameter values from a module to the top_level, then to other modules. I think I need something that will pass a parameter value from the top_level to other modules.

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 30, 2014 4:50 pm 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
EEyE:

I declare the parameters for both the top module and any sub-modules at the start of the top module. I can then use the testbench to modify these parameters to test specific configurations. I do this so that by reading the parameter settings of the top module I can determine/recall how the top module and the sub-modules are configured for a particular synthesis/MAP/PAR session.

The ISE command line can be used to define macro and set parameter values. Thus, I expect, although I've never attempted to do this, that I can modify the parameters in a compile/synthesis script and parameterize the complete project without any edits to the source files. There's a limited capability to do this in the GUI, but that capability is what I use to configure/command Data2MEM to modify the contents of the block RAMs for the M65C02/M16C5x soft-core projects.

Look into the operation of the defparam keyword. It appears to be used by Xilinx to directly modify parameters within a sub-module without going through the top module. I've come across examples of its use in most of the IP that CoreGen produces.

ElEctric_EyE wrote:
In my situation I have 'wires' in the top_level that use the parameter values as well, so when I try applying what you did in your example to my case, I get an error "such&such is not a constant".

I am not clear on the issue that you are experiencing. parameters are treated as constants as far as I know. For you to be getting that error indicates to me that you are trying to use a variable to determine vector indices in some way.

I am not a power use of Verilog 2001, but it appears to have some specific constructs to allow accessing various parts of a vector. I dropped in on stackoverflow.com and saw an example of such a construct. The question was posed as something like: "what does vector[8:i] do?"

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 30, 2014 8:27 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
I will investigate, that's good info. Thanks for passing your findings along!

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 13, 2014 6:13 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
................................

Today I was looking back at some Verilog code written for the orsoc graphics accelerator which has been posted in the Arithmetic Core Section on opencores.org. I had first started learning Verilog from this project years ago and have built my current project around the structure of the state machine that I had found in the gfx_line module. Back then I was trying to learn Bresenham Line...

After comparing that module to some of the other modules in that project today, I had noticed that one of the comments of another module of identical construction to the one I currently use for all my graphic accelerated functions, that said it was a Mealy machine. I had heard of Mealy/Moore state machines before but knew nothing of them.

So now something clicked and I immediately knew (at least I think I do!) what the difference is between the two.

In a Mealy state machine it takes inputs into consideration and when state machine tells an output to change state during a rising edge of a CLK, it actually happens on the following rising edge as if it were a flip flop. I've noticed this in my simulations, especially when I was nailing down exact timing on the back to back Read/Write functions of the Sync RAM I'm using.

In a Moore state machine, there are no inputs?, but when an output signal is assigned a value it changes during that state as if it were a latch.

Is this correct thinking?

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 66 posts ]  Go to page Previous  1, 2, 3, 4, 5

All times are UTC


Who is online

Users browsing this forum: No registered users and 10 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: