mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-06 14:55:14 +00:00
feat: modify some ip impls
This commit is contained in:
3 files changed
+209
-23
No files matched your search
@@ -0,0 +1,172 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// I2C Master controller Top-level ////
|
||||
//// ////
|
||||
//// Modified from original project on OpenCores. ////
|
||||
//// The top level routine modified to remove wishbone ////
|
||||
//// interface to match Raven simple interfaces. For the ////
|
||||
//// copyright and other original code, see source file ////
|
||||
//// i2c_master_byte_ctrl.v. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
module simple_i2c_master (
|
||||
input clk, // master clock input
|
||||
input resetn, // synchronous active low reset
|
||||
input [ 2:0] reg_cfg1_we, // config register 1 write enable (3 bits)
|
||||
input [31:0] reg_cfg1_di, // config register 1 data input
|
||||
output [31:0] reg_cfg1_do, // config register 1 data output
|
||||
input reg_cfg2_we, // config register 2 write enable (1 bit)
|
||||
input [31:0] reg_cfg2_di, // config register 2 data input
|
||||
output [31:0] reg_cfg2_do, // config register 2 data output
|
||||
input reg_dat_we, // data write enable input (1 bit)
|
||||
input reg_dat_re, // data read enable input
|
||||
input [31:0] reg_dat_di, // data input
|
||||
output [31:0] reg_dat_do, // data output
|
||||
// I2C signals
|
||||
// i2c clock line
|
||||
input scl_pad_i, // SCL-line input
|
||||
output scl_pad_o, // SCL-line output (always 1'b0)
|
||||
output scl_padoeb_o, // SCL-line output enable (active low)
|
||||
// i2c data line
|
||||
input sda_pad_i, // SDA-line input
|
||||
output sda_pad_o, // SDA-line output (always 1'b0)
|
||||
output sda_padoeb_o, // SDA-line output enable (active low)
|
||||
output irq_o // Interrupt for incoming data
|
||||
);
|
||||
|
||||
// registers (in config register 1)
|
||||
reg [15:0] prer; // clock prescale register
|
||||
reg [ 7:0] ctr; // control register
|
||||
|
||||
// registers (in config register 2)
|
||||
reg [ 7:0] cr; // command register
|
||||
wire [ 7:0] sr; // status register
|
||||
|
||||
// registers (in data register)
|
||||
reg [ 7:0] txr; // transmit register
|
||||
wire [ 7:0] rxr; // receive register
|
||||
|
||||
// done signal: command completed, clear command register
|
||||
wire done;
|
||||
|
||||
// core enable signal
|
||||
wire core_en;
|
||||
wire ien;
|
||||
|
||||
// status register signals
|
||||
wire irxack;
|
||||
reg rxack; // received aknowledge from slave
|
||||
reg tip; // transfer in progress
|
||||
reg irq_flag; // interrupt pending flag
|
||||
wire i2c_busy; // bus busy (start signal detected)
|
||||
wire i2c_al; // i2c bus arbitration lost
|
||||
reg al; // status register arbitration lost bit
|
||||
|
||||
//
|
||||
// module body
|
||||
//
|
||||
|
||||
assign reg_cfg1_do = {8'b0, ctr, prer};
|
||||
assign reg_cfg2_do = {24'b0, sr};
|
||||
assign reg_dat_do = done ? rxr : ~0;
|
||||
|
||||
// generate registers
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
prer <= 16'hffff;
|
||||
ctr <= 8'h0;
|
||||
txr <= 8'h0;
|
||||
end else begin
|
||||
if (reg_cfg1_we[0]) prer[7:0] <= reg_cfg1_di[7:0];
|
||||
if (reg_cfg1_we[1]) prer[15:8] <= reg_cfg1_di[15:8];
|
||||
if (reg_cfg1_we[2]) ctr <= reg_cfg1_di[23:16];
|
||||
// Upper 8 bits are not used
|
||||
|
||||
// Status register is not writeable
|
||||
// Upper 24 bits are not used
|
||||
|
||||
if (reg_dat_we) txr <= reg_dat_di[7:0];
|
||||
// Upper 24 bits are not used
|
||||
end
|
||||
end
|
||||
|
||||
// generate command register (special case)
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
cr <= 8'h0;
|
||||
end else if (reg_cfg2_we) begin
|
||||
if (core_en) cr <= reg_cfg2_di[7:0];
|
||||
end else begin
|
||||
if (done | i2c_al) cr[7:4] <= 4'h0; // clear command bits when done
|
||||
// or when aribitration lost
|
||||
cr[2:1] <= 2'b0; // reserved bits
|
||||
cr[0] <= 1'b0; // clear IRQ_ACK bit
|
||||
end
|
||||
end
|
||||
|
||||
// decode command register
|
||||
wire sta = cr[7];
|
||||
wire sto = cr[6];
|
||||
wire rd = cr[5];
|
||||
wire wr = cr[4];
|
||||
wire ack = cr[3];
|
||||
wire iack = cr[0];
|
||||
|
||||
// decode control register
|
||||
assign core_en = ctr[7];
|
||||
assign ien = ctr[6];
|
||||
|
||||
// hook up byte controller block
|
||||
i2c_master_byte_ctrl byte_controller (
|
||||
.clk (clk),
|
||||
.nReset (resetn),
|
||||
.ena (core_en),
|
||||
.clk_cnt (prer),
|
||||
.start (sta),
|
||||
.stop (sto),
|
||||
.read (rd),
|
||||
.write (wr),
|
||||
.ack_in (ack),
|
||||
.din (txr),
|
||||
.cmd_ack (done),
|
||||
.ack_out (irxack),
|
||||
.dout (rxr),
|
||||
.i2c_busy(i2c_busy),
|
||||
.i2c_al (i2c_al),
|
||||
.scl_i (scl_pad_i),
|
||||
.scl_o (scl_pad_o),
|
||||
.scl_oen (scl_padoeb_o),
|
||||
.sda_i (sda_pad_i),
|
||||
.sda_o (sda_pad_o),
|
||||
.sda_oen (sda_padoeb_o)
|
||||
);
|
||||
|
||||
// status register block + interrupt request signal
|
||||
always @(posedge clk)
|
||||
if (!resetn) begin
|
||||
al <= 1'b0;
|
||||
rxack <= 1'b0;
|
||||
tip <= 1'b0;
|
||||
irq_flag <= 1'b0;
|
||||
end else begin
|
||||
al <= i2c_al | (al & ~sta);
|
||||
rxack <= irxack;
|
||||
tip <= (rd | wr);
|
||||
irq_flag <= (done | i2c_al | irq_flag) & ~iack; // interrupt request flag is always generated
|
||||
end
|
||||
|
||||
// interrupt signal is only generated when IEN
|
||||
// (interrupt enable bit) is set
|
||||
assign irq_o = irq_flag && ien;
|
||||
|
||||
// assign status register bits
|
||||
assign sr[7] = rxack;
|
||||
assign sr[6] = i2c_busy;
|
||||
assign sr[5] = al;
|
||||
assign sr[4:2] = 3'h0; // reserved
|
||||
assign sr[1] = tip;
|
||||
assign sr[0] = irq_flag;
|
||||
|
||||
endmodule
|
||||
+7
-6
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* PicoSoC - A simple example SoC using PicoRV32
|
||||
*
|
||||
* Copyright (C) 2017 Claire Xenia Wolf <claire@yosyshq.com>
|
||||
* Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -17,9 +17,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
module simpleuart #(
|
||||
parameter integer DEFAULT_DIV = 1
|
||||
) (
|
||||
module simpleuart (
|
||||
input clk,
|
||||
input resetn,
|
||||
output ser_tx,
|
||||
@@ -31,7 +29,8 @@ module simpleuart #(
|
||||
input reg_dat_re,
|
||||
input [31:0] reg_dat_di,
|
||||
output [31:0] reg_dat_do,
|
||||
output reg_dat_wait
|
||||
output reg_dat_wait,
|
||||
output irq_out
|
||||
);
|
||||
reg [31:0] cfg_divider;
|
||||
|
||||
@@ -51,9 +50,11 @@ module simpleuart #(
|
||||
assign reg_dat_wait = reg_dat_we && (send_bitcnt || send_dummy);
|
||||
assign reg_dat_do = recv_buf_valid ? recv_buf_data : ~0;
|
||||
|
||||
assign irq_out = recv_buf_valid;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
cfg_divider <= DEFAULT_DIV;
|
||||
cfg_divider <= 1;
|
||||
end else begin
|
||||
if (reg_div_we[0]) cfg_divider[7:0] <= reg_div_di[7:0];
|
||||
if (reg_div_we[1]) cfg_divider[15:8] <= reg_div_di[15:8];
|
||||
|
||||
+30
-17
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* PicoSoC - A simple example SoC using PicoRV32
|
||||
*
|
||||
* Copyright (C) 2017 Claire Xenia Wolf <claire@yosyshq.com>
|
||||
* Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -24,12 +24,19 @@ module spimemio (
|
||||
output ready,
|
||||
input [23:0] addr,
|
||||
output reg [31:0] rdata,
|
||||
input pass_thru,
|
||||
input pass_thru_csb,
|
||||
input pass_thru_sck,
|
||||
input pass_thru_sdi,
|
||||
output pass_thru_sdo,
|
||||
output flash_csb,
|
||||
output flash_clk,
|
||||
output flash_io0_oe,
|
||||
output flash_io1_oe,
|
||||
output flash_io2_oe,
|
||||
output flash_io3_oe,
|
||||
output flash_csb_oeb,
|
||||
output flash_clk_oeb,
|
||||
output flash_io0_oeb,
|
||||
output flash_io1_oeb,
|
||||
output flash_io2_oeb,
|
||||
output flash_io3_oeb,
|
||||
output flash_io0_do,
|
||||
output flash_io1_do,
|
||||
output flash_io2_do,
|
||||
@@ -85,7 +92,7 @@ module spimemio (
|
||||
assign cfgreg_do[20] = config_cont;
|
||||
assign cfgreg_do[19:16] = config_dummy;
|
||||
assign cfgreg_do[15:12] = 0;
|
||||
assign cfgreg_do[11:8] = {flash_io3_oe, flash_io2_oe, flash_io1_oe, flash_io0_oe};
|
||||
assign cfgreg_do[11:8] = {~flash_io3_oeb, ~flash_io2_oeb, ~flash_io1_oeb, ~flash_io0_oeb};
|
||||
assign cfgreg_do[7:6] = 0;
|
||||
assign cfgreg_do[5] = flash_csb;
|
||||
assign cfgreg_do[4] = flash_clk;
|
||||
@@ -150,25 +157,30 @@ module spimemio (
|
||||
xfer_io3_90 <= xfer_io3_do;
|
||||
end
|
||||
|
||||
assign flash_csb = config_en ? xfer_csb : config_csb;
|
||||
assign flash_clk = config_en ? xfer_clk : config_clk;
|
||||
assign flash_csb = pass_thru ? pass_thru_csb : (config_en ? xfer_csb : config_csb);
|
||||
assign flash_clk = pass_thru ? pass_thru_sck : (config_en ? xfer_clk : config_clk);
|
||||
assign flash_csb_oeb = pass_thru ? 1'b0 : ~resetn ? 1'b1 : 1'b0;
|
||||
assign flash_clk_oeb = pass_thru ? 1'b0 : ~resetn ? 1'b1 : 1'b0;
|
||||
|
||||
assign flash_io0_oe = config_en ? xfer_io0_oe : config_oe[0];
|
||||
assign flash_io1_oe = config_en ? xfer_io1_oe : config_oe[1];
|
||||
assign flash_io2_oe = config_en ? xfer_io2_oe : config_oe[2];
|
||||
assign flash_io3_oe = config_en ? xfer_io3_oe : config_oe[3];
|
||||
assign flash_io0_oeb = pass_thru ? 1'b0 : ~resetn ? 1'b1 : (config_en ? ~xfer_io0_oe : ~config_oe[0]);
|
||||
assign flash_io1_oeb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? ~xfer_io1_oe : ~config_oe[1]);
|
||||
assign flash_io2_oeb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? ~xfer_io2_oe : ~config_oe[2]);
|
||||
assign flash_io3_oeb = (pass_thru | ~resetn) ? 1'b1 : (config_en ? ~xfer_io3_oe : ~config_oe[3]);
|
||||
|
||||
assign flash_io0_do = config_en ? (config_ddr ? xfer_io0_90 : xfer_io0_do) : config_do[0];
|
||||
assign flash_io0_do = pass_thru ? pass_thru_sdi : (config_en ? (config_ddr ? xfer_io0_90 : xfer_io0_do) : config_do[0]);
|
||||
assign flash_io1_do = config_en ? (config_ddr ? xfer_io1_90 : xfer_io1_do) : config_do[1];
|
||||
assign flash_io2_do = config_en ? (config_ddr ? xfer_io2_90 : xfer_io2_do) : config_do[2];
|
||||
assign flash_io3_do = config_en ? (config_ddr ? xfer_io3_90 : xfer_io3_do) : config_do[3];
|
||||
|
||||
assign pass_thru_sdo = pass_thru ? flash_io1_di : 1'b0;
|
||||
|
||||
wire xfer_dspi = din_ddr && !din_qspi;
|
||||
wire xfer_ddr = din_ddr && din_qspi;
|
||||
|
||||
spimemio_xfer xfer (
|
||||
.clk (clk),
|
||||
.resetn (xfer_resetn),
|
||||
.resetn (resetn),
|
||||
.xfer_resetn (xfer_resetn),
|
||||
.din_valid (din_valid),
|
||||
.din_ready (din_ready),
|
||||
.din_data (din_data),
|
||||
@@ -374,6 +386,7 @@ endmodule
|
||||
module spimemio_xfer (
|
||||
input clk,
|
||||
resetn,
|
||||
xfer_resetn,
|
||||
|
||||
input din_valid,
|
||||
output din_ready,
|
||||
@@ -435,9 +448,9 @@ module spimemio_xfer (
|
||||
xfer_tag_q <= xfer_tag;
|
||||
end
|
||||
|
||||
assign din_ready = din_valid && resetn && next_fetch;
|
||||
assign din_ready = din_valid && xfer_resetn && next_fetch;
|
||||
|
||||
assign dout_valid = (xfer_ddr_q ? fetch && !last_fetch : next_fetch && !fetch) && resetn;
|
||||
assign dout_valid = (xfer_ddr_q ? fetch && !last_fetch : next_fetch && !fetch) && xfer_resetn;
|
||||
assign dout_data = ibuffer;
|
||||
assign dout_tag = xfer_tag_q;
|
||||
|
||||
@@ -532,7 +545,7 @@ module spimemio_xfer (
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
if (!resetn || !xfer_resetn) begin
|
||||
fetch <= 1;
|
||||
last_fetch <= 1;
|
||||
flash_csb <= 1;
|
||||
|
||||
Reference in new issue
Block a user