⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 testing.v.txt

📁 verilog实例100多个
💻 TXT
📖 第 1 页 / 共 2 页
字号:
            // that was cool.  if 2 stops, then do this again

            if (nstops) begin

               #(bit_time);

               if (uart1out != 1)

                  receive_serial_result_uart1 = receive_serial_result_uart1 | `RECEIVE_RESULT_BADSTOP;

            end

         #(bit_time/2);

      end

   end

end

endtask





4.0  Memories



Memories, whether they are RAMs, ROMs or special memories like FIFOs 

are easily modeled in Verilog.  Note that you can define your own special

 testbench locations for debugging!  Say, you have a processor core hooked

up to these memories.  Define some special locations that when read or 

written to, display diagnostic messages.  Or, you can specify that a write to

 a particular location will halt the simulation or signify PASS or FAIL.  

Memories are an easy way for the embedded Verilog core processor to 

communicate to the testbench.  There are many possibilities.  



reg [15:0] FLASH_memory [0:(1024*32 - 1)];   // 32K of FLASH

reg [15:0] SRAM_memory  [0:(1024*32 - 1)];   // 32K of SRAM



//*****

//

//  The ASIC's ca[20] is the active LO chip select for the FLASH.

//  The ASIC's ca[18] is the active LO chip select for the SRAM.



// Write process for FLASH and SRAM

//

always @(posedge cwn) begin

   if (ca[20] == 1'b0) begin

      // Write to FLASH

      if (ca[16:15] != 2'b00) begin

         $display ("Illegal write to FLASH!");

      end

      else begin

         $display ("Write to FLASH Address = %h, Data = %h", ca, cb);

         // Our FLASH is only declared up to 32KW, so use ca[14:0]

         FLASH_memory[ca[14:0]] = cb;

         

         // Check for magic write from the embedded processor core!  This is done in the

         // C firmware simply by writing to the location.

         //

         if (ca == `MAGIC_ADDRESS) begin

            $display ("Embedded code has signalled DONE!");

            sa_test_status = `SA_TEST_DONE;

            sa_test_result = cb;

         end

      end

   end

   else if (ca[18] == 1'b0) begin

      // Write to SRAM

      if (ca[16:15] != 2'b00) begin

         $display ("Illegal write to SRAM!");

      end

      else begin

         $display ("Write to SRAM Address = %h, Data = %h", ca, cb);

         // Our SRAM is only declared up to 32KW, so use ca[14:0]

         SRAM_memory[ca[14:0]] = cb;

      end

   end

end



// Read process for FLASH and SRAM

//

always @(crn) begin

   if (crn == 1'b0) begin

      case ({ca[20], ca[18]})

         2'b11: cb_i <= 16'hzzzz;

         2'b10: begin

            $display ("Read from SRAM Address = %h, Data = %h", ca, SRAM_memory[ca[14:0]]);

            cb_i <= SRAM_memory[ca[14:0]];

            end

         2'b01: begin

            $display ("Read from FLASH Address = %h, Data = %h", ca, FLASH_memory[ca[14:0]]);

            cb_i <= FLASH_memory[ca[14:0]];

            end

         2'b00: begin

            $display ("Simultaneosly selecting FLASH and SRAM!!");

            end

      endcase

   end

   else begin

      cb_i <= 16'hzzzz;

   end

end



Clearing the memories is easy:



task clear_SRAM;

reg [15:0] SRAM_address;

begin

   $display ("Clearing SRAM..");

   for (SRAM_address = 16'h0000; SRAM_address < 16'h8000; SRAM_address = SRAM_address + 1) begin

      SRAM_memory[SRAM_address] = 0;

   end

end

endtask



Performing other operations is straight-forward.  How about a task 

that copies a firmware hex image to a FLASH memories boot area, 

relocating along the way and maybe setting a hew header bytes too. 

 Now, this task is specific to a particular processor, etc. but this 

shows what is fairly easily done in Verilog:



task copy_to_FLASH_boot;

reg [15:0] temp_memory[0:1023];

reg [15:0] original_address;

reg [15:0] FLASH_address;

integer n;

begin

   $display ("Copying ROM image to FLASH boot block..");



   // Read in the normal ROM file into our temporary memory.

   for (original_address = 0; original_address < 1024; original_address = original_address + 1) begin

      temp_memory[original_address] = 0;

   end

   $readmemh (`ROM_FILE, temp_memory);

   

   // Fill in Boot header

   FLASH_memory[15'h0800] = `BOOT_COPY_LENGTH; // Let's copy 1KW maximum

   FLASH_memory[15'h0801] = 0;              // Copy program to code space starting at zero

   FLASH_memory[15'h0802] = temp_memory[3]; // Entry point is same as the address in the reset vector

   

   // Now, copy from original image into the boot area.

   n = 0;

   FLASH_address = 15'h0803;

   original_address = 0;

   while (n < 1024) begin

      FLASH_memory[FLASH_address] = temp_memory[original_address];

      FLASH_address = FLASH_address + 1;

      original_address = original_address + 1;

      n = n + 1;

   end

end

endtask



Also, test vectors are easily loaded into Verilog memories using the 

$readmem statements.  You may easily read your stimulus vectors 

from a file into a memory, clock out the vectors to your circuit, and 

optionally capture your circuits response to another memory (or simply 

write the vector out using $fdisplay).  Once you have captured one

 output vector set that you know is good (e.g. your "Golden" vectors), 

your testbench can compare subsequent simulation vectors against 

these "Golden" vectors and detect any problems in your changing 

circuit (e.g. after back-annotation, scan insertion, or alpha space

 particle circuit corruption).



5.0  Bus Models



Many times a processor is interfaced to the logic being tested.  If the 

complete processor model/core is not present, then a "bus model" is 

a simple function that emulates the bus transaction.  More simply; the

 bus model allows the testbench to read and write values.  The following 

task utilizes very specific timing delays.  You should probably include

 'defines' for these and update them as you get better timing information.  

Typically, you will test your UART or whatever peripheral in isolation 

with the bus model, and later test your peripheral with the real processor core.



write_to_foobar (COMPAREH_REGISTER, next_word[31:16]);

#10;

write_to_ foobar(COMPAREL _REGISTER, next_word[15:0]);

#10;



task write_to_foobar;

input [15:0] address_arg;

input [15:0] data_arg;

// Several global bus signals are assumed: address, we, clk.

begin

   /* Wait until next rising clock edge */ 

   @(posedge clk);

	

   /* t_valid for address is 5ns, wait and then drive address */

   #5;  // <----  Manually back-annotate this, or use a define, whatever...

   address = address_arg;



   /* t_valid for wrxxx is 8ns, we are already 5ns into cycle, so wait 3ns */

   #3;

   we <= 1'b1;

	

   /* t_valid for wrdata is 20ns, We are 8ns into cycle, wait 12ns */

   #12

   data <= data_arg;



   /* Wait till the next rising edge, wait for a little bit of hold time. */

   @(posedge clk40);

   #1;

   address <= 4'hz;

   #1;

   we  <= 1'b0;

   #4;

   data <= 16'hzzzz;

		

   //$display ("Writing data %h to address: %h", data, address);

end

endtask



Here's a task that reads from the memory-mapped peripheral.



task read_from_foobar;

input [3:0] address_arg;

// Let's just write to a global with the resulting data retrieved (! bad practice, I know....)

// Gobal variable is 'last_data_read'.

begin

   /* Wait until next rising edge to do anything.. */

   @(posedge clk)

	

   /* t_valid for rwadrs is 5ns, wait and then drive address */

   #5;

   address = address_arg;



   /* t_valid for rbxxx is 8ns, we are already 5ns into cycle, so wait 3ns */

   #3;

   rw <= 1'b1;

	

   /* Wait till the next rising edge, wait for a little bit of hold time. */

   @(posedge clk);

   last_data_read = data;  // <-- keep in the global, caller can use if they wish.

   $display ("Reading data %h from address: %h", data, address);



   /* Wrap it up.  Deassert rw.  Let's float the address bus. */

   rw <= 1'b0;

   #1;

   address <= 16'hzzzz;

end

endtask



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -