引言
学习和研究OR,wishbone是绕不开的问题。本小节就做一个简单的实验,进一步加深对wishbone总线的理解。
6.1 总线timing
请参考官方spec,链接如下:
http://opencores.org/opencores,wishbone
附:
http://blog.csdn.net/column/details/ce123-wishbone.html
6.2 实验内容
一个master,一个slave,master通过wishbone传递数据(两个操作数)给slave,slave做加法运算,将结果传给master。
如图:
6.3 用modelsim emulate 结果,可以看到1 + 2 = 3
6.4 实验code,写blog的编辑器xheditor真是无语了。这个实验的5个.v文件都是分开的,但是这个编辑器非要弄到一起,人工还修改不了。
1>master
//`include "wb_conbus_defines.v"
`timescale 1ns / 10ps
module my_master_model(clk, rst, adr, din, dout, cyc, stb, sel, we, ack, err, rty);
input ack, err, rty;
input clk, rst;
input [31:0] din;
output [31:0] adr;
output [31:0] dout;
output cyc, stb;
output [3:0] sel;
output we;
//external registers
reg [31:0] adr,dout;
reg cyc,stb,we;
reg [3:0] sel;
//internal registers
reg [31:0] result;
initial
begin
adr=32'hffff_ffff;
dout=32'hxxxx_xxxx;
cyc=0;
stb=0;
sel=4'hx;
we=1'hx;
result=32'hxxxx_xxxx;
#10;
end
task write_numbers;
input [31:0] slave_addr;
input [31:0] operd_a,operd_b;
begin
@(posedge clk);
adr=slave_addr;
dout=operd_a;
cyc=1;
stb=1;
we=1;
@(posedge clk);
while(~ack &~err)@(posedge clk);
adr=slave_addr+32'h1;
dout=operd_b;
@(posedge clk);
while(~ack &~err)@(posedge clk);
@(posedge clk);
@(posedge clk);
adr=adr+32'h1;
we=0;
@(posedge clk);
while(~ack &~err)@(posedge clk);
result=din;
cyc=0;
stb=0;
we=1'bx;
adr=32'hxxxx_xxxx;
dout=32'hxxxx_xxxx;
end
endtask
always @(result,dout,adr)
$display("master model time: %t dout:%h result:%h adr:%h ",$realtime,dout,result,adr);
endmodule
2>slave
//`include "wb_conbus_defines.v"
`timescale 1ns / 10ps
module my_slave_model(clk, rst, adr, din, dout, cyc, stb, sel, we, ack, err, rty);
input clk, rst;
input [31:0] adr, din;
output [31:0] dout;
input cyc, stb;
input [3:0] sel;
input we;
output ack, err, rty;
//output registers
reg [31:0] dout;
reg ack;
//internal registers
reg [31:0]Cal_A,Cal_B;
reg [31:0] Result;
reg A_Status,B_Status,R_Status;
//reg Reslt_Enbl;
//reg Oprd_Enbl;
//reg Wrt_Continue;
assign err=0;
assign rty=0;
always @(posedge clk)
if(rst)
begin
A_Status<=0;
B_Status<=0;
Cal_A<=0;
Cal_B<=0;
end
else if(A_Status &B_Status)
begin
Result<=Cal_A+Cal_B;
R_Status<=1'b1;
A_Status<=0;
B_Status<=0;
end
else if(cyc & stb & we)
begin
if(adr==32'h10000000 & !A_Status)
begin
Cal_A<=din;
A_Status<=1'b1;
end
else if(adr==32'h10000001 & !B_Status)
begin
Cal_B<=din;
B_Status<=1'b1;
end
end
/*
always @(posedge clk)
if(rst)
begin
Result<=0;
Reslt_Enbl<=0;
end
else if(Oprd_Enbl)
begin
Result<=Cal_A+Cal_B;
Reslt_Enbl<=1'b1;
end
*/
always @(posedge clk)
if(rst)
dout<=0;
else if(R_Status)
begin
dout<=Result;
R_Status<=0;
end
always @(posedge clk)
if(rst)
begin
ack<=0;
end
else if(stb & !ack)
begin
ack<=!ack;
end
else if(ack)
ack<=0;
always @(din,adr,stb,we,cyc,Cal_A,Cal_B,Result)
$display("slave model time:%t din:%h adr:%h stb:%b we:%b cyc:%b operd_a: %h operd_b:%h result:%h",$realtime,din,adr,stb,we,cyc,Cal_A,Cal_B,Result);
endmodule
3>bus top
/ WISHBONE Connection Bus Top Level Author: Johny Chi chisuhua@yahoo.com.cn / Copyright (C) 2000 Authors and OPENCORES.ORG This source file may be used and distributed without restriction provided that this copyright statement is not removed from the file and that any derivative work contains the original copyright notice and the associated disclaimer. This source file is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This source 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this source; if not, download it from http://www.opencores.org/lgpl.shtml // // // Description // 1. Up to 8 masters and 8 slaves share bus Wishbone connection // 2. no priorty arbitor , 8 masters are processed in a round // robin way, // 3. if WB_USE_TRISTATE was defined, the share bus is a tristate // bus, and use less logic resource. // 4. wb_conbus was synthesis to XC2S100-5-PQ208 using synplify, // Max speed >60M , and 374 SLICE if using Multiplexor bus // or 150 SLICE if using tri-state bus. // //`include "wb_conbus_defines.v" `timescale 1ns / 10ps `define dw 32 // Data bus Width `define aw 32 // Address bus Width `define sw `dw / 8 // Number of Select Lines `define mbusw `aw + `sw + `dw +4 //address width + byte select width + dat width + cyc + we + stb +cab , input from master interface `define sbusw 3 // ack + err + rty, input from slave interface `define mselectw 8 // number of masters `define sselectw 8 // number of slavers //`define WB_USE_TRISTATE module wb_conbus_top( clk_i, rst_i, // Master 0 Interface m0_dat_i, m0_dat_o, m0_adr_i, m0_sel_i, m0_we_i, m0_cyc_i, m0_stb_i, m0_ack_o, m0_err_o, m0_rty_o, m0_cab_i, // Master 1 Interface m1_dat_i, m1_dat_o, m1_adr_i, m1_sel_i, m1_we_i, m1_cyc_i, m1_stb_i, m1_ack_o, m1_err_o, m1_rty_o, m1_cab_i, // Master 2 Interface m2_dat_i, m2_dat_o, m2_adr_i, m2_sel_i, m2_we_i, m2_cyc_i, m2_stb_i, m2_ack_o, m2_err_o, m2_rty_o, m2_cab_i, // Master 3 Interface m3_dat_i, m3_dat_o, m3_adr_i, m3_sel_i, m3_we_i, m3_cyc_i, m3_stb_i, m3_ack_o, m3_err_o, m3_rty_o, m3_cab_i, // Master 4 Interface m4_dat_i, m4_dat_o, m4_adr_i, m4_sel_i, m4_we_i, m4_cyc_i, m4_stb_i, m4_ack_o, m4_err_o, m4_rty_o, m4_cab_i, // Master 5 Interface m5_dat_i, m5_dat_o, m5_adr_i, m5_sel_i, m5_we_i, m5_cyc_i, m5_stb_i, m5_ack_o, m5_err_o, m5_rty_o, m5_cab_i, // Master 6 Interface m6_dat_i, m6_dat_o, m6_adr_i, m6_sel_i, m6_we_i, m6_cyc_i, m6_stb_i, m6_ack_o, m6_err_o, m6_rty_o, m6_cab_i, // Master 7 Interface m7_dat_i, m7_dat_o, m7_adr_i, m7_sel_i, m7_we_i, m7_cyc_i, m7_stb_i, m7_ack_o, m7_err_o, m7_rty_o, m7_cab_i, // Slave 0 Interface s0_dat_i, s0_dat_o, s0_adr_o, s0_sel_o, s0_we_o, s0_cyc_o, s0_stb_o, s0_ack_i, s0_err_i, s0_rty_i, s0_cab_o, // Slav