Shop OBEX P1 Docs P2 Docs Learn Events
Questions on the P1 Verilog code to anyone... - Page 2 — Parallax Forums

Questions on the P1 Verilog code to anyone...

2»

Comments

  • Cluso99Cluso99 Posts: 18,069
    edited 2014-08-13 22:39
    pik33 wrote: »
    Maybe it will be better to make vga for cog7 instead of cog0; cog0 is busy with spin interpreter and it has to be free to run vga pasm code.
    Probably true. Easy to change - a single "if (COG == n)" statement.
    Although it is also possible some will run with less than 8 cogs.
  • Willy EkerslykeWilly Ekerslyke Posts: 29
    edited 2014-08-13 23:49
    Interesting. The original code I gave in #13 didn't zero the unused vidack & vid_pin_out because it made no difference to device usage in my setup. Without the initialising:
    Flow Status Successful - Thu Aug 14 06:56:27 2014
    Quartus II 32-bit Version 13.1.0 Build 162 10/23/2013 SJ Web Edition
    Revision Name top
    Top-level Entity Name top
    Family Cyclone III
    Device EP3C16F484C6
    Timing Models Final
    Total logic elements   13,402 / 15,408 ( 87 % )
    Total combinational functions  12,299 / 15,408 ( 80 % )
    Dedicated logic registers  4,390 / 15,408 ( 28 % )
    Total registers    4390
    Total pins    42 / 347 ( 12 % )
    Total virtual pins   0
    Total memory bits   458,752 / 516,096 ( 89 % )
    Embedded Multiplier 9-bit elements 0 / 112 ( 0 % )
    Total PLLs    1 / 4 ( 25 % )
    

    With:
    Flow Status Successful - Thu Aug 14 07:20:16 2014
    Quartus II 32-bit Version 13.1.0 Build 162 10/23/2013 SJ Web Edition
    Revision Name top
    Top-level Entity Name top
    Family Cyclone III
    Device EP3C16F484C6
    Timing Models Final
    Total logic elements 13,402 / 15,408 ( 87 % )
    Total combinational functions 12,300 / 15,408 ( 80 % )
    Dedicated logic registers 4,390 / 15,408 ( 28 % )
    Total registers 4390
    Total pins 42 / 347 ( 12 % )
    Total virtual pins 0
    Total memory bits 458,752 / 516,096 ( 89 % )
    Embedded Multiplier 9-bit elements 0 / 112 ( 0 % )
    Total PLLs 1 / 4 ( 25 % )
    

    Then I realised that my project is set to optimise for space rather than speed. It'd be interesting to see if you can make further space savings by changing your project's optimisation too.
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-08-14 01:02
    Interesting. The original code I gave in #13 didn't zero the unused vidack & vid_pin_out because it made no difference to device usage in my setup. Without the initialising:
    Then I realised that my project is set to optimise for space rather than speed. It'd be interesting to see if you can make further space savings by changing your project's optimisation too.
    Here is my latest compile results...
    +---------------------------------------------------------------------------------+
    ; Flow Summary                                                                    ;
    +------------------------------------+--------------------------------------------+
    ; Flow Status                        ; Successful - Thu Aug 14 17:41:01 2014      ;
    ; Quartus II 64-Bit Version          ; 14.0.0 Build 200 06/17/2014 SJ Web Edition ;
    ; Revision Name                      ; top                                        ;
    ; Top-level Entity Name              ; top                                        ;
    ; Family                             ; Cyclone IV E                               ;
    ; Device                             ; EP4CE22F17C6                               ;
    ; Timing Models                      ; Final                                      ;
    ; Total logic elements               ; 12,971 / 22,320 ( 58 % )                   ;
    ;     Total combinational functions  ; 12,063 / 22,320 ( 54 % )                   ;
    ;     Dedicated logic registers      ; 4,195 / 22,320 ( 19 % )                    ;
    ; Total registers                    ; 4195                                       ;
    ; Total pins                         ; 42 / 154 ( 27 % )                          ;
    ; Total virtual pins                 ; 0                                          ;
    ; Total memory bits                  ; 524,288 / 608,256 ( 86 % )                 ;
    ; Embedded Multiplier 9-bit elements ; 0 / 132 ( 0 % )                            ;
    ; Total PLLs                         ; 1 / 4 ( 25 % )                             ;
    +------------------------------------+--------------------------------------------+
    
    If you have time, I would love to see what results Quartus 13 comes up with.
    Attached are my modified files (I have modified cog.v, dig.v, hub.v, hub_mem.v).
    deo_cluso_20140814.zip

    Currently, I have no idea of the settings. I basically just downloaded and ran.
    I do have timing errors and I am not sure what the max speed is (or where to look yet - still learning)
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-08-14 01:14
    Here is my hub_mem.v code.

    I am not sure how to do the $readmemh command.
    Can anyone answer help?
    // RR20140811     Bigger Hub RAM & No ROM
    //                RAM is 48KB and remaps 48-64KB to 32-48KB
    //                requires $readmemh("hub_rom_high.hex",memname,$8000,$BFFF);
    // =======================================
    module                hub_mem
    (
    input                clk_cog,
    input                ena_bus,
    input                w,
    input         [3:0]    wb,
    input        [13:0]    a,
    input        [31:0]    d,
    output        [31:0]    q
    );
    // 12288 x 32 ram with byte-write enables ($0000..$BFFF) = 48KB for DE0 (compiles)
    reg [7:0] ram3 [12287:0];
    reg [7:0] ram2 [12287:0];
    reg [7:0] ram1 [12287:0];
    reg [7:0] ram0 [12287:0];
    
    // ??? $readmemh("hub_rom_high.hex",memname,$8000,$BFFF);
    
    reg [7:0] ram_q3;
    reg [7:0] ram_q2;
    reg [7:0] ram_q1;
    reg [7:0] ram_q0;
    
    wire [13:0] addr = !a[13] ? a[13:0] : {2'b10, a[11:0]};    // remap RAM: 48-64KB overlays 32-48KB
    always @(posedge clk_cog)
    begin
        if (ena_bus && w && wb[3])
            ram3[addr[13:0]] <= d[31:24];
        if (ena_bus)
            ram_q3 <= ram3[addr[13:0]];
    end
    always @(posedge clk_cog)
    begin
        if (ena_bus && w && wb[2])
            ram2[addr[13:0]] <= d[23:16];
        if (ena_bus)
            ram_q2 <= ram2[addr[13:0]];
    end
    always @(posedge clk_cog)
    begin
        if (ena_bus && w && wb[1])
            ram1[addr[13:0]] <= d[15:8];
        if (ena_bus)
            ram_q1 <= ram1[addr[13:0]];
    end
    always @(posedge clk_cog)
    begin
        if (ena_bus && w && wb[0])
            ram0[addr[13:0]] <= d[7:0];
        if (ena_bus)
            ram_q0 <= ram0[addr[13:0]];
    end
    assign q            = {ram_q3, ram_q2, ram_q1, ram_q0};
    endmodule
    /*
    Copyright 2014 Parallax Inc.
    This file is part of the hardware description for the Propeller 1 Design.
    The Propeller 1 Design is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by the
    Free Software Foundation, either version 3 of the License, or (at your option)
    any later version.
    The Propeller 1 Design is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    more details.
    You should have received a copy of the GNU General Public License along with
    the Propeller 1 Design.  If not, see <http://www.gnu.org/licenses/>.
    */
    
  • pik33pik33 Posts: 2,366
    edited 2014-08-14 01:30
    That is how I use $readmemh. In the code below I initialized the buffer with sine wave file so it plays a sine wave after it start to show if it works
    module audiobuf (clk, datain,datastb,left,right,audiostb,empty);
    
    // Audio buffer for de2-115 and the Propeller verilog with portb enabled
    // v20140814-1025
    // Piotr Kardasz, pik33@o2.pl
    // gpl 3.0 
    // Warning: ALPHA QUALITY CODE, no warranty, use at your own risk
    
    
    input wire clk;
    input wire [31:0] datain;
    input wire datastb;
    output reg [23:0] left;
    output reg [23:0] right;
    input wire audiostb;
    output reg[1:0] empty;
    
    reg [31:0] buff [256];
    reg [31:0] adata;
    reg [7:0] aaddr;
    reg oldaudiostb;
    reg olddatastb;
    reg [7:0] dataaddr;
    
    initial
      begin
      $readmemh("sinus.hex",buff);
      aaddr<=0;
      empty<=0;
      dataaddr<=0;
      end
      
      
     always@(posedge clk)
       begin
        oldaudiostb<=audiostb; 
        olddatastb<=datastb;
    
          
       if ((audiostb==1) && (oldaudiostb==0)) // posedge audiostb
          begin
         adata<=buff[aaddr];
         aaddr<=aaddr+1;
         if (aaddr==128) empty[0]<=1;
         if (aaddr==0) empty[1]<=1;
          left<={adata[31:16],8'h00};
          right<={adata[15:0],8'h00};
          oldaudiostb<=audiostb;
          end
          
        if ((datastb==1) && (olddatastb==0)) // posedge datastb
          begin
         buff[dataaddr]<=datain;
          dataaddr<=dataaddr+1;
          if(dataaddr<128) empty[0]<=0; else empty[1]<=0;
          olddatastb<=datastb;
          end  
        end  
        
    endmodule    
    
    

    The hex file looks like this:
    00000000
    06480648
    0C8C0C8C
    12C812C8
    18F918F9
    1F1A1F1A
    25282528
    2B1F2B1F
    30FB30FB
    36BA36BA
    3C563C56
    41CE41CE
    471C471C
    4C3F4C3F
    51335133
    55F555F5
    5A825A82
    5ED75ED7
    62F162F1
    66CF66CF
    6A6D6A6D
    6DC96DC9
    70E270E2
    73B573B5
    76417641
    78847884
    7A7C7A7C
    7C297C29
    7D897D89
    7E9C7E9C
    7F617F61
    7FD87FD8
    7FFF7FFF
    7FD87FD8
    7F617F61
    7E9C7E9C
    7D897D89
    7C297C29
    7A7C7A7C
    78847884
    76417641
    73B573B5
    70E270E2
    6DC96DC9
    6A6D6A6D
    66CF66CF
    62F162F1
    5ED75ED7
    5A825A82
    55F555F5
    51335133
    4C3F4C3F
    471C471C
    41CE41CE
    3C563C56
    36BA36BA
    30FB30FB
    2B1F2B1F
    25282528
    1F1A1F1A
    18F918F9
    12C812C8
    0C8C0C8C
    06480648
    00000000
    F9B8F9B8
    F374F374
    ED38ED38
    E707E707
    E0E6E0E6
    DAD8DAD8
    D4E1D4E1
    CF05CF05
    C946C946
    C3AAC3AA
    BE32BE32
    B8E4B8E4
    B3C1B3C1
    AECDAECD
    AA0BAA0B
    A57EA57E
    A129A129
    9D0F9D0F
    99319931
    95939593
    92379237
    8F1E8F1E
    8C4B8C4B
    89BF89BF
    877C877C
    85848584
    83D783D7
    82778277
    81648164
    809F809F
    80288028
    80018001
    80288028
    809F809F
    81648164
    82778277
    83D783D7
    85848584
    877C877C
    89BF89BF
    8C4B8C4B
    8F1E8F1E
    92379237
    95939593
    99319931
    9D0F9D0F
    A129A129
    A57EA57E
    AA0BAA0B
    AECDAECD
    B3C1B3C1
    B8E4B8E4
    BE32BE32
    C3AAC3AA
    C946C946
    CF05CF05
    D4E1D4E1
    DAD8DAD8
    E0E6E0E6
    E707E707
    ED38ED38
    F374F374
    F9B8F9B8
    00000000
    06480648
    0C8C0C8C
    12C812C8
    18F918F9
    1F1A1F1A
    25282528
    2B1F2B1F
    30FB30FB
    36BA36BA
    3C563C56
    41CE41CE
    471C471C
    4C3F4C3F
    51335133
    55F555F5
    5A825A82
    5ED75ED7
    62F162F1
    66CF66CF
    6A6D6A6D
    6DC96DC9
    70E270E2
    73B573B5
    76417641
    78847884
    7A7C7A7C
    7C297C29
    7D897D89
    7E9C7E9C
    7F617F61
    7FD87FD8
    7FFF7FFF
    7FD87FD8
    7F617F61
    7E9C7E9C
    7D897D89
    7C297C29
    7A7C7A7C
    78847884
    76417641
    73B573B5
    70E270E2
    6DC96DC9
    6A6D6A6D
    66CF66CF
    62F162F1
    5ED75ED7
    5A825A82
    55F555F5
    51335133
    4C3F4C3F
    471C471C
    41CE41CE
    3C563C56
    36BA36BA
    30FB30FB
    2B1F2B1F
    25282528
    1F1A1F1A
    18F918F9
    12C812C8
    0C8C0C8C
    06480648
    00000000
    F9B8F9B8
    F374F374
    ED38ED38
    E707E707
    E0E6E0E6
    DAD8DAD8
    D4E1D4E1
    CF05CF05
    C946C946
    C3AAC3AA
    BE32BE32
    B8E4B8E4
    B3C1B3C1
    AECDAECD
    AA0BAA0B
    A57EA57E
    A129A129
    9D0F9D0F
    99319931
    95939593
    92379237
    8F1E8F1E
    8C4B8C4B
    89BF89BF
    877C877C
    85848584
    83D783D7
    82778277
    81648164
    809F809F
    80288028
    80018001
    80288028
    809F809F
    81648164
    82778277
    83D783D7
    85848584
    877C877C
    89BF89BF
    8C4B8C4B
    8F1E8F1E
    92379237
    95939593
    99319931
    9D0F9D0F
    A129A129
    A57EA57E
    AA0BAA0B
    AECDAECD
    B3C1B3C1
    B8E4B8E4
    BE32BE32
    C3AAC3AA
    C946C946
    CF05CF05
    D4E1D4E1
    DAD8DAD8
    E0E6E0E6
    E707E707
    ED38ED38
    F374F374
    F9B8F9B8
    
    
  • Willy EkerslykeWilly Ekerslyke Posts: 29
    edited 2014-08-14 01:46
    If you have time, I would love to see what results Quartus 13 comes up with.

    I'm already using 13.1. Can't use 14 because it doesn't support my board's Cyclone III.
    Currently, I have no idea of the settings. I basically just downloaded and ran.

    In Quartus go to the Assignments menu and select Settings. In the Settings window select Analysis & Synthesis Settings and then on the right you can select Optimistsation for Speed, Area or a Balance between the two.
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-08-14 02:15
    I'm already using 13.1. Can't use 14 because it doesn't support my board's Cyclone III.
    Yes, thats what I would like to see - 13.1 results. I am using 14, so it would be a good comparison.
    In Quartus go to the Assignments menu and select Settings. In the Settings window select Analysis & Synthesis Settings and then on the right you can select Optimistsation for Speed, Area or a Balance between the two.
    Thanks. Just checked and its set for
    Under Assignments / Settings / Physical Synthesis Optimisations / Effort Level / Extra is ticked (optimise during synthesis and fitting; major compilation time increase)
    Other options were Fast & Normal. There are other sections but nothing ticked.
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-08-14 02:17
    pik33 wrote: »
    That is how I use $readmemh. In the code below I initialized the buffer with sine wave file so it plays a sine wave after it start to show if it works

    Our RAM is built as byte blocks. Do you know how I name this?
    // 12288 x 32 ram with byte-write enables ($0000..$BFFF) = 48KB for DE0 (compiles) reg [7:0] ram3 [12287:0]; reg [7:0] ram2 [12287:0]; reg [7:0] ram1 [12287:0]; reg [7:0] ram0 [12287:0]; 
    initial   begin   $readmemh("rom.hex",{ram3, ram2, ram1, ram0});   end
    

    I can build the hex file easily.
  • pik33pik33 Posts: 2,366
    edited 2014-08-14 02:32
    I don't know if you can init 4 bufers at once. (I am still learning) - try to init one ram block at once
    
    reg [7:0] ram0 [12287:0];
    reg [7:0] ram1 [12287:0];
    reg [7:0] ram2 [12287:0];
    reg [7:0] ram3 [12287:0];
    
    
    then
    
    $readmemh("ram0.hex",ram0);
    $readmemh("ram1.hex",ram1);
    $readmemh("ram2.hex",ram2);
    $readmemh("ram3.hex",ram3);
    
    
    
    
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-08-14 06:00
    Pik33,
    I was trying to avoid having 4 files, each with interleaved bytes fron longs.
  • Todd MarshallTodd Marshall Posts: 89
    edited 2014-08-14 09:07
    Here it is for my Cyclone V (original code from Chip):

    Flow Status Successful - Thu Aug 14 10:54:11 2014
    Quartus II 64-Bit Version 13.1.0 Build 162 10/23/2013 SJ Web Edition
    Revision Name top
    Top-level Entity Name top
    Family Cyclone V
    Device 5CGXFC5C6F27C7
    Timing Models Final
    Logic utilization (in ALMs) 8,010 / 29,080 ( 28 % )
    Total registers 5884
    Total pins 42 / 364 ( 12 % )
    Total virtual pins 0
    Total block memory bits 524,288 / 4,567,040 ( 11 % )
    Total DSP Blocks 0 / 150 ( 0 % )
    Total HSSI RX PCSs 0 / 6 ( 0 % )
    Total HSSI PMA RX Deserializers 0 / 6 ( 0 % )
    Total HSSI TX PCSs 0 / 6 ( 0 % )
    Total HSSI TX Channels 0 / 6 ( 0 % )
    Total PLLs 1 / 12 ( 8 % )
    Total DLLs 0 / 4 ( 0 % )
  • jmgjmg Posts: 15,173
    edited 2014-08-14 12:56
    Cluso99 wrote: »

    I was trying to avoid having 4 files, each with interleaved bytes fron longs.

    I think you would then need to re-organise the memory declaration so there is a single name to point $readmemh at.
    Seems that can be any width, eg 32,36,40,160 wide, the hex file line width just matches the Array Name width..

    Looking at the Cyclone V, if the memory is declared as 160b (4x40) wide, you can extract 5x32 from that for no wastage.( and a 25% boost in available Memory, on the CV). (Likewise 8x36 would allow 9x32 extract)
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-08-14 21:24
    Is this possible and if so, can you help with the syntax for this line please?
    ram32{[31:24][addr[13:0]]} <= d[31:24];
    From this I should be able to figure out the problem 2 lines lower.
    I have converted the RAM to 32bit wide to make it easier to load the default ROM file.
    reg [31:0] ram32 [12287];    // RAM 48KB as longs
    reg [31:0] ram32_q;
    
    wire [13:0] addr = !a[13] ? a[13:0] : {2'b10, a[11:0]};    // remap RAM: 48-64KB overlays 32-48KB
    
    always @(posedge clk_cog)
    begin
        if (ena_bus && w && wb[3])
            ram32{[31:24][addr[13:0]]} <= d[31:24];
        if (ena_bus)
            ram32_q[31:24] <= ram32{[31:24][addr[13:0]]};
    end
    
    
    I have figured it out :(
  • jmgjmg Posts: 15,173
    edited 2014-08-15 00:31
    Cluso99 wrote: »
    I have converted the RAM to 32bit wide to make it easier to load the default ROM file.

    I found this
    http://stackoverflow.com/questions/9075289/bit-half-byte-byte-memory-access-in-32-bit-memory-using-verilog

    and note the comment there
    BlockRAMs have an option to support individual byte enables.

    I think that matters, as if you need single-byte writes into 32b memory, without a read+mask, then you need to create the BLOCK RAM using byteena[3:0]

    The Altera doc CV-52002 2014.06.30 has a byteena[3:0] example in
    Table 2-13: byteena Controls in x40 Data Width

    I think this detail scuttles my idea of packing 5 x 32 in 4 x 40, as we do not have 5 byteena lines. Oh well...
  • Cluso99Cluso99 Posts: 18,069
    edited 2014-09-04 16:35
    Here is another verilog question...
        sa <= ix[oh:ol] == 6'b000110    ?                            // AUGxx
              ix[wz:im] == 4'b0001      ?    {14'b0, ix[sh:sl]}      // AUGDS 000110_0001_1111_ddddddddd_sssssssss
              ix[wz:wr] == 3'b010       ?    ix[22:0]                // AUGS  000110_010s_ssss_sssssssss_sssssssss
                                        :    32'b0;                  // else all 0's
    
    
    I am unsure if I need to bracket groups, and whether the else works for all???
    This is what I am trying to achieve...
    if ix[oh:ol] == 6'b000110
      if ix[wz:im] == 4'b0001
        sa <= 14'b0, ix[sh:sl]
      else if ix[wz:wr] == 3'b010
        sa <= ix[22:0]
      else
        sa <= 32'b0
    else
      sa <= 32'b0
    
    Is there a better way to do this???

    Also noticed this in cog.v
    always @(posedge clk_cog or negedge ena)
    if (!ena)
        p <= 1'b0;
    else if (m[3] && !(cond && jump_cancel))
        p <= px + 1'b1;
    
    
    Shouldn't p <= 1'b0 be p <= 9'b0 ???
  • Willy EkerslykeWilly Ekerslyke Posts: 29
    edited 2014-09-05 11:05
    I am unsure if I need to bracket groups, and whether the else works for all???
    The else part doesn't work for all - each '?' operator needs a matching ':'.
    if ix[oh:ol] == 6'b000110
      if ix[wz:im] == 4'b0001
        sa <= 14'b0, ix[sh:sl]
      else if ix[wz:wr] == 3'b010
        sa <= ix[22:0]
      else
        sa <= 32'b0
    else
      sa <= 32'b0
    
    Is there a better way to do this???
    If you are doing this within an always block (as implied by the '<=') then you could try this:
    sa <= 32'b0;            // set default value
    if ix[oh:ol] == 6'b000110
       if ix[wz:im] == 4'b0001
         sa <= 14'b0, ix[sh:sl]
       else if ix[wz:wr] == 3'b010
         sa <= ix[22:0]
    
    Also noticed this in cog.v
    always @(posedge clk_cog or negedge ena)
    if (!ena)
        p <= 1'b0;
    else if (m[3] && !(cond && jump_cancel))
        p <= px + 1'b1;
    
    Shouldn't p <= 1'b0 be p <= 9'b0 ???
    Verilog will extend the 1'b0 with as many extra leading 'b0 as necessary to match the width of the destination. From a code-documentation point of view it may seem useful for the constant's width to match the destination but can you trust that it's been maintained correctly when the width of the destination was changed? :smile:
Sign In or Register to comment.