2016-05-13 12 views
0

Gibt es ein Idiom in Verilog oder Systemverilog, mit dem ich eine Kompilierzeitvariable inkrementieren kann? Ich möchte in der Lage, so etwas zu tun:Verilog: Gibt es ein Idiom für einen inkrementierenden Kompilierzeitzähler?

wire [MAX_IRQ:0] irq_vec; 

localparam IRQ_COUNT = 0; 
`ifdef INCLUDE_UART 
uart inst_uart(
    .irq(irq_vec[IRQ_COUNT]), 
    ...other ports... 
); 
IRQ_COUNT = IRQ_COUNT + 1; 
`endif 

`ifdef INCLUDE_TIMER 
timer inst_timer(
    .irq(irq_vec[IRQ_COUNT]), 
    ...other ports... 
); 
IRQ_COUNT = IRQ_COUNT + 1; 
`endif 

Das, was ich zu tun versuche, ist eine Synthese Parameterdatei zu haben, die mich gewählt haben, die Anzahl und die Art der Ressourcen ermöglicht, die ich in dem System enthalten und machen Die Adressenzuordnung und die IRQ-Zuordnungen und solche richten sich automatisch abhängig von den ausgewählten Syntheseoptionen ein. Oder hat jemand eine bessere Methode, um dasselbe zu erreichen?

+1

Sieht aus wie 'Generate if' würde in dieser Situation funktionieren. – Morgan

Antwort

0

Nein, Sie können es nicht im laufenden Betrieb ändern.

Aber kann es Lösungen, siehe unten Code und versuchen zu verstehen,

wire [MAX_IRQ:0] irq_vec; 
integer IRQ_COUNT; 

wire is_uart; 
wire is_timer; 

`ifdef INCLUDE_UART 
assign is_uart = 1'b1; 
`else 
assign is_uart = 1'b0; 
`endif 

`ifdef INCLUDE_TIMER 
assign is_timer = 1'b1; 
`else 
assign is_timer = 1'b0; 
`endif 

always @ (*) 
begin 
    if(is_uart) 
    begin 
    inst_uart(irq_vec[IRQ_COUNT]), ...other ports...); // make module into task or function, whichever is applicable 
    IRQ_COUNT = IRQ_COUNT + 1; 
    end 

    if(is_timer) 
    begin 
    inst_timer(irq_vec[IRQ_COUNT],...other ports...); // make module into task or function, whichever is applicable 
    IRQ_COUNT = IRQ_COUNT + 1; 
    end 
end 

task inst_uart (
    input [MAX_IRQ:0] irq_vec, 
    // input output other ports; 

    ... 
); 
    wire [MAX_IRQ:0] irq_vec_v; 
    // define local variables 

    begin 
    irq_vec_v = irq_vec; // IO to varible 
    // .. other port assignment .. 

    // do operations 

    // assign operations and produced result will be stored into outputs 
    end 
    // Variable to IO assignment 
endtask 

task inst_timer (
    input [MAX_IRQ:0] irq_vec, 
    // input output other ports; 

    ... 
); 
    wire [MAX_IRQ:0] irq_vec_v; 
    // define local variables 

    begin 
    irq_vec_v = irq_vec; // IO to Variable 
    // .. other port assignment .. 

    // do operations 

    // assign operations and produced result will be stored into outputs 
    end 
    // Variable to IO 
endtask 

Ja, man kann sagen, dass es Beschränkung, aber wenn Sie es tun wollen, müssen Sie mit der Hardware-Auslastung gefährden, auch Wenn Sie nur Timer verwenden, muss für beide Hardware erzeugt werden, was unbrauchbar wird.

Was ich vorschlagen würde ist, bitte ändern Sie Ihre Architektur oder tun etwas in RTL von UART oder TIMER, wirklich, kombinieren beide in einzelnen Modul und behandeln nach Ihrer Anforderung.

0

Sie könnten etwas wie unten tun. Haben Sie separate IRQ-Parameter für jede Komponente und legen Sie sie basierend auf dem, was zuvor enthalten war:

wire [MAX_IRQ:0] irq_vec; 

localparam UART_IRQ = 0; 
`ifdef INCLUDE_UART 
uart inst_uart(
    .irq(irq_vec[UART_IRQ]), 
    ...other ports... 
); 
localparam TIMER_IRQ = UART_IRQ + 1; 
`else 
localparam TIMER_IRQ = UART_IRQ; 
`endif 

`ifdef INCLUDE_TIMER 
timer inst_timer(
    .irq(irq_vec[TIMER_IRQ]), 
    ...other ports... 
); 
localparam SOME_OTHER_IRQ = TIMER_IRQ + 1; 
`else 
localparam SOME_OTHER_IRQ = TIMER_IRQ; 
`endif