parent
837af2c977
commit
07b33baf94
|
@ -87,6 +87,14 @@ module rib(
|
|||
output reg s4_req_o, // 从设备4访问请求标志
|
||||
output reg s4_we_o, // 从设备4写标志
|
||||
|
||||
// slave 5 interface
|
||||
output reg[`MemAddrBus] s5_addr_o, // 从设备5读、写地址
|
||||
output reg[`MemBus] s5_data_o, // 从设备5写数据
|
||||
input wire[`MemBus] s5_data_i, // 从设备5读取到的数据
|
||||
input wire s5_ack_i, // 从设备5访问完成标志
|
||||
output reg s5_req_o, // 从设备5访问请求标志
|
||||
output reg s5_we_o, // 从设备5写标志
|
||||
|
||||
output reg hold_flag_o // 暂停流水线标志
|
||||
|
||||
);
|
||||
|
@ -99,6 +107,7 @@ module rib(
|
|||
parameter [3:0]slave_2 = 4'b0010;
|
||||
parameter [3:0]slave_3 = 4'b0011;
|
||||
parameter [3:0]slave_4 = 4'b0100;
|
||||
parameter [3:0]slave_5 = 4'b0101;
|
||||
|
||||
parameter [1:0]grant0 = 2'h0;
|
||||
parameter [1:0]grant1 = 2'h1;
|
||||
|
@ -191,21 +200,25 @@ module rib(
|
|||
s2_addr_o = `ZeroWord;
|
||||
s3_addr_o = `ZeroWord;
|
||||
s4_addr_o = `ZeroWord;
|
||||
s5_addr_o = `ZeroWord;
|
||||
s0_data_o = `ZeroWord;
|
||||
s1_data_o = `ZeroWord;
|
||||
s2_data_o = `ZeroWord;
|
||||
s3_data_o = `ZeroWord;
|
||||
s4_data_o = `ZeroWord;
|
||||
s5_data_o = `ZeroWord;
|
||||
s0_req_o = `RIB_NREQ;
|
||||
s1_req_o = `RIB_NREQ;
|
||||
s2_req_o = `RIB_NREQ;
|
||||
s3_req_o = `RIB_NREQ;
|
||||
s4_req_o = `RIB_NREQ;
|
||||
s5_req_o = `RIB_NREQ;
|
||||
s0_we_o = `WriteDisable;
|
||||
s1_we_o = `WriteDisable;
|
||||
s2_we_o = `WriteDisable;
|
||||
s3_we_o = `WriteDisable;
|
||||
s4_we_o = `WriteDisable;
|
||||
s5_we_o = `WriteDisable;
|
||||
end else begin
|
||||
m0_ack_o = `RIB_NACK;
|
||||
m1_ack_o = `RIB_NACK;
|
||||
|
@ -219,21 +232,25 @@ module rib(
|
|||
s2_addr_o = `ZeroWord;
|
||||
s3_addr_o = `ZeroWord;
|
||||
s4_addr_o = `ZeroWord;
|
||||
s5_addr_o = `ZeroWord;
|
||||
s0_data_o = `ZeroWord;
|
||||
s1_data_o = `ZeroWord;
|
||||
s2_data_o = `ZeroWord;
|
||||
s3_data_o = `ZeroWord;
|
||||
s4_data_o = `ZeroWord;
|
||||
s5_data_o = `ZeroWord;
|
||||
s0_req_o = `RIB_NREQ;
|
||||
s1_req_o = `RIB_NREQ;
|
||||
s2_req_o = `RIB_NREQ;
|
||||
s3_req_o = `RIB_NREQ;
|
||||
s4_req_o = `RIB_NREQ;
|
||||
s5_req_o = `RIB_NREQ;
|
||||
s0_we_o = `WriteDisable;
|
||||
s1_we_o = `WriteDisable;
|
||||
s2_we_o = `WriteDisable;
|
||||
s3_we_o = `WriteDisable;
|
||||
s4_we_o = `WriteDisable;
|
||||
s5_we_o = `WriteDisable;
|
||||
|
||||
case (grant)
|
||||
grant0: begin
|
||||
|
@ -278,6 +295,14 @@ module rib(
|
|||
m0_ack_o = s4_ack_i;
|
||||
m0_data_o = s4_data_i;
|
||||
end
|
||||
slave_5: begin
|
||||
s5_req_o = m0_req_i;
|
||||
s5_we_o = m0_we_i;
|
||||
s5_addr_o = {{4'h0}, {m0_addr_i[27:0]}};
|
||||
s5_data_o = m0_data_i;
|
||||
m0_ack_o = s5_ack_i;
|
||||
m0_data_o = s5_data_i;
|
||||
end
|
||||
default: begin
|
||||
|
||||
end
|
||||
|
@ -325,6 +350,14 @@ module rib(
|
|||
m1_ack_o = s4_ack_i;
|
||||
m1_data_o = s4_data_i;
|
||||
end
|
||||
slave_5: begin
|
||||
s5_req_o = m1_req_i;
|
||||
s5_we_o = m1_we_i;
|
||||
s5_addr_o = {{4'h0}, {m1_addr_i[27:0]}};
|
||||
s5_data_o = m1_data_i;
|
||||
m1_ack_o = s5_ack_i;
|
||||
m1_data_o = s5_data_i;
|
||||
end
|
||||
default: begin
|
||||
|
||||
end
|
||||
|
@ -372,6 +405,14 @@ module rib(
|
|||
m2_ack_o = s4_ack_i;
|
||||
m2_data_o = s4_data_i;
|
||||
end
|
||||
slave_5: begin
|
||||
s5_req_o = m2_req_i;
|
||||
s5_we_o = m2_we_i;
|
||||
s5_addr_o = {{4'h0}, {m2_addr_i[27:0]}};
|
||||
s5_data_o = m2_data_i;
|
||||
m2_ack_o = s5_ack_i;
|
||||
m2_data_o = s5_data_i;
|
||||
end
|
||||
default: begin
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
Copyright 2020 Blue Liang, liangkangnan@163.com
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
// spi master模块
|
||||
module spi(
|
||||
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
|
||||
input wire[31:0] data_i,
|
||||
input wire[31:0] addr_i,
|
||||
input wire we_i,
|
||||
input wire req_i,
|
||||
|
||||
output reg[31:0] data_o,
|
||||
output reg ack_o,
|
||||
|
||||
output reg spi_mosi, // spi控制器输出、spi设备输入信号
|
||||
input wire spi_miso, // spi控制器输入、spi设备输出信号
|
||||
output wire spi_ss, // spi设备片选
|
||||
output reg spi_clk // spi设备时钟,最大频率为输入clk的一半
|
||||
|
||||
);
|
||||
|
||||
|
||||
localparam SPI_CTRL = 4'h0; // spi_ctrl寄存器地址偏移
|
||||
localparam SPI_DATA = 4'h4; // spi_data寄存器地址偏移
|
||||
localparam SPI_STATUS = 4'h8; // spi_status寄存器地址偏移
|
||||
|
||||
// spi控制寄存器
|
||||
// addr: 0x00
|
||||
// [0]: 1: enable, 0: disable
|
||||
// [1]: CPOL
|
||||
// [2]: CPHA
|
||||
// [3]: select slave, 1: select, 0: deselect
|
||||
// [15:8]: clk div
|
||||
reg[31:0] spi_ctrl;
|
||||
// spi数据寄存器
|
||||
// addr: 0x04
|
||||
// [7:0] cmd or inout data
|
||||
reg[31:0] spi_data;
|
||||
// spi状态寄存器
|
||||
// addr: 0x08
|
||||
// [0]: 1: busy, 0: idle
|
||||
reg[31:0] spi_status;
|
||||
|
||||
reg[8:0] clk_cnt; // 分频计数
|
||||
reg en; // 使能,开始传输信号,传输期间一直有效
|
||||
reg[4:0] spi_clk_edge_cnt; // spi clk时钟沿的个数
|
||||
reg spi_clk_edge_level; // spi clk沿电平
|
||||
reg[7:0] rdata; // 从spi设备读回来的数据
|
||||
reg done; // 传输完成信号
|
||||
reg[3:0] bit_index; // 数据bit索引
|
||||
wire[8:0] div_cnt;
|
||||
|
||||
|
||||
assign spi_ss = ~spi_ctrl[3]; // SPI设备片选信号
|
||||
|
||||
assign div_cnt = spi_ctrl[15:8];// 0: 2分频,1:4分频,2:8分频,3:16分频,4:32分频,以此类推
|
||||
|
||||
|
||||
// 产生使能信号
|
||||
// 传输期间一直有效
|
||||
always @ (posedge clk) begin
|
||||
if (rst == 1'b0) begin
|
||||
en <= 1'b0;
|
||||
end else begin
|
||||
if (spi_ctrl[0] == 1'b1) begin
|
||||
en <= 1'b1;
|
||||
end else if (done == 1'b1) begin
|
||||
en <= 1'b0;
|
||||
end else begin
|
||||
en <= en;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// 对输入时钟进行计数
|
||||
always @ (posedge clk) begin
|
||||
if (rst == 1'b0) begin
|
||||
clk_cnt <= 9'h0;
|
||||
end else if (en == 1'b1) begin
|
||||
if (clk_cnt == div_cnt) begin
|
||||
clk_cnt <= 9'h0;
|
||||
end else begin
|
||||
clk_cnt <= clk_cnt + 1'b1;
|
||||
end
|
||||
end else begin
|
||||
clk_cnt <= 9'h0;
|
||||
end
|
||||
end
|
||||
|
||||
// 对spi clk沿进行计数
|
||||
// 每当计数到分频值时产生一个上升沿脉冲
|
||||
always @ (posedge clk) begin
|
||||
if (rst == 1'b0) begin
|
||||
spi_clk_edge_cnt <= 5'h0;
|
||||
spi_clk_edge_level <= 1'b0;
|
||||
end else if (en == 1'b1) begin
|
||||
// 计数达到分频值
|
||||
if (clk_cnt == div_cnt) begin
|
||||
if (spi_clk_edge_cnt == 5'd17) begin
|
||||
spi_clk_edge_cnt <= 5'h0;
|
||||
spi_clk_edge_level <= 1'b0;
|
||||
end else begin
|
||||
spi_clk_edge_cnt <= spi_clk_edge_cnt + 1'b1;
|
||||
spi_clk_edge_level <= 1'b1;
|
||||
end
|
||||
end else begin
|
||||
spi_clk_edge_level <= 1'b0;
|
||||
end
|
||||
end else begin
|
||||
spi_clk_edge_cnt <= 5'h0;
|
||||
spi_clk_edge_level <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// bit序列
|
||||
always @ (posedge clk) begin
|
||||
if (rst == 1'b0) begin
|
||||
spi_clk <= 1'b0;
|
||||
rdata <= 8'h0;
|
||||
spi_mosi <= 1'b0;
|
||||
bit_index <= 4'h0;
|
||||
end else begin
|
||||
if (en) begin
|
||||
if (spi_clk_edge_level == 1'b1) begin
|
||||
case (spi_clk_edge_cnt)
|
||||
// 第奇数个时钟沿
|
||||
1, 3, 5, 7, 9, 11, 13, 15: begin
|
||||
spi_clk <= ~spi_clk;
|
||||
if (spi_ctrl[2] == 1'b1) begin
|
||||
spi_mosi <= spi_data[bit_index]; // 送出1bit数据
|
||||
bit_index <= bit_index - 1'b1;
|
||||
end else begin
|
||||
rdata <= {rdata[6:0], spi_miso}; // 读1bit数据
|
||||
end
|
||||
end
|
||||
// 第偶数个时钟沿
|
||||
2, 4, 6, 8, 10, 12, 14, 16: begin
|
||||
spi_clk <= ~spi_clk;
|
||||
if (spi_ctrl[2] == 1'b1) begin
|
||||
rdata <= {rdata[6:0], spi_miso}; // 读1bit数据
|
||||
end else begin
|
||||
spi_mosi <= spi_data[bit_index]; // 送出1bit数据
|
||||
bit_index <= bit_index - 1'b1;
|
||||
end
|
||||
end
|
||||
17: begin
|
||||
spi_clk <= spi_ctrl[1];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end else begin
|
||||
// 初始状态
|
||||
spi_clk <= spi_ctrl[1];
|
||||
if (spi_ctrl[2] == 1'b0) begin
|
||||
spi_mosi <= spi_data[7]; // 送出最高位数据
|
||||
bit_index <= 4'h6;
|
||||
end else begin
|
||||
bit_index <= 4'h7;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// 产生结束(完成)信号
|
||||
always @ (posedge clk) begin
|
||||
if (rst == 1'b0) begin
|
||||
done <= 1'b0;
|
||||
end else begin
|
||||
if (en && spi_clk_edge_cnt == 5'd17) begin
|
||||
done <= 1'b1;
|
||||
end else begin
|
||||
done <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// write reg
|
||||
always @ (posedge clk) begin
|
||||
if (rst == 1'b0) begin
|
||||
spi_ctrl <= 32'h0;
|
||||
spi_data <= 32'h0;
|
||||
spi_status <= 32'h0;
|
||||
end else begin
|
||||
spi_status[0] <= en;
|
||||
if (we_i == 1'b1) begin
|
||||
case (addr_i[3:0])
|
||||
SPI_CTRL: begin
|
||||
spi_ctrl <= data_i;
|
||||
end
|
||||
SPI_DATA: begin
|
||||
spi_data <= data_i;
|
||||
end
|
||||
default: begin
|
||||
|
||||
end
|
||||
endcase
|
||||
end else begin
|
||||
spi_ctrl[0] <= 1'b0;
|
||||
// 发送完成后更新数据寄存器
|
||||
if (done == 1'b1) begin
|
||||
spi_data <= {24'h0, rdata};
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// read reg
|
||||
always @ (*) begin
|
||||
if (rst == 1'b0) begin
|
||||
data_o = 32'h0;
|
||||
end else begin
|
||||
case (addr_i[3:0])
|
||||
SPI_CTRL: begin
|
||||
data_o = spi_ctrl;
|
||||
end
|
||||
SPI_DATA: begin
|
||||
data_o = spi_data;
|
||||
end
|
||||
SPI_STATUS: begin
|
||||
data_o = spi_status;
|
||||
end
|
||||
default: begin
|
||||
data_o = 32'h0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -33,7 +33,12 @@ module tinyriscv_soc_top(
|
|||
input wire jtag_TCK, // JTAG TCK引脚
|
||||
input wire jtag_TMS, // JTAG TMS引脚
|
||||
input wire jtag_TDI, // JTAG TDI引脚
|
||||
output wire jtag_TDO // JTAG TDO引脚
|
||||
output wire jtag_TDO, // JTAG TDO引脚
|
||||
|
||||
input wire spi_miso, // SPI MISO引脚
|
||||
output wire spi_mosi, // SPI MOSI引脚
|
||||
output wire spi_ss, // SPI SS引脚
|
||||
output wire spi_clk // SPI CLK引脚
|
||||
|
||||
);
|
||||
|
||||
|
@ -102,6 +107,14 @@ module tinyriscv_soc_top(
|
|||
wire s4_req_o;
|
||||
wire s4_we_o;
|
||||
|
||||
// slave 5 interface
|
||||
wire[`MemAddrBus] s5_addr_o;
|
||||
wire[`MemBus] s5_data_o;
|
||||
wire[`MemBus] s5_data_i;
|
||||
wire s5_ack_i;
|
||||
wire s5_req_o;
|
||||
wire s5_we_o;
|
||||
|
||||
// rib
|
||||
wire rib_hold_flag_o;
|
||||
|
||||
|
@ -227,6 +240,22 @@ module tinyriscv_soc_top(
|
|||
.io_pin(io_pin)
|
||||
);
|
||||
|
||||
// spi模块例化
|
||||
spi spi_0(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.data_i(s5_data_o),
|
||||
.addr_i(s5_addr_o),
|
||||
.we_i(s5_we_o),
|
||||
.req_i(s5_req_o),
|
||||
.data_o(s5_data_i),
|
||||
.ack_o(s5_ack_i),
|
||||
.spi_mosi(spi_mosi),
|
||||
.spi_miso(spi_miso),
|
||||
.spi_ss(spi_ss),
|
||||
.spi_clk(spi_clk)
|
||||
);
|
||||
|
||||
// rib模块例化
|
||||
rib u_rib(
|
||||
.clk(clk),
|
||||
|
@ -296,6 +325,14 @@ module tinyriscv_soc_top(
|
|||
.s4_req_o(s4_req_o),
|
||||
.s4_we_o(s4_we_o),
|
||||
|
||||
// slave 5 interface
|
||||
.s5_addr_o(s5_addr_o),
|
||||
.s5_data_o(s5_data_o),
|
||||
.s5_data_i(s5_data_i),
|
||||
.s5_ack_i(s5_ack_i),
|
||||
.s5_req_o(s5_req_o),
|
||||
.s5_we_o(s5_we_o),
|
||||
|
||||
.hold_flag_o(rib_hold_flag_o)
|
||||
);
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
iverilog -s tinyriscv_soc_tb -o out.vvp -I ..\rtl\core tinyriscv_soc_tb.v ..\rtl\core\defines.v ..\rtl\core\ex.v ..\rtl\core\id.v ..\rtl\core\tinyriscv.v ..\rtl\core\pc_reg.v ..\rtl\core\id_ex.v ..\rtl\core\ctrl.v ..\rtl\core\regs.v ..\rtl\perips\ram.v ..\rtl\perips\rom.v ..\rtl\core\if_id.v ..\rtl\core\div.v ..\rtl\core\rib.v ..\rtl\core\clint.v ..\rtl\core\csr_reg.v ..\rtl\debug\jtag_dm.v ..\rtl\debug\jtag_driver.v ..\rtl\debug\jtag_top.v ..\rtl\perips\timer.v ..\rtl\perips\uart_tx.v ..\rtl\perips\gpio.v ..\rtl\soc\tinyriscv_soc_top.v
|
||||
iverilog -s tinyriscv_soc_tb -o out.vvp -I ..\rtl\core tinyriscv_soc_tb.v ..\rtl\core\defines.v ..\rtl\core\ex.v ..\rtl\core\id.v ..\rtl\core\tinyriscv.v ..\rtl\core\pc_reg.v ..\rtl\core\id_ex.v ..\rtl\core\ctrl.v ..\rtl\core\regs.v ..\rtl\perips\ram.v ..\rtl\perips\rom.v ..\rtl\perips\spi.v ..\rtl\core\if_id.v ..\rtl\core\div.v ..\rtl\core\rib.v ..\rtl\core\clint.v ..\rtl\core\csr_reg.v ..\rtl\debug\jtag_dm.v ..\rtl\debug\jtag_driver.v ..\rtl\debug\jtag_top.v ..\rtl\perips\timer.v ..\rtl\perips\uart_tx.v ..\rtl\perips\gpio.v ..\rtl\soc\tinyriscv_soc_top.v
|
||||
vvp out.vvp
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
..\tools\BinToMem_CLI.exe %1 %2
|
||||
iverilog -s tinyriscv_soc_tb -o out.vvp -I ..\rtl\core tinyriscv_soc_tb.v ..\rtl\core\defines.v ..\rtl\core\ex.v ..\rtl\core\id.v ..\rtl\core\tinyriscv.v ..\rtl\core\pc_reg.v ..\rtl\core\id_ex.v ..\rtl\core\ctrl.v ..\rtl\core\regs.v ..\rtl\perips\ram.v ..\rtl\perips\rom.v ..\rtl\core\if_id.v ..\rtl\core\div.v ..\rtl\core\rib.v ..\rtl\core\clint.v ..\rtl\core\csr_reg.v ..\rtl\debug\jtag_dm.v ..\rtl\debug\jtag_driver.v ..\rtl\debug\jtag_top.v ..\rtl\perips\timer.v ..\rtl\perips\uart_tx.v ..\rtl\perips\gpio.v ..\rtl\soc\tinyriscv_soc_top.v
|
||||
iverilog -s tinyriscv_soc_tb -o out.vvp -I ..\rtl\core tinyriscv_soc_tb.v ..\rtl\core\defines.v ..\rtl\core\ex.v ..\rtl\core\id.v ..\rtl\core\tinyriscv.v ..\rtl\core\pc_reg.v ..\rtl\core\id_ex.v ..\rtl\core\ctrl.v ..\rtl\core\regs.v ..\rtl\perips\ram.v ..\rtl\perips\rom.v ..\rtl\perips\spi.v ..\rtl\core\if_id.v ..\rtl\core\div.v ..\rtl\core\rib.v ..\rtl\core\clint.v ..\rtl\core\csr_reg.v ..\rtl\debug\jtag_dm.v ..\rtl\debug\jtag_driver.v ..\rtl\debug\jtag_top.v ..\rtl\perips\timer.v ..\rtl\perips\uart_tx.v ..\rtl\perips\gpio.v ..\rtl\soc\tinyriscv_soc_top.v
|
||||
vvp out.vvp
|
||||
|
|
Loading…
Reference in New Issue