深圳灰指甲怎麽治疗判断or1200cpu是跟sram 通过wishbone进行通信的

打算以后继续进行基于opencore的SOC的学习,写些关于openrisc,opencores的文章。这段时间有种感悟,怎样避免&再发明相同的车轮&呢,写博客是个好方法,利人利己。
&ODE2-115和DE2-70的存储器配置
DE2-115相对于DE2-70在存储器方面有两处不同的地方就是:其一,SDRAM容量加倍了,但是DE2-115中的两片SDRAM(32Mx16),在硬件上直接连在一块了(像ADDR,WE,CAS,RAS这些信号两块SDRAM都是共用的),若用就只能把两块32Mx16的SDRAM连在一起当做128M的SDRAM来用;而DE2-70上两块SDRAM(好像各是16Mx16)则是分别控制的,既可以连起来用,也可以分别当做两个独立的SDRAM来用。之所以这样是为了节省信号线吧,但却给DE2-115板上的资源利用带来了很大的不便,比方说,我现在要用友晶的D5M视频采集模块来采集数据,搭建SOC系统,来验证我写的H.264视频编码器。D5M中的DE2-115的参考设计是把整块SDRAM(128M)都当做是视频流的buffer的,这样也忒浪费了吧,况且我如果再搭建SOC系统,移植操作系统的话还有什么资源可用呢(需要把编码生成的bitstream数据通过网口传送到PC机端验证),那便只能拼板,而查了一下两块DE2-115拼板用的HSMC排线,居然要3000多元钱。而DE2-70虽然sdram和fpga的容量不如DE2-115但却可以满足我的要求。其二,DE2-115的sram,又从DE2-70的32bit 2M同步SRAM(SSRAM),恢复到了DE2(DE2-35)时期的16位SRAM时代,我不是很懂,是SRAM的价格比SSRAM的价格要便宜吗,不过我知道现在的软核处理器(OR1200)都是32位的SRAM控制起来要比SSRAM麻烦得多,得在32bit和16bit之间反复转换。
&OSram控制器的3中验证方案
本文设计了设计符合wishbone规范的SRAM控制器,用wishbone的总线功能模型BFM作了验证,在FPGA(DE2,DE2-115)上实现和验证,本文已给出了DE2-70上的wishbone总线规范的SSRAM控制器(用opencores的yadmc核来控制SSRAM,实在没有必要)。
以DE2上的256K x 16 IS61LV25616为例来做研究吧,其实DE2-115上的SRAM也一样。需要用到IS61LV25616的model。
我觉得,Sram_wrapper的验证方案有以下3种,第一种直接用BFM和所写的sram_wrapper相连,读写数据,第二种用BFM作为master接口,sram_wrapper作为slave接口连接到wishbone总线上进行验证,第三种方案是对整个soc平台做系统验证。第二种是否没有必要?
&ODE2中sram控制器的时序要求
IS61LV25616的一些常用引脚的功能
读和写时序按照参照datasheet中所介绍的这两种方式
在wishbone接口中需满足途中的基本时序要求。
IS61LV25616的verilog
model在网络上很容易可以找到
1 // IS61LV25616 Asynchronous SRAM, 256K x 16 = 4M; speed: 10ns.
2 // N 1) Please include "+define+ OEb" in running script if you want to check
timing in the case of OE_ being set.
2) Please specify access time by defining tAC_10 or tAC_12.
6 `define OEb
7 `define tAC_10
//tAC_10 or tAC_12 defines different parameters
8 `timescale 1ns/1ns
10 module IS61LV25616 (A, IO, CE_, OE_, WE_, LB_, UB_); 11
12 parameter dqbits = 16; 13 parameter memdepth = 262143; 14 parameter addbits = 19; 15 parameter Toha
17 parameter Tsa
19 `ifdef tAC_10
//if "`define tAC_10 " at beginning,sentences below are compiled 20
parameter Taa
Thzce = 3, 22
Thzwe = 5; 23 `endif 24
25 `ifdef tAC_12
//if "`define tAC_12 " at beginning,sentences below are compiled 26
parameter Taa
Thzce = 5, 28
Thzwe = 6; 29 `endif 30
31 input CE_, OE_, WE_, LB_, UB_; 32 input [(addbits - 1) : 0] A; 33 inout [(dqbits - 1) : 0] IO; 34
35 wire [(dqbits - 1) : 0] 36 reg
[(dqbits/2 - 1) : 0] bank0 [0 : memdepth];
[(dqbits/2 - 1) : 0] bank1 [0 : memdepth]; 38 //array to simulate SRAM 39 // wire [(dqbits - 1) : 0] memprobe = {bank1[A], bank0[A]}; 40
41 wire r_en = WE_ & (~CE_) & (~OE_);
//WE=1,CE=OE=0 Read 42 wire w_en = (~WE_) & (~CE_) & ((~LB_) | (~UB_)); //WE=CE=0,LB or UB="0",OE=x Write 43 assign #(r_en ? Taa : Thzce) IO = r_en ? dout : 16'
45 initial 46
$timeformat (-9, 0.1, " ns", 10); //show current simulation time 47
48 assign dout [(dqbits/2 - 1) : 0]
= LB_ ? 8'bz : bank0[A]; 49 assign dout [(dqbits - 1) : (dqbits/2)] = UB_ ? 8'bz : bank1[A]; 50
51 always @(A or w_en) 52
//address setup time 54
if (w_en) 55
bank0[A] = LB_ ? bank0[A] : IO [(dqbits/2 - 1) : 0]; 58
bank1[A] = UB_ ? bank1[A] : IO [(dqbits - 1)
: (dqbits/2)]; 59
62 // Timing Check 63 `ifdef tAC_10 64
//sepcify delay 65
specparam 66
tPWE2 = 10, 71
tPWE1 = 8, 72
= 8; 73 `else 74
75 `ifdef tAC_12 76
specify 77
specparam 78
tPWE2 = 12, 83
tPWE1 = 8, 84
= 8; 85 `endif 86 `endif 87
$setup (A, negedge CE_, tSA); 89
$setup (A, posedge CE_, tAW); 90
$setup (IO, posedge CE_, tSD); 91
$setup (A, negedge WE_, tSA); 92
$setup (IO, posedge WE_, tSD); 93
$setup (A, negedge LB_, tSA); 94
$setup (A, negedge UB_, tSA); 95
$width (negedge CE_, tSCE); 97
$width (negedge LB_, tPBW); 98
$width (negedge UB_, tPBW); 99
`ifdef OEb100
$width (negedge WE_, tPWE1);101
$width (negedge WE_, tPWE2);103
`endif104 105
endspecify106 107 endmodule
&OSram控制器的设计
Sram_wrapper用状态机控制的,两个周期用于读写低16位,两个周期用于读写高16位,sram
datasheet中的时序应该能满足,但是过于保守了,效率应该低了。
Sram_wrapper的源码
// Author(s):// - Huailu Ren, hlren.//// Revision 1.1
hlren// created//// synopsys translate_off`include "timescale.v"// synopsys translate_onmodule sram_wrapper (
//wb_dat_o,
// Bi-Directional
// Outputs
SRAM_ADDR,
SRAM_LB_N,
SRAM_UB_N,
SRAM_CE_N,
SRAM_OE_N,
SRAM_WE_N);//// clock and reset signals//
wb_rst_i;//// WB slave i/f//
[31:0] wb_dat_i;
output [31:0] wb_dat_o;
[31:0] wb_adr_i;
[ 3:0] wb_sel_i;
wb_err_o;//// SRAM port//
// SRAM Data bus 16 Bits
output [17:0] SRAM_ADDR;
// SRAM Address bus 18 Bits
SRAM_LB_N;
// SRAM Low-byte Data Mask
SRAM_UB_N;
// SRAM High-byte Data Mask
SRAM_CE_N;
// SRAM Chip chipselect
SRAM_OE_N;
// SRAM Output chipselect
SRAM_WE_N;
// SRAM Write chipselect
[17:0] SRAM_ADDR;
SRAM_LB_N;
SRAM_UB_N;
SRAM_CE_N;
SRAM_OE_N;
SRAM_WE_N;
reg [3:0] state, state_r;
reg [15:0] wb_data_o_l, wb_data_o_u;
reg [16:0] wb_addr_i_
reg [31:0] wb_data_i_
//reg [31:0] wb_data_o_
reg [ 3:0] wb_sel_i_
reg ack_we, ack_// *****************************************************************************//
FSM// *****************************************************************************
localparam IDLE = 0;
localparam WE0
localparam WE1
localparam WE2
localparam WE3
localparam RD0
localparam RD1
localparam RD2
localparam RD3
localparam ACK
assign SRAM_DQ =
( (state_r == WE0 || state_r == WE1) ? wb_data_i_reg[15: 0]
: (state_r == WE2 || state_r == WE3) ? wb_data_i_reg[31:16]
: 16'hzzzz);
assign wb_dat_o = {wb_data_o_u,wb_data_o_l};
assign wb_ack_o = (state == ACK);
assign wb_err_o = wb_cyc_i & wb_stb_i & (| wb_adr_i[23:19]);
always @ (posedge wb_clk_i or posedge wb_rst_i) begin
if(wb_rst_i)
state &= IDLE;
else begin
case (state)
IDLE : begin
if (wb_cyc_i & wb_stb_i & wb_we_i & ~ack_we)
state &= WE0;
else if (wb_cyc_i & wb_stb_i & ~wb_err_o & ~wb_we_i & ~ack_re)
state &= RD0;
WE0 : state &= WE1;
WE1 : state &= WE2;
WE2 : state &= WE3;
WE3 : state &= ACK;
RD0 : state &= RD1;
RD1 : state &= RD2;
RD2 : state &= RD3;
RD3 : state &= ACK;
ACK : state &= IDLE;
default : state &= IDLE;
always @ (posedge wb_clk_i or posedge wb_rst_i) begin
if (wb_rst_i)
state_r &= IDLE;
state_r &=
end//// Write acknowledge//
always @ (posedge wb_clk_i or posedge wb_rst_i) begin
if (wb_rst_i)
ack_we &= 1'b0;
if (wb_cyc_i & wb_stb_i & wb_we_i & ~ack_we)
ack_we &= #1 1'b1;
ack_we &= #1 1'b0;
end //// Read acknowledge//
always @ (posedge wb_clk_i or posedge wb_rst_i) begin
if (wb_rst_i)
ack_re &= 1'b0;
if (wb_cyc_i & wb_stb_i & ~wb_err_o & ~wb_we_i & ~ack_re)
ack_re &= #1 1'b1;
ack_re &= #1 1'b0;
always @ (posedge wb_clk_i or posedge wb_rst_i) begin
if (wb_rst_i) begin
wb_addr_i_reg &= 32'b0;
wb_data_i_reg &= 32'b0;
wb_sel_i_reg
if (wb_cyc_i & wb_stb_i & ~ack_re & ~ack_we)
wb_addr_i_reg &= wb_adr_i[18:2];
wb_data_i_reg &= wb_dat_i[31:0];
wb_sel_i_reg
&= wb_sel_i[3:0];
always @ (posedge wb_clk_i or posedge wb_rst_i) begin
if (wb_rst_i) begin
SRAM_ADDR &= 18'b0;
case (state)
WE0, WE1, RD0, RD1 :
SRAM_ADDR &= {wb_addr_i_reg[16:0], 1'b0};
WE2, WE3, RD2, RD3 :
SRAM_ADDR &= {wb_addr_i_reg[16:0], 1'b1};
default : SRAM_ADDR &= 18'
always @ (posedge wb_clk_i or posedge wb_rst_i) begin
if (wb_rst_i) begin
SRAM_LB_N &= 1'b1;
case (state)
WE0, WE1, RD0, RD1 :
SRAM_LB_N &= ~wb_sel_i[0];
WE2, WE3, RD2, RD3 :
SRAM_LB_N &= ~wb_sel_i[2];
SRAM_LB_N &= 1'b1;
always @ (posedge wb_clk_i or posedge wb_rst_i) begin
if (wb_rst_i) begin
SRAM_UB_N &= 1'b1;
case (state)
WE0, WE1, RD0, RD1 :
SRAM_UB_N &= ~wb_sel_i[1];
WE2, WE3, RD2, RD3 :
SRAM_UB_N &= ~wb_sel_i[3];
SRAM_UB_N &= 1'b1;
always @ (posedge wb_clk_i or posedge wb_rst_i) begin
if (wb_rst_i) begin
SRAM_CE_N &= 1'b1;
case (state)
WE0, WE1, RD0, RD1 :
SRAM_CE_N &= 1'b0;
WE2, WE3, RD2, RD3 :
SRAM_CE_N &= 1'b0;
SRAM_CE_N &= 1'b1;
always @ (posedge wb_clk_i or posedge wb_rst_i) begin
if (wb_rst_i) begin
SRAM_OE_N &= 1'b1;
case (state)
RD0, RD1, RD2, RD3 :
SRAM_OE_N &= 1'b0;
SRAM_OE_N &= 1'b1;
always @ (posedge wb_clk_i or posedge wb_rst_i) begin
if (wb_rst_i) begin
SRAM_WE_N &= 1'b1;
case (state)
WE0, WE1, WE2, WE3 :
SRAM_WE_N &= 1'b0;
SRAM_WE_N &= 1'b1;
// assemble ouput data
always @ (posedge wb_clk_i or posedge wb_rst_i) begin
if (wb_rst_i) begin
wb_data_o_l &= 16'b0;
wb_data_o_u &= 16'b0;
case (state_r)
RD0, RD1 :
wb_data_o_l &= SRAM_DQ;
RD2, RD3 :
wb_data_o_u &= SRAM_DQ;
endendmodule
&OSram_wrapper的wishbone BFM验证
Sram_wrapper的BFM验证的testbench代码如下:
1 // Author(s):
2 // - Huailu Ren, hlren.
5 // Revision 1.1
6 // created
9 // synopsys translate_off 10 `include "timescale.v" 11 // synopsys translate_on 12
13 module tb_sram_ 14
15 // 16 // clock and reset signals 17 // 18
wb_clk_i; 19
wb_rst_i; 20
21 // ***************************************************************************** 22 //
wishbone master bus functional model 23 // ***************************************************************************** 24
wire [31:0] wb_din_w; 26
wire [31:0] wb_dout_w; 27
wire [31:0] wb_adr_w; 28
wire [ 3:0] wb_sel_w; 29
wb_we_w; 30
wb_cyc_w; 31
wb_stb_w; 32
wb_ack_w; 33
wb_err_w; 34
wb_mast u_wb_mast( 36
( wb_clk_i ), 37
( wb_rst_i ), 38
( wb_adr_w ), 40
( wb_din_w ), 41
.dout ( wb_dout_w ), 42
( wb_cyc_w ), 43
( wb_stb_w ), 44
( wb_sel_w ), 45
( wb_we_w ), 46
( wb_ack_w ), 47
( wb_err_w ), 48
( wb_rty_w ) 49
51 // ***************************************************************************** 52 //
sram controller 53 // ***************************************************************************** 54
wire [15:0]
SRAM_DQ_w;
// SRAM Data bus 16 Bits 56
wire [17:0] SRAM_ADDR_w;
// SRAM Address bus 18 Bits 57
SRAM_LB_N_w;
// SRAM Low-byte Data Mask 58
SRAM_UB_N_w;
// SRAM High-byte Data Mask 59
SRAM_CE_N_w;
// SRAM Chip chipselect 60
SRAM_OE_N_w;
// SRAM Output chipselect 61
SRAM_WE_N_w;
// SRAM Write chipselect 62
sram_wrapper DUT_sram_wrapper( 64
( wb_clk_i ), 65
( wb_rst_i ), 66
( wb_dout_w ), 68
( wb_din_w ), 69
( wb_adr_w ), 70
( wb_sel_w ), 71
( wb_we_w ), 72
( wb_cyc_w ), 73
( wb_stb_w ), 74
( wb_ack_w ), 75
( wb_err_w ), 76
// SRAM 78
( SRAM_DQ_w ), 79
.SRAM_ADDR ( SRAM_ADDR_w ), 80
.SRAM_LB_N ( SRAM_LB_N_w ), 81
.SRAM_UB_N ( SRAM_UB_N_w ), 82
.SRAM_CE_N ( SRAM_CE_N_w ), 83
.SRAM_OE_N ( SRAM_OE_N_w ), 84
.SRAM_WE_N ( SRAM_WE_N_w ) 85 ); 86
87 // ***************************************************************************** 88 //
sram model 89 // ***************************************************************************** 90
IS61LV25616 u_sram_model( 92
( {1'b0,SRAM_ADDR_w[17:0]} ), 93
( SRAM_DQ_w ), 94
.CE_ ( SRAM_CE_N_w ), 95
.OE_ ( SRAM_OE_N_w ), 96
.WE_ ( SRAM_WE_N_w ), 97
.LB_ ( SRAM_LB_N_w ), 98
.UB_ ( SRAM_UB_N_w ) 99
initial begin103
wb_clk_i &= 0;104
wb_rst_i &= 0;105
always@(wb_clk_i)
#10 wb_clk_i &= ~wb_clk_i;109
end110 111
reg [31:0] tmp_112 113
reg [31:0] d0,d1,d2,d3;114 115
initial begin116
repeat (1) @ (posedge wb_clk_i);117
wb_rst_i &= 1;118
repeat (3) @ (posedge wb_clk_i);119
wb_rst_i &= 0;120
//write your test here!121
repeat (1) @ (posedge wb_clk_i);122
u_wb_mast.wb_wr1(32'h04,4'b1111,32'haabbccdd);123
u_wb_mast.wb_rd1(32'h04,4'b1111,tmp_dat);124
u_wb_mast.wb_wr1(32'h08,4'b1111,32'hddccbbaa);125
u_wb_mast.wb_rd1(32'h08,4'b1111,tmp_dat);126
$display($time,,"readfrom %x, value = %x\n",32'h00,tmp_dat);127
//adr,adr+4,adr+8,adr+12128
u_wb_mast.wb_wr4(32'h00,4'b1111,1,32'h01,32'h02,32'h03,32'h04);129
u_wb_mast.wb_rd4(32'h00,4'b1111,3,d0,d1,d2,d3);130
$display($time,,"read4from %x, value = %x , %x , %x , %x\n",32'h05,d0,d1,d2,d3);131
initial137
$fsdbDumpfile("sram_wrapper.fsdb");139
end141 endmodule
# INFO: WISHBONE MASTER MODEL INSTANTIATED
(tb_sram_wrapper.u_wb_mast)
#&&&&&&&&&&&&&&&&& 571 readfrom ,
value = ddccbbaa
#&&&&&&&&&&&&&&&& 1891 read4from ,
&OSram_wrapper的soc系统仿真验证
加入sram_wrapper模块之后,并没有在sram空间上跑代码,只是对sram作了以下简单的读写实验,测试代码如下所示
1 #include "orsocdef.h" 2 #include "board.h" 3 #include "uart.h" 4
5 int 6 main (void) 7 { 8
long gpio_ 9
REG32 (RGPIO_OE) = 0xffffffff;10 11
uart_init();12
uart_print_str("2Hello World!\n");14
int t0, t1;17
t0 = 0xaabbccdd;18
for(i=0;i&10;i++){19
//REG32 (RGPIO_OUT) = t0;20
REG32 (SRAM_BASE + i*4) = t0;21
t1 = REG32 (SRAM_BASE + i*4);22
//REG32 (RGPIO_OUT) = t1;23
if(t0 == t1)24
uart_print_str("correct!\n");25
uart_print_str("error!\n");27
t0 = t0 - 0x;28
while(1){31
gpio_in = REG32 (RGPIO_IN);32
gpio_in = gpio_in & 0x0000ffff;33
REG32 (RGPIO_OUT) = gpio_34
return 0;37 }
在fpga上的验证几个月前跑过,没有留图,结果与设想的一致,是没有错误的。
&OSsram控制器的设计与验证
Ssram控制器的设计与验证,与sram相似,只不过它是同步的,ssram的model自己写即可,而且它是32位的,控制起来就简单多了。
关于DE2-70上的ssram控制器,参考设计中用yadmc核来控制ssram,是没有必要的。Ssram的控制代码如下
1 //----------------------------------------------------------------------------//
2 // Filename
: ssram_wrapper.v
3 // Author
: Huailu Ren ...()
4 // Email
5 // Created
6 //----------------------------------------------------------------------------//
7 // Description
// 10 //----------------------------------------------------------------------------// 11
12 module ssram_wrapper( 13
wb_stb_i, 17
wb_cyc_i, 18
output reg
wb_ack_o, 19
[31: 0] wb_addr_i, 20
[ 3: 0] wb_sel_i, 21
wb_we_i, 22
[31: 0] wb_data_i, 23
[31: 0] wb_data_o, 24
// SSRAM side 25
[31: 0] SRAM_DQ,
SRAM Data Bus 32 Bits 26
[ 3: 0] SRAM_DPA,
SRAM Parity Data Bus 27
// Outputs
SRAM Clock 29
[18: 0] SRAM_A,
SRAM Address bus 21 Bits 30
SRAM_ADSC_N, //
SRAM Controller Address Status
SRAM_ADSP_N, //
SRAM Processor Address Status 32
SRAM_ADV_N,
SRAM Burst Address Advance 33
[ 3: 0] SRAM_BE_N,
SRAM Byte Write Enable 34
SRAM_CE1_N,
SRAM Chip Enable 35
SRAM Chip Enable 36
SRAM_CE3_N,
SRAM Chip Enable 37
SRAM_GW_N,
SRAM Global Write Enable 38
SRAM_OE_N,
SRAM Output Enable 39
SRAM Write Enable 40
// request signal 43
// request signal's rising edge 46
request_ 47
wire request_rising_ 48
wire is_read, is_ 49
// ack signal 51
// get request signal 54
assign request = wb_stb_i & wb_cyc_i; 55
// Internal Assignments 57
assign is_read
= wb_stb_i & wb_cyc_i & ~wb_we_i; 58
assign is_write = wb_stb_i & wb_cyc_i & wb_we_i; 59
// Output Assignments 61
assign wb_data_o
= SRAM_DQ; 62
assign SRAM_DQ[31:24] = (wb_sel_i[3] & is_write) ? wb_data_i[31:24] : 8' 64
assign SRAM_DQ[23:16] = (wb_sel_i[2] & is_write) ? wb_data_i[23:16] : 8' 65
assign SRAM_DQ[15: 8] = (wb_sel_i[1] & is_write) ? wb_data_i[15: 8] : 8' 66
assign SRAM_DQ[ 7: 0] = (wb_sel_i[0] & is_write) ? wb_data_i[ 7: 0] : 8' 67
assign SRAM_DPA
assign SRAM_CLK
= clk_i; 71
assign SRAM_A
= wb_addr_i[20:2]; 72
assign SRAM_ADSC_N
= ~(is_write); 73
assign SRAM_ADSP_N
= ~(is_read); 74
assign SRAM_ADV_N
= 1'b1; 75
assign SRAM_BE_N[3] = ~(wb_sel_i[3] & request); 76
assign SRAM_BE_N[2] = ~(wb_sel_i[2] & request); 77
assign SRAM_BE_N[1] = ~(wb_sel_i[1] & request); 78
assign SRAM_BE_N[0] = ~(wb_sel_i[0] & request); 79
assign SRAM_CE1_N
assign SRAM_CE2
= 1'b1; 81
assign SRAM_CE3_N
= 1'b0; 82
assign SRAM_GW_N
= 1'b1; 83
assign SRAM_OE_N
assign SRAM_WE_N
// get the rising edge of request signal 87
always @ (posedge clk_i) 88
if(rst_i == 1) 90
request_delay &= 0; 91
request_delay &= 93
assign request_rising_edge = (request_delay ^ request) & 96
// generate a 1 cycle acknowledgement for each request rising edge 98
always @ (posedge clk_i) 99
if (rst_i == 1)101
ram_ack &= 0;102
else if (request_rising_edge == 1)103
ram_ack &= 1;104
ram_ack &= 0;106
end107 108
// register wb_ack output, because onchip ram0 uses registered output109
always @ (posedge clk_i)110
if (rst_i == 1)112
wb_ack_o &= 0;113
wb_ack_o &= ram_115
end116 117 endmodule
并没有写testbench,直接在fpga上跑了,而且是跑的程序。经验证没有问题。
源码可以在这里下载
稍后。。。
用所写的sram_wrapper基于DE2平台让or1200在sram空间跑下代码
修改以下用所写的sram_wrapper移植到DE2-115平台上
To Do--关于opencore,or1200的soc平台
OR1200的引导方案设计(基于硬件或者软件uart控制)
移植uc/os II操作系统
驱动起来DE2-70上的网卡
加入jtag模块
移植u-boot
移植ucLinux
阅读(...) 评论()软核处理器or1200内部设计分析(40)
以下内容摘自《步步惊芯——软核处理器内部设计分析》一书
& & & 完整的OR1200处理器流水线数据通路图,如图9.12所示,图中显示了数据处理类、特殊寄存器访问类、转移类、异常处理类、乘法除法类、加载存储类指令处理过程中流水线各个阶段的数据流转。
& & & (1)取指阶段:GENPC模块计算指令地址,然后通过指令Wishbone总线从指令存储器中取得指令,取得的指令送入IF模块,该指令进入流水线。
& & & (2)译码阶段:取出指令需要的通用寄存器的值dataa、datab,同时对指令中可能有的立即数进行符号扩展或零扩展得到id_simm,OPERAND_MUX模块从中选择两个数据作为下一步的运算数据operand_a、operand_b,为了解决流水线数据相关的问题,将执行阶段计算的结果muxout也作为OPERAND_MUX模块的备选数据。
& & & (3)执行阶段:分七种情况:
& & & A、如果是数据处理类指令,那么ALU模块依据操作码alu_op、alu_op2、comp_op,对操作数a、b进行运算,a、b就是译码阶段的输出operand_a、operand_b,计算过程会改变SPRS中特殊寄存器SR的CY、OV、F位,计算的结果result输出到WB_MUX模块。
& & & B、如果是特殊寄存器访问类指令,那么SPRS模块通过a、ex_simm计算SPR地址,依据指令进行SPR的读写操作,写操作时将b的值写入SPR,读操作时将SPR的值读入并通过to_wbmux输出到WB_MUX模块。
& & & C、如果是转移类指令,那么GENPC会依据输入的ex_branch_op、ex_branch_addtarget、操作数b的值确定新的指令地址icpu_adr_o,其中ex_branch_addtarget作为相对转移时的目标地址,其计算方法是处于执行阶段指令地址加上指令中26位立即数的符号扩展,操作数b作为绝对转移时的目标地址。如果转移指令是l.jalr、l.jal,则还会将转移指令地址加8的值送入WB_MUX模块。
& & & D、如果是异常处理类指令,或者发生了异常,EXCEPTION会判断异常类型,并输出到GENPC模块,GENPC会依据异常类型except_type确定新的指令地址icpu_adr_o。
& & & E、如果是乘法除法类指令,那么MULTI_MAC模块依据操作码,对a、b进行乘法、除法、乘累加等运算,运算结果result输出到ALU模块,此时ALU的输出result就等于乘法除法运算结果。
& & & F、如果是存储类指令,那么LSU会依据muxed_a、ex_simm计算要存储到的目的地址,然后将操作数b的值通过数据Wishbone总线的接口dcpu_dat_o送入数据存储器。
& & & G、如果是加载类指令,那么LSU会依据muxed_a、ex_simm计算要加载的数据地址,加载数据通过数据Wishbone总线送入LSU模块的接口lsu_datain,LSU模块将从中取出有效数据然后通过lsu_dataout送入WB_MUX模块。
& & & WB_MUX模块是一个多路选择器,依据rfwb_op从多个输入中选择一个作为输出,对数据处理类、乘法除法类指令而言WB_MUX将ALU的计算结果作为输出muxout的值,对于特殊寄存器访问类指令而言WB_MUX将SPRS的输出to_wbmux作为muxout的值,对于加载类指令而言WB_MUX将LSU的输出lsu_dataout作为muxout的值,如果存在要写入的目的寄存器,那么muxout将被写入目的寄存器。对于l.jalr、l.jal指令而言,转移指令地址加8的和作为muxout的值,并且写入寄存器r9。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:150381次
积分:2738
积分:2738
排名:第9099名
原创:119篇
转载:10篇
评论:139条
(2)(2)(8)(2)(3)(1)(6)(1)(4)(8)(13)(13)(19)(11)(8)(8)(12)(2)(1)(1)(1)(1)(1)(1)> 强烈推荐:wishbone总线详细介绍
管理员:&&&&人数:232小组积分:2544简介:嵌入式相关的,电路相关的,都是讨论的话题多多交流共同进步!hello!Electronicworld!小组公告小组暂无公告.&&|&&&&|&&
需要确认注册邮箱后才能下载,
楼主&&[其他]&
强烈推荐:wishbone总线详细介绍
6年会员勋章目前未领取。领取条件:&凡是注册时间六年以上的活跃用户即可领取该勋章。
积分:990分
总积分:1959分
发表于 09:19
图1 Wishbone总线规范中使用的主要信号(一个点到点互联的例子)在图1中,主设备具有遵守Wishbone规范的主设备接口,从设备具有遵守Wishbone规范的从设备接口,INTERCON模块将主设备和从设备的对应数据、地址和控制线连接起来,SYSCON模块提供时钟和复位信号,这两个信号被送入主设备和从设备。图1给出了Wishbone接口的常见信号,这些信号有些是必须的,有些是可选的。这些信号的基本功能描述如下:CLK_O/CLK_I:时钟信号。时钟信号由SYSCON模块产生,并送入各个主设备和从设备。SYSCON通常内部存在一个锁相环,将来源于芯片外的晶体振荡器或者时钟输入信号整形、分频或者倍频为芯片内所需要的时钟信号。所有Wishbone信号都同步到时钟信号上,包括复位信号。RST_O/RST_I:同步复位信号,高电平有效。复位信号由SYSCON模块产生,并送入各主设备及从设备。DAT_O()/DAT_I():主设备和从设备的之间的数据信号,数据可以由主设备传送给从设备,也可以由从设备传送给主设备。一对主设备和从设备之间最多存在两条数据总线,一条用于主设备向从设备传输数据,另外一条用于从设备向主设备传输数据。Wishbone规定数据总线的最大宽度为64位,这一规定实际上是考虑到目前商用处理器的最大位数为64,实际上数据总线的宽度可以是任意值。就笔者看来,在64位处理器以后,处理器将向多核方向发展,总线将向高速串行方向发展。ADR_O(n…m)/ADR_I(n…m):地址信号,主设备输出地址到从设备。n取决于IP核的地址宽度,m取决于数据总线DAT_O()/DAT_I()的宽度和粒度。数据总线的粒度指的是数据总线能够一次传送的最小比特数,很多处理器如ARM的数据总线的粒度为1个字节,但是也有一些处理器如CEVA TeakLite DSP的数据总线粒度为2个字节。一个位宽为32比特、粒度为1个字节的数据总线的地址信号应定义为ADR_O(n…2)/ADR_I(n…2)。在传送数据时,具体哪些字节有效通过SEL_O()/SEL_I()信号(见下文)控制。TGD_O/TGD_I()、TGA_O()/TGA_I():TGD_O/TGD_I()为数据标签,具体讲是附加于在数据总线DAT_O()/DAT_I()的标签,该标签可以用于传送关于数据总线的额外信息如奇偶校验信息、时间戳信息等。TGA_O/TGA_I()为地址标签,具体讲是附加于在地址总线ADR_O()/ADR_I()的标签,该标签可以用于传送关于地址总线的额外信息如地址总线奇偶校验信息、存储器保护信息等。Wishbone只规定了TGD_O/TGD_I和TGA_O()/TGA_I()的接口时序,用户可以定义TGD_O/TGD_I的具体含义。TGC_O/TGC_I():TGC_O/TGC_I()为总线周期标签,该标签可以用于传送关于当前总线周期所进行操作的描述如操作类型(包括单次操作、块操作、RMW操作)、中断应答类型、缓存操作类型等。类似的,Wishbone只规定了TGC_O/TGC_I()的接口时序,用户可以定义TGD_O/TGD_I的具体含义。ACK_O/ACK_I、ERR_O/ERR_I、RTY_O/RTY_I:主从设备间的操作结束方式信号。ACK表示成功,ERR表示错误,RTY表示重试(Retry)。操作总是在某一总线周期内完成的,因此操作结束方式也称为总线周期结束方式。成功是操作的正常结束方式,错误表示操作失败,造成失败的原因可能是地址或者数据校验错误,写操作或者读操作不支持等。重试表示从设备当前忙,不能及时处理该操作,该操作可以稍后重新发起。接收到操作失败或者重试后,主设备如何响应取决于主设备的设计者。SEL_O()/SEL_I():有效数据总线选择信号,标识当前操作中数据总线上哪些比特是有效的,以总线粒度为单位。SEL_O()/SEL_I()的宽度为数据总线宽度除以数据总线粒度。比如一个具有32位宽、粒度为1个字节的数据总线的选择信号应定义为SEL_O(3:0)/ SEL_I(3:0),SEL(4’b1001)代表当前操作中数据总线的最高和最低字节有效。CYC_O/CYC_I、LOCK_O/LOCK_I、GNT_O()/GNT_I:总线周期信号CYC_O/CYC_I有效代表一个主设备请求总线使用权或者正在占有总线,但是不一定正在进行总线操作(是否正在进行总线操作取决于选通信号STB_O/STB_I是否有效)。只有该信号有效,Wishbone主设备和从设备接口的其它信号才有意义。CYC_O/CYC_I信号在一次总线操作过程中必须持续有效,比如一次块读操作可能需要多个时钟周期,CYC_O/CYC_I信号必须保持持续有效。实际上,该信号的实际作用等同于其他总线标准中的仲裁申请信号。当存在多个主设备时,它们可能希望同时进行总线操作,主设备通过仲裁申请信号向仲裁器申请总线占有权,仲裁器通过一定的仲裁优先级逻辑向其中一个选定的主设备发送总线允许信号GNT_O()/GNT_I,表示该主设备可以占用总线。GNT_O()是仲裁器输出的允许信号,一般有多个;而对于一个主设备,其允许信号输入GNT_I却只有一个。一次总线操作可能需要多个时钟周期,比如一次块操作。在操作过程中,仲裁器可能会提前将总线占用权收回并分配给其他主设备从而打断当前主设备的操作,LOCK_O/LOCK_I有效代表本次总线操作是不可打断的。仲裁器收到LOCK_I信号,就不会提前收回总线使用权。图1中只有一个主设备和一个从设备,因此没画出仲裁器模块,该模块可以视为是INTERCON的一部分,见本章最后给出的例子。STB_O/STB_I:选通信号。选通有效代表主设备发起一次总线操作。只有选通信号有效(此时CYC_O/CYC_I也必须为高),ADR_O/ADR_I()、DAT_O()/DAT_I()、SEL_O()/SEL_I()才有意义。在Wishbone总线规范中,CYC_O/CYC_I是最高层的控制信号,只有该信号有效,STB_O/STB_I信号才有意义。一个信号有意义是指该信号的当前值是需要主设备或者从设备解释的,0为无效,1为有效,而一个信号没有意义是指该信号的当前值主设备和从设备不必关心,是0还是1都无效。WE_O/WE_I:写使能信号,代表当前周期中进行的操作是写操作还是读操作。1代表写,0代表读。该从设备的Wishbone文档如表5。表5 从设备的Wishbone文档描述规范功能8比特从设备支持的总线周期类型从设备读写从设备块读写从设备RMW操作数据端口宽度数据端口粒度数据端口最大操作数尺寸数据传输顺序888大端或者小端支持的信号及其对应WISHBONE信号列表align = "center" 信号名WISHBONE等效ACK_OACK_OCLK_ICLK_IDAT_I[7:0]DAT_I()DAT_O[7:0]DAT_O()RST_IRST_ISTB_ISTB_IWE_IWE_I该从设备的Wishbone文档如表6。表6 从设备的Wishbone文档描述规范功能随机数生成器,32比特从设备支持的总线周期类型从设备读写从设备块读写从设备RMW操作数据端口宽度数据端口粒度数据端口最大操作数尺寸数据传输顺序32832大端或者小端支持的信号及其对应WISHBONE信号列表align = "center" 信号名WISHBONE等效ACK_OACK_OCLK_ICLK_IDAT_I[7:0]DAT_I()DAT_O[7:0]DAT_O()RST_IRST_ISTB_ISTB_IWE_IWE_ISEL_I[3:0]SEL_I()所使用的Flash实际上是一个只读的Flash,模型仿真了典型的Nor Flash如INTEL 28f016s3 FLASH的读时序,而忽略了写时序。主设备每读32比特的数据需要4个时钟周期。其源代码列出如下:
module flash_top (
wb_clk_i, wb_rst_i,&
wb_dat_i, wb_dat_o, wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i,
wb_stb_i, wb_ack_o, wb_err_o);//内部数据线和寄存器reg [7:0]
mem [2097151:0]; //2M字节wire [31:0]
wb_err_o;reg [31:0]
prev_adr;reg [1:0]
delay;wire
wb_err;&//assign adr = {8'h00, wb_adr_i[23:2], 2'b00};&//FLASH的初始化initial $readmemh("../src/flash.in", mem, 0);&//读模型,数据被一次赋值assign wb_dat_o[7:0] = wb_adr_i[23:0] & 65535 ? mem[adr+3] : 8'h00;assign wb_dat_o[15:8] = wb_adr_i[23:0] & 65535 ? mem[adr+2] : 8'h00;assign wb_dat_o[23:16] = wb_adr_i[23:0] & 65535 ? mem[adr+1] : 8'h00; assign wb_dat_o[31:24] = wb_adr_i[23:0] & 65535 ? mem[adr+0] : 8'h00; // delay逻辑,该逻辑的目的是每次发生读操作,都在4个周期后产生应答信号wb_ack_oalways @(posedge wb_clk_i or posedge wb_rst_i) if (wb_rst_i) begin
delay &= #1 2'd3;
prev_adr &= #1 32'h; end else if (delay && (wb_adr_i == prev_adr) && wb_cyc_i && wb_stb_i)
delay &= #1 delay - 2'd1; else if (wb_ack_o || wb_err_o || (wb_adr_i != prev_adr) || ~wb_stb_i) begin
delay &= #1 2'd0; // delay ... can range from 3 to 0
prev_adr &= #1 wb_adr_i; endassign wb_ack_o = wb_cyc_i & wb_stb_i & ~wb_err & (delay == 2'd0) & (wb_adr_i == prev_adr);//总线操作错误信号,错误产生的原因是输入地址值过大assign wb_err = wb_cyc_i & wb_stb_i & (delay == 2'd0) & (|wb_adr_i[23:21]);
always @(posedge wb_clk_i or posedge wb_rst_i) if (wb_rst_i)
wb_err_o &= #1 1'b0; else
wb_err_o &= #1 wb_err & !wb_err_o;
marioforever 编辑于 11:01
--- 现有 1个主题,共 1页,目前第 1页 ---&&
点击,立即回复。
EDN China官方微信
扫一扫关注,获取电子新知,设计灵感
IC厂商小组
在线研讨会
赞助商链接
2016 EDN China -- Use of this website is subject to its terms of use.
京ICP备号-4 |
京公网安备37 |
新版社区已上线,旧版论坛、博客将停用
1、为防数据丢失,旧版论坛、博客不再接受发帖;
2、老用户只需重设密码,即可直接登录新平台;
3、新版博客将于8月底完美归来,敬请期待;
4、全新论坛、问答,体验升级、手机阅读更方便。

我要回帖

更多关于 宫颈糜烂怎麽治 的文章

 

随机推荐