1. 程式人生 > >OC8051內部邏輯分析(1)

OC8051內部邏輯分析(1)

採用資料流的方式進行OC8051內部的邏輯分析,需要首先理解其儲存器架構,然後追蹤程式到再到資料流。

  前面有提到過,OC8051程式和資料儲存器邏輯分離,在物理上,其可能有4種儲存器,分別為內部程式儲存器irom,內部資料儲存器iram,外部程式儲存器器xrom,外部資料程式儲存器xram,其中訪問xram和訪問iram的指令不同(mov、movx,並要通過DPTR暫存器)。OC8051使用oc8051_defines.v控制所採用的儲存結構,oc8051_defines.v部分程式碼如下:

 1 //
 2 // oc8051 ITERNAL ROM
 3 //
 4 `define OC8051_ROM
 5 
 6 
 7 //
 8 // oc8051 memory
 9 //
10 //`define OC8051_CACHE
11 //`define OC8051_WB 12 13 //`define OC8051_RAM_XILINX 14 //`define OC8051_RAM_VIRTUALSILICON 15 `define OC8051_RAM_GENERIC 16 17 18 `define OC8051_XILINX_ROM

  `define OC8051_ROM:使用內部iROM,而外部xROM ,OC8051提供了3種可選的介面,1、CACHE;2、WISHBONE;3、內部訊號線直通。

  irom和iram是屬於8051的部分,xrom,xram則可以沒有,在實際的實現上,irom和xrom只要有一個就行。OC8051提供了irom的一個FPGA(XILINX)實現和一個行為模擬模型,均在檔案oc8051_rom.v裡,通過`define OC8051_XILINX_ROM,使用XILINX的實現,否則使用的是通用的模擬模型。另外OC8051工程提供了一個工具可以將HEX檔案轉換為.v,這種轉換的實現和`define OC8051_XILINX_ROM所選用的實現是一樣的,其更新ROM中程式碼非常不方便;這和其採用的ROM模型有關,通過如下程式碼可以看出其採用的儲存器模型:

 1 reg [7:0] buff [0:65535]; //64kb
 2 
 3 assign ea = 1'b0;
 4 
 5 initial
 6 begin
 7   $readmemh("../../../bench/in/oc8051_rom.in", buff);
 8 end
 9 
10 always @(posedge clk or posedge rst)
11  if (rst)
12    ea_int <= #1 1'b1;
13   else ea_int <= #1 !ea;
14 
15 always @(posedge clk)
16 begin
17   data_o <= #1
{buff[addr+3], buff[addr+2], buff[addr+1], buff[addr]}; 18 end

  這樣的儲存模型很難直接使用通用的儲存器進行實現。因為8051為8位微處理器,一般而言,程式儲存器位寬為8即可,然而OC8051的實現使用了預取指令,需要一次發射3條指令(具體可通過其內部程式碼得到證實。);上述程式碼所示模型,需要儲存器一個週期發射4Byte的程式,而由於8051送出來的地址是非字對齊的,因此這樣的行為模型需要儲存器支援非對其訪問。如:addr=1;則data_o={buff[4],buff[3],buff[2],buff[1]},而如果採用32位寬的儲存器,0~3個位元組是一組,4~7為一組,一次只能出來一組的32位資料。

  外部程式儲存器介面可以選擇CACHE方式和WB方式和直通方式,由於內部cpu實現方式,其行為模型依然需要和內部程式儲存器一樣。oc8051_xrom.v程式碼如下:

 1 module oc8051_xrom (rst, clk, addr, data, stb_i, cyc_i, ack_o);
 2 
 3 parameter DELAY=5;
 4 
 5 
 6 input rst, clk, stb_i, cyc_i;
 7 input [15:0] addr;
 8 output ack_o;
 9 output [31:0] data;
10 
11 
12 reg ack_o;
13 reg [31:0] data;
14 
15 reg [7:0] buff [0:65535];
16 //reg [7:0] buff [8388607:0];
17 reg [2:0] cnt;
18 integer i;
19 
20 
21 initial
22 begin
23 //  for (i=0; i<65536; i=i+1)
24 //    buff [i] = 8'h00;
25   $readmemh("../../../bench/in/oc8051_xrom.in", buff);
26 end
27 
28 always @(posedge clk or posedge rst)
29 begin
30   if (rst) begin
31     data <= #1 31'h0;
32     ack_o <= #1 1'b0;
33   end else if (stb_i && ((DELAY==3'b000) || (cnt==3'b000))) begin
34     data <= #1 {buff[addr+3], buff[addr+2], buff[addr+1], buff [addr]};
35     ack_o <= #1 1'b1;
36   end else
37     ack_o <= #1 1'b0;
38 end
39 
40 always @(posedge clk or posedge rst)
41 begin
42   if (rst)
43     cnt <= #1 DELAY;
44   else if (cnt == 3'b000)
45     cnt <= #1 DELAY;
46   else if (stb_i)
47     cnt <= #1 cnt - 3'b001;
48   else cnt <= #1 DELAY;
49 end
50 
51 endmodule

  可以看出基本和irom行為模型一樣,只不過支援引數定義其延遲週期(一般外部儲存器訪問速度會要慢些。)

  ps:今天在模擬過程發現,使用外部xrom(tb中讀入得ea=0:使用xrom,ea=1:使用irom),介面配置為WB介面(`define OC8051_WB),其延遲引數只有定義為DELAY=2時,程式才能正常執行,其他設定均會出錯。